mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Refactor of interal tunnel analysis code.
- Pulled more common code into NetSessions::DoNextInnerPacket() and made the pcap header it makes internally use network_time - Remove Encapsulation class ctor from pointer - Rename Encapsulation class to EncapsulationStack
This commit is contained in:
parent
e04d629733
commit
ce58a3e908
8 changed files with 60 additions and 65 deletions
14
src/Conn.cc
14
src/Conn.cc
|
@ -113,7 +113,7 @@ unsigned int Connection::external_connections = 0;
|
|||
IMPLEMENT_SERIAL(Connection, SER_CONNECTION);
|
||||
|
||||
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
||||
uint32 flow, const Encapsulation* arg_encap)
|
||||
uint32 flow, const EncapsulationStack* arg_encap)
|
||||
{
|
||||
sessions = s;
|
||||
key = k;
|
||||
|
@ -162,7 +162,7 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
|||
uid = 0; // Will set later.
|
||||
|
||||
if ( arg_encap )
|
||||
encapsulation = new Encapsulation(arg_encap);
|
||||
encapsulation = new EncapsulationStack(*arg_encap);
|
||||
else
|
||||
encapsulation = 0;
|
||||
|
||||
|
@ -200,7 +200,7 @@ Connection::~Connection()
|
|||
--external_connections;
|
||||
}
|
||||
|
||||
void Connection::CheckEncapsulation(const Encapsulation* arg_encap)
|
||||
void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
|
||||
{
|
||||
if ( encapsulation && arg_encap )
|
||||
{
|
||||
|
@ -208,22 +208,22 @@ void Connection::CheckEncapsulation(const Encapsulation* arg_encap)
|
|||
{
|
||||
Event(tunnel_changed, 0, arg_encap->GetVectorVal());
|
||||
delete encapsulation;
|
||||
encapsulation = new Encapsulation(arg_encap);
|
||||
encapsulation = new EncapsulationStack(*arg_encap);
|
||||
}
|
||||
}
|
||||
|
||||
else if ( encapsulation )
|
||||
{
|
||||
Encapsulation empty;
|
||||
EncapsulationStack empty;
|
||||
Event(tunnel_changed, 0, empty.GetVectorVal());
|
||||
delete encapsulation;
|
||||
encapsulation = new Encapsulation(arg_encap);
|
||||
encapsulation = 0;
|
||||
}
|
||||
|
||||
else if ( arg_encap )
|
||||
{
|
||||
Event(tunnel_changed, 0, arg_encap->GetVectorVal());
|
||||
encapsulation = new Encapsulation(arg_encap);
|
||||
encapsulation = new EncapsulationStack(*arg_encap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class Analyzer;
|
|||
class Connection : public BroObj {
|
||||
public:
|
||||
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
||||
uint32 flow, const Encapsulation* arg_encap);
|
||||
uint32 flow, const EncapsulationStack* arg_encap);
|
||||
virtual ~Connection();
|
||||
|
||||
// Invoked when an encapsulation is discovered. It records the
|
||||
|
@ -60,7 +60,7 @@ public:
|
|||
// event if it's different from the previous encapsulation (or the
|
||||
// first encountered). encap can be null to indicate no
|
||||
// encapsulation.
|
||||
void CheckEncapsulation(const Encapsulation* encap);
|
||||
void CheckEncapsulation(const EncapsulationStack* encap);
|
||||
|
||||
// Invoked when connection is about to be removed. Use Ref(this)
|
||||
// inside Done to keep the connection object around (though it'll
|
||||
|
@ -252,7 +252,7 @@ public:
|
|||
|
||||
uint64 GetUID() const { return uid; }
|
||||
|
||||
const Encapsulation* GetEncapsulation() const
|
||||
const EncapsulationStack* GetEncapsulation() const
|
||||
{ return encapsulation; }
|
||||
|
||||
void CheckFlowLabel(bool is_orig, uint32 flow_label);
|
||||
|
@ -292,7 +292,7 @@ protected:
|
|||
double inactivity_timeout;
|
||||
RecordVal* conn_val;
|
||||
LoginConn* login_conn; // either nil, or this
|
||||
const Encapsulation* encapsulation; // tunnels
|
||||
const EncapsulationStack* encapsulation; // tunnels
|
||||
int suppress_event; // suppress certain events to once per conn.
|
||||
|
||||
unsigned int installed_status_timer:1;
|
||||
|
|
|
@ -367,7 +367,7 @@ int NetSessions::CheckConnectionTag(Connection* conn)
|
|||
|
||||
void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
||||
int hdr_size, const Encapsulation* encapsulation)
|
||||
int hdr_size, const EncapsulationStack* encapsulation)
|
||||
{
|
||||
uint32 caplen = hdr->caplen - hdr_size;
|
||||
const struct ip* ip4 = ip_hdr->IP4_Hdr();
|
||||
|
@ -576,8 +576,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
return;
|
||||
}
|
||||
|
||||
Encapsulation* outer = new Encapsulation(encapsulation);
|
||||
|
||||
// Look up to see if we've already seen this IP tunnel, identified
|
||||
// by the pair of IP addresses, so that we can always associate the
|
||||
// same UID with it.
|
||||
|
@ -594,18 +592,13 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr());
|
||||
ip_tunnels[tunnel_idx] = TunnelActivity(ec, network_time);
|
||||
timer_mgr->Add(new IPTunnelTimer(network_time, tunnel_idx));
|
||||
outer->Add(ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.second = network_time;
|
||||
outer->Add(it->second.first);
|
||||
}
|
||||
|
||||
DoNextInnerPacket(t, hdr, inner, outer);
|
||||
DoNextInnerPacket(t, hdr, inner, encapsulation,
|
||||
ip_tunnels[tunnel_idx].first);
|
||||
|
||||
delete inner;
|
||||
delete outer;
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
@ -724,7 +717,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
}
|
||||
|
||||
void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr,
|
||||
const IP_Hdr* inner, const Encapsulation* outer)
|
||||
const IP_Hdr* inner, const EncapsulationStack* prev,
|
||||
const EncapsulatingConn& ec)
|
||||
{
|
||||
struct pcap_pkthdr fake_hdr;
|
||||
fake_hdr.caplen = fake_hdr.len = inner->TotalLen();
|
||||
|
@ -732,7 +726,11 @@ void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( hdr )
|
||||
fake_hdr.ts = hdr->ts;
|
||||
else
|
||||
fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0;
|
||||
{
|
||||
fake_hdr.ts.tv_sec = (time_t) network_time;
|
||||
fake_hdr.ts.tv_usec = (suseconds_t)
|
||||
((network_time - (double)fake_hdr.ts.tv_sec) * 1000000);
|
||||
}
|
||||
|
||||
const u_char* pkt = 0;
|
||||
|
||||
|
@ -741,7 +739,14 @@ void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
else
|
||||
pkt = (const u_char*) inner->IP6_Hdr();
|
||||
|
||||
EncapsulationStack* outer = prev ?
|
||||
new EncapsulationStack(*prev) : new EncapsulationStack();
|
||||
outer->Add(ec);
|
||||
|
||||
DoNextPacket(t, &fake_hdr, inner, pkt, 0, outer);
|
||||
|
||||
delete inner;
|
||||
delete outer;
|
||||
}
|
||||
|
||||
int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
||||
|
@ -778,7 +783,7 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
|||
|
||||
bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
||||
const struct pcap_pkthdr* h,
|
||||
const u_char* p, const Encapsulation* encap)
|
||||
const u_char* p, const EncapsulationStack* encap)
|
||||
{
|
||||
uint32 min_hdr_len = 0;
|
||||
switch ( proto ) {
|
||||
|
@ -1110,7 +1115,7 @@ void NetSessions::GetStats(SessionStats& s) const
|
|||
|
||||
Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||
const u_char* data, int proto, uint32 flow_label,
|
||||
const Encapsulation* encapsulation)
|
||||
const EncapsulationStack* encapsulation)
|
||||
{
|
||||
// FIXME: This should be cleaned up a bit, it's too protocol-specific.
|
||||
// But I'm not yet sure what the right abstraction for these things is.
|
||||
|
@ -1331,7 +1336,7 @@ void NetSessions::Internal(const char* msg, const struct pcap_pkthdr* hdr,
|
|||
}
|
||||
|
||||
void NetSessions::Weird(const char* name, const struct pcap_pkthdr* hdr,
|
||||
const u_char* pkt, const Encapsulation* encap)
|
||||
const u_char* pkt, const EncapsulationStack* encap)
|
||||
{
|
||||
if ( hdr )
|
||||
dump_this_packet = 1;
|
||||
|
@ -1343,7 +1348,7 @@ void NetSessions::Weird(const char* name, const struct pcap_pkthdr* hdr,
|
|||
}
|
||||
|
||||
void NetSessions::Weird(const char* name, const IP_Hdr* ip,
|
||||
const Encapsulation* encap)
|
||||
const EncapsulationStack* encap)
|
||||
{
|
||||
if ( encap && encap->LastType() != BifEnum::Tunnel::NONE )
|
||||
reporter->Weird(ip->SrcAddr(), ip->DstAddr(),
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
struct pcap_pkthdr;
|
||||
|
||||
class Encapsulation;
|
||||
class EncapsulationStack;
|
||||
class Connection;
|
||||
class ConnID;
|
||||
class OSFingerprint;
|
||||
|
@ -109,9 +109,9 @@ public:
|
|||
void GetStats(SessionStats& s) const;
|
||||
|
||||
void Weird(const char* name, const struct pcap_pkthdr* hdr,
|
||||
const u_char* pkt, const Encapsulation* encap = 0);
|
||||
const u_char* pkt, const EncapsulationStack* encap = 0);
|
||||
void Weird(const char* name, const IP_Hdr* ip,
|
||||
const Encapsulation* encap = 0);
|
||||
const EncapsulationStack* encap = 0);
|
||||
|
||||
PacketFilter* GetPacketFilter()
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
|
||||
void DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
||||
int hdr_size, const Encapsulation* encapsulation);
|
||||
int hdr_size, const EncapsulationStack* encapsulation);
|
||||
|
||||
/**
|
||||
* Wrapper that recurses on DoNextPacket for encapsulated IP packets.
|
||||
|
@ -147,10 +147,15 @@ public:
|
|||
* so that the fake pcap header passed to DoNextPacket will use
|
||||
* the same timeval. The caplen and len fields of the fake pcap
|
||||
* header are always set to the TotalLength() of \a inner.
|
||||
* @param outer The encapsulation information for the inner IP packet.
|
||||
* @param inner Pointer to IP header wrapper of the inner packet, ownership
|
||||
* of the pointer's memory is assumed by this function.
|
||||
* @param prev Any previous encapsulation stack of the caller, not including
|
||||
* the most-recently found depth of encapsulation.
|
||||
* @param ec The most-recently found depth of encapsulation.
|
||||
*/
|
||||
void DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr,
|
||||
const IP_Hdr* inner, const Encapsulation* outer);
|
||||
const IP_Hdr* inner, const EncapsulationStack* prev,
|
||||
const EncapsulatingConn& ec);
|
||||
|
||||
/**
|
||||
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
|
||||
|
@ -185,7 +190,7 @@ protected:
|
|||
|
||||
Connection* NewConn(HashKey* k, double t, const ConnID* id,
|
||||
const u_char* data, int proto, uint32 flow_lable,
|
||||
const Encapsulation* encapsulation);
|
||||
const EncapsulationStack* encapsulation);
|
||||
|
||||
// Check whether the tag of the current packet is consistent with
|
||||
// the given connection. Returns:
|
||||
|
@ -234,7 +239,7 @@ protected:
|
|||
// than that protocol's minimum header size.
|
||||
bool CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
||||
const struct pcap_pkthdr* hdr, const u_char* pkt,
|
||||
const Encapsulation* encap);
|
||||
const EncapsulationStack* encap);
|
||||
|
||||
CompositeHash* ch;
|
||||
PDict(Connection) tcp_conns;
|
||||
|
|
|
@ -149,7 +149,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
|||
return;
|
||||
}
|
||||
|
||||
const Encapsulation* e = Conn()->GetEncapsulation();
|
||||
const EncapsulationStack* e = Conn()->GetEncapsulation();
|
||||
|
||||
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
|
||||
{
|
||||
|
@ -222,12 +222,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
|||
Conn()->Event(teredo_bubble, 0, teredo_hdr);
|
||||
}
|
||||
|
||||
Encapsulation* outer = new Encapsulation(e);
|
||||
EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO);
|
||||
outer->Add(ec);
|
||||
|
||||
sessions->DoNextInnerPacket(network_time, 0, inner, outer);
|
||||
|
||||
delete inner;
|
||||
delete outer;
|
||||
sessions->DoNextInnerPacket(network_time, 0, inner, e, ec);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ RecordVal* EncapsulatingConn::GetRecordVal() const
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool operator==(const Encapsulation& e1, const Encapsulation& e2)
|
||||
bool operator==(const EncapsulationStack& e1, const EncapsulationStack& e2)
|
||||
{
|
||||
if ( ! e1.conns )
|
||||
return e2.conns;
|
||||
|
|
|
@ -114,12 +114,12 @@ protected:
|
|||
/**
|
||||
* Abstracts an arbitrary amount of nested tunneling.
|
||||
*/
|
||||
class Encapsulation {
|
||||
class EncapsulationStack {
|
||||
public:
|
||||
Encapsulation() : conns(0)
|
||||
EncapsulationStack() : conns(0)
|
||||
{}
|
||||
|
||||
Encapsulation(const Encapsulation& other)
|
||||
EncapsulationStack(const EncapsulationStack& other)
|
||||
{
|
||||
if ( other.conns )
|
||||
conns = new vector<EncapsulatingConn>(*(other.conns));
|
||||
|
@ -127,15 +127,7 @@ public:
|
|||
conns = 0;
|
||||
}
|
||||
|
||||
Encapsulation(const Encapsulation* other)
|
||||
{
|
||||
if ( other && other->conns )
|
||||
conns = new vector<EncapsulatingConn>(*(other->conns));
|
||||
else
|
||||
conns = 0;
|
||||
}
|
||||
|
||||
Encapsulation& operator=(const Encapsulation& other)
|
||||
EncapsulationStack& operator=(const EncapsulationStack& other)
|
||||
{
|
||||
if ( this == &other )
|
||||
return *this;
|
||||
|
@ -150,10 +142,10 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
~Encapsulation() { delete conns; }
|
||||
~EncapsulationStack() { delete conns; }
|
||||
|
||||
/**
|
||||
* Add a new inner-most tunnel to the Encapsulation.
|
||||
* Add a new inner-most tunnel to the EncapsulationStack.
|
||||
*
|
||||
* @param c The new inner-most tunnel to append to the tunnel chain.
|
||||
*/
|
||||
|
@ -200,9 +192,11 @@ public:
|
|||
return vv;
|
||||
}
|
||||
|
||||
friend bool operator==(const Encapsulation& e1, const Encapsulation& e2);
|
||||
friend bool operator==(const EncapsulationStack& e1,
|
||||
const EncapsulationStack& e2);
|
||||
|
||||
friend bool operator!=(const Encapsulation& e1, const Encapsulation& e2)
|
||||
friend bool operator!=(const EncapsulationStack& e1,
|
||||
const EncapsulationStack& e2)
|
||||
{
|
||||
return ! ( e1 == e2 );
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ flow AYIYA_Flow
|
|||
function process_ayiya(pdu: PDU): bool
|
||||
%{
|
||||
Connection *c = connection()->bro_analyzer()->Conn();
|
||||
const Encapsulation* e = c->GetEncapsulation();
|
||||
const EncapsulationStack* e = c->GetEncapsulation();
|
||||
|
||||
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
|
||||
{
|
||||
|
@ -72,14 +72,10 @@ flow AYIYA_Flow
|
|||
if ( result != 0 )
|
||||
return false;
|
||||
|
||||
Encapsulation* outer = new Encapsulation(e);
|
||||
EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA);
|
||||
outer->Add(ec);
|
||||
|
||||
sessions->DoNextInnerPacket(network_time(), 0, inner, outer);
|
||||
sessions->DoNextInnerPacket(network_time(), 0, inner, e, ec);
|
||||
|
||||
delete inner;
|
||||
delete outer;
|
||||
return (result == 0) ? true : false;
|
||||
%}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue