mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 09:08:20 +00:00

This commit marks (hopefully) ever one-parameter constructor as explicit. It also uses override in (hopefully) all circumstances where a virtual method is overridden. There are a very few other minor changes - most of them were necessary to get everything to compile (like one additional constructor). In one case I changed an implicit operation to an explicit string conversion - I think the automatically chosen conversion was much more convoluted. This took longer than I want to admit but not as long as I feared :)
289 lines
9.2 KiB
C++
289 lines
9.2 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#ifndef sessions_h
|
|
#define sessions_h
|
|
|
|
#include "Dict.h"
|
|
#include "CompHash.h"
|
|
#include "IP.h"
|
|
#include "Frag.h"
|
|
#include "PacketFilter.h"
|
|
#include "Stats.h"
|
|
#include "NetVar.h"
|
|
#include "TunnelEncapsulation.h"
|
|
#include "analyzer/protocol/tcp/Stats.h"
|
|
|
|
#include <utility>
|
|
|
|
class EncapsulationStack;
|
|
class Connection;
|
|
class OSFingerprint;
|
|
class ConnCompressor;
|
|
struct ConnID;
|
|
|
|
declare(PDict,Connection);
|
|
declare(PDict,FragReassembler);
|
|
|
|
class Discarder;
|
|
class PacketFilter;
|
|
|
|
namespace analyzer { namespace stepping_stone { class SteppingStoneManager; } }
|
|
namespace analyzer { namespace arp { class ARP_Analyzer; } }
|
|
|
|
struct SessionStats {
|
|
int num_TCP_conns;
|
|
int max_TCP_conns;
|
|
uint64 cumulative_TCP_conns;
|
|
|
|
int num_UDP_conns;
|
|
int max_UDP_conns;
|
|
uint64 cumulative_UDP_conns;
|
|
|
|
int num_ICMP_conns;
|
|
int max_ICMP_conns;
|
|
uint64 cumulative_ICMP_conns;
|
|
|
|
int num_fragments;
|
|
int max_fragments;
|
|
uint64 num_packets;
|
|
};
|
|
|
|
// Drains and deletes a timer manager if it hasn't seen any advances
|
|
// for an interval timer_mgr_inactivity_timeout.
|
|
class TimerMgrExpireTimer : public Timer {
|
|
public:
|
|
TimerMgrExpireTimer(double t, TimerMgr* arg_mgr)
|
|
: Timer(t, TIMER_TIMERMGR_EXPIRE), mgr(arg_mgr)
|
|
{ }
|
|
|
|
void Dispatch(double t, int is_expire) override;
|
|
|
|
protected:
|
|
TimerMgr* mgr;
|
|
};
|
|
|
|
class NetSessions {
|
|
public:
|
|
NetSessions();
|
|
~NetSessions();
|
|
|
|
// Main entry point for packet processing.
|
|
void NextPacket(double t, const Packet* pkt);
|
|
|
|
void Done(); // call to drain events before destructing
|
|
|
|
// Returns a reassembled packet, or nil if there are still
|
|
// some missing fragments.
|
|
FragReassembler* NextFragment(double t, const IP_Hdr* ip,
|
|
const u_char* pkt);
|
|
|
|
int Get_OS_From_SYN(struct os_type* retval,
|
|
uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS,
|
|
uint8 ocnt, uint8* op, uint16 MSS, uint8 win_scale,
|
|
uint32 tstamp, /* uint8 TOS, */ uint32 quirks,
|
|
uint8 ECN) const;
|
|
|
|
bool CompareWithPreviousOSMatch(const IPAddr& addr, int id) const;
|
|
|
|
// Looks up the connection referred to by the given Val,
|
|
// which should be a conn_id record. Returns nil if there's
|
|
// no such connection or the Val is ill-formed.
|
|
Connection* FindConnection(Val* v);
|
|
|
|
void Remove(Connection* c);
|
|
void Remove(FragReassembler* f);
|
|
|
|
void Insert(Connection* c);
|
|
|
|
// Generating connection_pending events for all connections
|
|
// that are still active.
|
|
void Drain();
|
|
|
|
void GetStats(SessionStats& s) const;
|
|
|
|
void Weird(const char* name, const Packet* pkt,
|
|
const EncapsulationStack* encap = 0);
|
|
void Weird(const char* name, const IP_Hdr* ip,
|
|
const EncapsulationStack* encap = 0);
|
|
|
|
PacketFilter* GetPacketFilter()
|
|
{
|
|
if ( ! packet_filter )
|
|
packet_filter = new PacketFilter(packet_filter_default);
|
|
return packet_filter;
|
|
}
|
|
|
|
// Looks up timer manager associated with tag. If tag is unknown and
|
|
// "create" is true, creates new timer manager and stores it. Returns
|
|
// global timer manager if tag is nil.
|
|
TimerMgr* LookupTimerMgr(const TimerMgr::Tag* tag, bool create = true);
|
|
|
|
void ExpireTimerMgrs();
|
|
|
|
analyzer::stepping_stone::SteppingStoneManager* GetSTPManager() { return stp_manager; }
|
|
|
|
unsigned int CurrentConnections()
|
|
{
|
|
return tcp_conns.Length() + udp_conns.Length() +
|
|
icmp_conns.Length();
|
|
}
|
|
|
|
void DoNextPacket(double t, const Packet *pkt, const IP_Hdr* ip_hdr,
|
|
const EncapsulationStack* encapsulation);
|
|
|
|
/**
|
|
* Wrapper that recurses on DoNextPacket for encapsulated IP packets.
|
|
*
|
|
* @param t Network time.
|
|
* @param hdr If the outer pcap header is available, this pointer can be set
|
|
* 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 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 Packet *pkt,
|
|
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
|
|
* or IPv6 header based on whether it's long enough to contain such a header,
|
|
* if version given in the header matches the proto argument, and also checks
|
|
* that the payload length field of that header matches the actual
|
|
* length of \a pkt given by \a caplen.
|
|
*
|
|
* @param caplen The length of \a pkt in bytes.
|
|
* @param pkt The inner IP packet data.
|
|
* @param proto Either IPPROTO_IPV6 or IPPROTO_IPV4 to indicate which IP
|
|
* protocol \a pkt corresponds to.
|
|
* @param inner The inner IP packet wrapper pointer to be allocated/assigned
|
|
* if \a pkt looks like a valid IP packet or at least long enough
|
|
* to hold an IP header.
|
|
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
|
|
* is greater than the supposed IP packet's payload length field, -2
|
|
* if the version of the inner header does not match proto or
|
|
* 1 if \a caplen is less than the supposed packet's payload length.
|
|
* In the -1 case, \a inner may still be non-null if \a caplen was
|
|
* long enough to be an IP header, and \a inner is always non-null
|
|
* for other return values.
|
|
*/
|
|
int ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
|
IP_Hdr*& inner);
|
|
|
|
unsigned int ConnectionMemoryUsage();
|
|
unsigned int ConnectionMemoryUsageConnVals();
|
|
unsigned int MemoryAllocation();
|
|
analyzer::tcp::TCPStateStats tcp_stats; // keeps statistics on TCP states
|
|
|
|
protected:
|
|
friend class RemoteSerializer;
|
|
friend class ConnCompressor;
|
|
friend class TimerMgrExpireTimer;
|
|
friend class IPTunnelTimer;
|
|
|
|
Connection* NewConn(HashKey* k, double t, const ConnID* id,
|
|
const u_char* data, int proto, uint32 flow_lable,
|
|
const Packet* pkt, const EncapsulationStack* encapsulation);
|
|
|
|
// Check whether the tag of the current packet is consistent with
|
|
// the given connection. Returns:
|
|
// -1 if current packet is to be completely ignored.
|
|
// 0 if tag is not consistent and new conn should be instantiated.
|
|
// 1 if tag is consistent, i.e., packet is part of connection.
|
|
int CheckConnectionTag(Connection* conn);
|
|
|
|
// Returns true if the port corresonds to an application
|
|
// for which there's a Bro analyzer (even if it might not
|
|
// be used by the present policy script), or it's more
|
|
// generally a likely server port, false otherwise.
|
|
//
|
|
// Note, port is in host order.
|
|
bool IsLikelyServerPort(uint32 port,
|
|
TransportProto transport_proto) const;
|
|
|
|
// 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), and, if yes, whether we should flip the roles of
|
|
// originator and responder (based on known ports or such).
|
|
// Use tcp_flags=0 for non-TCP.
|
|
bool WantConnection(uint16 src_port, uint16 dest_port,
|
|
TransportProto transport_proto,
|
|
uint8 tcp_flags, bool& flip_roles);
|
|
|
|
// Record the given packet (if a dumper is active). If len=0
|
|
// then the whole packet is recorded, otherwise just the first
|
|
// len bytes.
|
|
void DumpPacket(const Packet *pkt, int len=0);
|
|
|
|
// For a given protocol, checks whether the header's length as derived
|
|
// from lower-level headers or the length actually captured is less
|
|
// than that protocol's minimum header size.
|
|
bool CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
|
const Packet *pkt, const EncapsulationStack* encap);
|
|
|
|
CompositeHash* ch;
|
|
PDict(Connection) tcp_conns;
|
|
PDict(Connection) udp_conns;
|
|
PDict(Connection) icmp_conns;
|
|
PDict(FragReassembler) fragments;
|
|
|
|
typedef pair<IPAddr, IPAddr> IPPair;
|
|
typedef pair<EncapsulatingConn, double> TunnelActivity;
|
|
typedef std::map<IPPair, TunnelActivity> IPTunnelMap;
|
|
IPTunnelMap ip_tunnels;
|
|
|
|
analyzer::arp::ARP_Analyzer* arp_analyzer;
|
|
|
|
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
|
|
Discarder* discarder;
|
|
PacketFilter* packet_filter;
|
|
OSFingerprint* SYN_OS_Fingerprinter;
|
|
int build_backdoor_analyzer;
|
|
int dump_this_packet; // if true, current packet should be recorded
|
|
uint64 num_packets_processed;
|
|
PacketProfiler* pkt_profiler;
|
|
|
|
// We may use independent timer managers for different sets of related
|
|
// activity. The managers are identified by an unique tag.
|
|
typedef std::map<TimerMgr::Tag, TimerMgr*> TimerMgrMap;
|
|
TimerMgrMap timer_mgrs;
|
|
};
|
|
|
|
|
|
class IPTunnelTimer : public Timer {
|
|
public:
|
|
IPTunnelTimer(double t, NetSessions::IPPair p)
|
|
: Timer(t + BifConst::Tunnel::ip_tunnel_timeout,
|
|
TIMER_IP_TUNNEL_INACTIVITY), tunnel_idx(p) {}
|
|
|
|
~IPTunnelTimer() override {}
|
|
|
|
void Dispatch(double t, int is_expire) override;
|
|
|
|
protected:
|
|
NetSessions::IPPair tunnel_idx;
|
|
};
|
|
|
|
|
|
class FragReassemblerTracker {
|
|
public:
|
|
FragReassemblerTracker(NetSessions* s, FragReassembler* f)
|
|
: net_sessions(s), frag_reassembler(f)
|
|
{ }
|
|
|
|
~FragReassemblerTracker()
|
|
{ net_sessions->Remove(frag_reassembler); }
|
|
|
|
private:
|
|
NetSessions* net_sessions;
|
|
FragReassembler* frag_reassembler;
|
|
};
|
|
|
|
// Manager for the currently active sessions.
|
|
extern NetSessions* sessions;
|
|
|
|
#endif
|