Move IP and IP tunnel code from Sessions into packet analyzers

This commit is contained in:
Tim Wojtulewicz 2020-09-23 16:17:06 -07:00
parent 69da2d7b1d
commit 1cf251d1ca
53 changed files with 1226 additions and 907 deletions

View file

@ -15,20 +15,16 @@
ZEEK_FORWARD_DECLARE_NAMESPACED(EncapsulationStack, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(EncapsulatingConn, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(Packet, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(PacketProfiler, zeek::detail);
ZEEK_FORWARD_DECLARE_NAMESPACED(Connection, zeek);
class ConnCompressor;
namespace zeek { struct ConnID; }
using ConnID [[deprecated("Remove in v4.1. Use zeek::ConnID.")]] = zeek::ConnID;
ZEEK_FORWARD_DECLARE_NAMESPACED(Discarder, zeek::detail);
ZEEK_FORWARD_DECLARE_NAMESPACED(SteppingStoneManager, zeek, analyzer::stepping_stone);
namespace zeek {
namespace detail { class IPTunnelTimer; }
struct SessionStats {
size_t num_TCP_conns;
size_t max_TCP_conns;
@ -53,23 +49,17 @@ public:
~NetSessions();
// Main entry point for packet processing.
[[deprecated("Remove in v4.1. Do not call this method directly. Packet processing should start with a call to packet_mgr->ProcessPacket().")]]
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.
detail::FragReassembler* NextFragment(double t, const IP_Hdr* ip,
const u_char* pkt);
// 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(detail::FragReassembler* f);
void Insert(Connection* c);
// Generating connection_pending events for all connections
@ -86,9 +76,9 @@ public:
void Weird(const char* name, const IP_Hdr* ip,
const EncapsulationStack* encap = nullptr, const char* addl = "");
detail::PacketFilter* GetPacketFilter()
detail::PacketFilter* GetPacketFilter(bool init=true)
{
if ( ! packet_filter )
if ( ! packet_filter && init )
packet_filter = new detail::PacketFilter(detail::packet_filter_default);
return packet_filter;
}
@ -100,48 +90,14 @@ public:
return tcp_conns.size() + udp_conns.size() + icmp_conns.size();
}
/**
* Main entry point for processing packets destined for session analyzers. This
* method is called by the packet analysis manager when after it has processed
* an IP-based packet, and shouldn't be called directly from other places.
*/
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 pkt 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);
/**
* Recurses on DoNextPacket for encapsulated Ethernet/IP packets.
*
* @param t Network time.
* @param pkt 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.
* @param caplen number of captured bytes remaining
* @param len number of bytes remaining as claimed by outer framing
* @param data the remaining packet data
* @param link_type layer 2 link type used for initializing inner packet
* @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,
uint32_t caplen, uint32_t len,
const u_char* data, int link_type,
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,
@ -172,12 +128,15 @@ public:
unsigned int MemoryAllocation();
analyzer::tcp::TCPStateStats tcp_stats; // keeps statistics on TCP states
// 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);
protected:
friend class ConnCompressor;
friend class detail::IPTunnelTimer;
using ConnectionMap = std::map<detail::ConnIDKey, Connection*>;
using FragmentMap = std::map<detail::FragReassemblerKey, detail::FragReassembler*>;
Connection* NewConn(const detail::ConnIDKey& k, double t, const ConnID* id,
const u_char* data, int proto, uint32_t flow_label,
@ -203,11 +162,6 @@ protected:
TransportProto transport_proto,
uint8_t 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.
@ -224,55 +178,13 @@ protected:
ConnectionMap tcp_conns;
ConnectionMap udp_conns;
ConnectionMap icmp_conns;
FragmentMap fragments;
SessionStats stats;
using IPPair = std::pair<IPAddr, IPAddr>;
using TunnelActivity = std::pair<EncapsulatingConn, double>;
using IPTunnelMap = std::map<IPPair, TunnelActivity>;
IPTunnelMap ip_tunnels;
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
detail::Discarder* discarder;
detail::PacketFilter* packet_filter;
uint64_t num_packets_processed;
detail::PacketProfiler* pkt_profiler;
};
namespace detail {
class IPTunnelTimer final : 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, bool 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;
};
} // namespace detail
// Manager for the currently active sessions.
extern NetSessions* sessions;
@ -280,7 +192,6 @@ extern NetSessions* sessions;
using SessionStats [[deprecated("Remove in v4.1. Use zeek::SessionStats.")]] = zeek::SessionStats;
using NetSessions [[deprecated("Remove in v4.1. Use zeek::NetSessions.")]] = zeek::NetSessions;
using IPTunnelTimer [[deprecated("Remove in v4.1. Use zeek::detail::IPTunnelTimer.")]] = zeek::detail::IPTunnelTimer;
using FragReassemblerTracker [[deprecated("Remove in v4.1. Use zeek::detail::FragReassemblerTracker.")]] = zeek::detail::FragReassemblerTracker;
extern zeek::NetSessions*& sessions [[deprecated("Remove in v4.1. Use zeek:sessions.")]];