Use shared_ptr for encapsulation data instead of raw pointer

This commit is contained in:
Tim Wojtulewicz 2020-10-12 13:15:52 -07:00
parent a7d4364334
commit 41dcd0cde0
16 changed files with 103 additions and 115 deletions

View file

@ -119,11 +119,21 @@ Connection::Connection(NetSessions* s, const detail::ConnIDKey& k, double t,
++total_connections;
if ( arg_encap )
encapsulation = new EncapsulationStack(*arg_encap);
encapsulation = std::make_unique<EncapsulationStack>(*arg_encap);
else
encapsulation = nullptr;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Connection::Connection(NetSessions* s, const detail::ConnIDKey& k, double t,
const ConnID* id, uint32_t flow, const Packet* pkt)
: Connection(s, k, t, id, flow, pkt, pkt->encap.get())
{
}
#pragma GCC diagnostic pop
Connection::~Connection()
{
if ( ! finished )
@ -135,12 +145,11 @@ Connection::~Connection()
conn_val->SetOrigin(nullptr);
delete root_analyzer;
delete encapsulation;
--current_connections;
}
void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& arg_encap)
{
if ( encapsulation && arg_encap )
{
@ -150,8 +159,7 @@ void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
EnqueueEvent(tunnel_changed, nullptr, ConnVal(),
arg_encap->ToVal());
delete encapsulation;
encapsulation = new EncapsulationStack(*arg_encap);
encapsulation = std::make_shared<EncapsulationStack>(*arg_encap);
}
}
@ -163,7 +171,6 @@ void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
EnqueueEvent(tunnel_changed, nullptr, ConnVal(), empty.ToVal());
}
delete encapsulation;
encapsulation = nullptr;
}
@ -172,7 +179,7 @@ void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
if ( tunnel_changed )
EnqueueEvent(tunnel_changed, nullptr, ConnVal(), arg_encap->ToVal());
encapsulation = new EncapsulationStack(*arg_encap);
encapsulation = std::make_shared<EncapsulationStack>(*arg_encap);
}
}

View file

@ -63,8 +63,12 @@ static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1,
class Connection final : public Obj {
public:
[[deprecated("Remove in v4.1. Store encapsulation in the packet and use the other version of the constructor instead.")]]
Connection(NetSessions* s, const detail::ConnIDKey& k, double t, const ConnID* id,
uint32_t flow, const Packet* pkt, const EncapsulationStack* arg_encap);
Connection(NetSessions* s, const detail::ConnIDKey& k, double t, const ConnID* id,
uint32_t flow, const Packet* pkt);
~Connection() override;
// Invoked when an encapsulation is discovered. It records the
@ -72,7 +76,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 EncapsulationStack* encap);
void CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& encap);
// Invoked when connection is about to be removed. Use Ref(this)
// inside Done to keep the connection object around (though it'll
@ -306,7 +310,7 @@ public:
UID GetUID() const { return uid; }
EncapsulationStack* GetEncapsulation() const
std::shared_ptr<EncapsulationStack> GetEncapsulation() const
{ return encapsulation; }
void CheckFlowLabel(bool is_orig, uint32_t flow_label);
@ -351,7 +355,7 @@ protected:
double start_time, last_time;
double inactivity_timeout;
RecordValPtr conn_val;
EncapsulationStack* encapsulation; // tunnels
std::shared_ptr<EncapsulationStack> encapsulation; // tunnels
int suppress_event; // suppress certain events to once per conn.
unsigned int installed_status_timer:1;

View file

@ -81,8 +81,7 @@ void NetSessions::NextPacket(double t, Packet* pkt)
packet_mgr->ProcessPacket(pkt);
}
void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr,
const EncapsulationStack* encapsulation)
void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr)
{
uint32_t caplen = pkt->cap_len - pkt->hdr_size;
uint32_t len = ip_hdr->TotalLen();
@ -93,7 +92,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
int proto = ip_hdr->NextProto();
if ( CheckHeaderTrunc(proto, len, caplen, pkt, encapsulation) )
if ( CheckHeaderTrunc(proto, len, caplen, pkt) )
return;
const u_char* data = ip_hdr->Payload();
@ -158,7 +157,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
}
default:
Weird("unknown_protocol", pkt, encapsulation, util::fmt("%d", proto));
Weird("unknown_protocol", pkt, pkt->encap, util::fmt("%d", proto));
return;
}
@ -173,7 +172,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
if ( ! conn )
{
conn = NewConn(key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt, encapsulation);
conn = NewConn(key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt);
if ( conn )
InsertConnection(d, key, conn);
}
@ -185,13 +184,13 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
conn->Event(connection_reused, nullptr);
Remove(conn);
conn = NewConn(key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt, encapsulation);
conn = NewConn(key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt);
if ( conn )
InsertConnection(d, key, conn);
}
else
{
conn->CheckEncapsulation(encapsulation);
conn->CheckEncapsulation(pkt->encap);
}
}
@ -275,7 +274,7 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
}
bool NetSessions::CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen,
const Packet* p, const EncapsulationStack* encap)
const Packet* p)
{
uint32_t min_hdr_len = 0;
switch ( proto ) {
@ -295,13 +294,13 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen,
if ( len < min_hdr_len )
{
Weird("truncated_header", p, encap);
Weird("truncated_header", p, p->encap);
return true;
}
if ( caplen < min_hdr_len )
{
Weird("internally_truncated_header", p, encap);
Weird("internally_truncated_header", p, p->encap);
return true;
}
@ -537,7 +536,7 @@ void NetSessions::GetStats(SessionStats& s) const
Connection* NetSessions::NewConn(const detail::ConnIDKey& k, double t, const ConnID* id,
const u_char* data, int proto, uint32_t flow_label,
const Packet* pkt, const EncapsulationStack* encapsulation)
const Packet* pkt)
{
// 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.
@ -576,7 +575,7 @@ Connection* NetSessions::NewConn(const detail::ConnIDKey& k, double t, const Con
if ( ! WantConnection(src_h, dst_h, tproto, flags, flip) )
return nullptr;
Connection* conn = new Connection(this, k, t, id, flow_label, pkt, encapsulation);
Connection* conn = new Connection(this, k, t, id, flow_label, pkt);
conn->SetTransport(tproto);
if ( flip )
@ -632,8 +631,8 @@ bool NetSessions::IsLikelyServerPort(uint32_t port, TransportProto proto) const
}
bool NetSessions::WantConnection(uint16_t src_port, uint16_t dst_port,
TransportProto transport_proto,
uint8_t tcp_flags, bool& flip_roles)
TransportProto transport_proto,
uint8_t tcp_flags, bool& flip_roles)
{
flip_roles = false;
@ -679,7 +678,8 @@ bool NetSessions::WantConnection(uint16_t src_port, uint16_t dst_port,
}
void NetSessions::Weird(const char* name, const Packet* pkt,
const EncapsulationStack* encap, const char* addl)
const std::shared_ptr<EncapsulationStack>& encap,
const char* addl)
{
if ( pkt )
pkt->dump_packet = true;
@ -691,7 +691,8 @@ void NetSessions::Weird(const char* name, const Packet* pkt,
}
void NetSessions::Weird(const char* name, const IP_Hdr* ip,
const EncapsulationStack* encap, const char* addl)
const std::shared_ptr<EncapsulationStack>& encap,
const char* addl)
{
if ( encap && encap->LastType() != BifEnum::Tunnel::NONE )
reporter->Weird(ip->SrcAddr(), ip->DstAddr(),

View file

@ -13,7 +13,6 @@
#include <sys/types.h> // for u_char
ZEEK_FORWARD_DECLARE_NAMESPACED(EncapsulationStack, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(EncapsulatingConn, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(Packet, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(Connection, zeek);
class ConnCompressor;
@ -72,9 +71,11 @@ public:
void GetStats(SessionStats& s) const;
void Weird(const char* name, const Packet* pkt,
const EncapsulationStack* encap = nullptr, const char* addl = "");
const std::shared_ptr<EncapsulationStack>& encap = nullptr,
const char* addl = "");
void Weird(const char* name, const IP_Hdr* ip,
const EncapsulationStack* encap = nullptr, const char* addl = "");
const std::shared_ptr<EncapsulationStack>& encap = nullptr,
const char* addl = "");
detail::PacketFilter* GetPacketFilter(bool init=true)
{
@ -95,8 +96,7 @@ public:
* 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);
void DoNextPacket(double t, const Packet *pkt, const IP_Hdr* ip_hdr);
/**
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
@ -134,8 +134,8 @@ protected:
using ConnectionMap = std::map<detail::ConnIDKey, Connection*>;
Connection* NewConn(const detail::ConnIDKey& k, double t, const ConnID* id,
const u_char* data, int proto, uint32_t flow_label,
const Packet* pkt, const EncapsulationStack* encapsulation);
const u_char* data, int proto, uint32_t flow_label,
const Packet* pkt);
Connection* LookupConn(const ConnectionMap& conns, const detail::ConnIDKey& key);
@ -145,8 +145,7 @@ protected:
// generally a likely server port, false otherwise.
//
// Note, port is in host order.
bool IsLikelyServerPort(uint32_t port,
TransportProto transport_proto) const;
bool IsLikelyServerPort(uint32_t 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
@ -154,14 +153,13 @@ protected:
// originator and responder (based on known ports or such).
// Use tcp_flags=0 for non-TCP.
bool WantConnection(uint16_t src_port, uint16_t dest_port,
TransportProto transport_proto,
uint8_t tcp_flags, bool& flip_roles);
TransportProto transport_proto,
uint8_t tcp_flags, bool& flip_roles);
// 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_t len, uint32_t caplen,
const Packet *pkt, const EncapsulationStack* encap);
bool CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen, const Packet *pkt);
// Inserts a new connection into the sessions map. If a connection with
// the same key already exists in the map, it will be overwritten by

View file

@ -50,7 +50,7 @@ void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint6
if ( result == 0 )
{
ProtocolConfirmation();
const zeek::EncapsulationStack* e = Conn()->GetEncapsulation();
std:shared_ptr<EncapsulationStack> e = Conn()->GetEncapsulation();
EncapsulatingConn ec(Conn(), BifEnum::Tunnel::AYIYA);
packet_analysis::IPTunnel::ip_tunnel_analyzer->ProcessEncapsulatedPacket(
run_state::network_time, nullptr, inner, e, ec);

View file

@ -17,7 +17,7 @@ flow AYIYA_Flow
function process_ayiya(pdu: PDU): bool
%{
zeek::Connection* c = connection()->zeek_analyzer()->Conn();
const zeek::EncapsulationStack* e = c->GetEncapsulation();
std:shared_ptr<zeek::EncapsulationStack> e = c->GetEncapsulation();
if ( e && e->Depth() >= zeek::BifConst::Tunnel::max_depth )
{

View file

@ -62,7 +62,7 @@ void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint6
std::move(gtp_hdr_val),
inner->ToPktHdrVal());
const zeek::EncapsulationStack* e = Conn()->GetEncapsulation();
std::shared_ptr<zeek::EncapsulationStack> e = Conn()->GetEncapsulation();
EncapsulatingConn ec(Conn(), BifEnum::Tunnel::GTPv1);
zeek::packet_analysis::IPTunnel::ip_tunnel_analyzer->ProcessEncapsulatedPacket(
run_state::network_time, nullptr, inner, e, ec);

View file

@ -649,7 +649,7 @@ flow GTPv1_Flow(is_orig: bool)
%{
ZeekAnalyzer a = connection()->zeek_analyzer();
zeek::Connection* c = a->Conn();
const zeek::EncapsulationStack* e = c->GetEncapsulation();
const std::shared_ptr<zeek::EncapsulationStack> e = c->GetEncapsulation();
connection()->set_valid(is_orig(), false);

View file

@ -158,7 +158,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
return;
}
const EncapsulationStack* e = Conn()->GetEncapsulation();
std::shared_ptr<EncapsulationStack> e = Conn()->GetEncapsulation();
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
{

View file

@ -48,7 +48,7 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
return;
}
EncapsulationStack* outer = Conn()->GetEncapsulation();
std::shared_ptr<EncapsulationStack> outer = Conn()->GetEncapsulation();
if ( outer && outer->Depth() >= BifConst::Tunnel::max_depth )
{
@ -56,12 +56,8 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
return;
}
bool delete_outer = false;
if ( ! outer )
{
outer = new EncapsulationStack();
delete_outer = true;
}
outer = std::make_shared<EncapsulationStack>();
EncapsulatingConn inner(Conn(), BifEnum::Tunnel::VXLAN);
outer->Add(inner);
@ -83,9 +79,6 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
if ( ! pkt.l2_valid )
{
if ( delete_outer )
delete outer;
ProtocolViolation("VXLAN invalid inner ethernet frame",
(const char*) data, len);
return;
@ -97,9 +90,6 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
if ( ! pkt.ip_hdr )
{
if ( delete_outer )
delete outer;
ProtocolViolation("Truncated VXLAN or invalid inner IP",
(const char*) data, len);
return;
@ -110,9 +100,6 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
if ( vxlan_packet )
Conn()->EnqueueEvent(vxlan_packet, nullptr, ConnVal(),
pkt.ip_hdr->ToPktHdrVal(), val_mgr->Count(vni));
if ( delete_outer )
delete outer;
}
} // namespace zeek::analyzer::vxlan

View file

@ -62,8 +62,7 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen,
l3_proto = L3_UNKNOWN;
l3_checksummed = false;
delete encap;
encap = nullptr;
encap.reset();
delete ip_hdr;
ip_hdr = nullptr;
@ -93,7 +92,7 @@ const IP_Hdr Packet::IP() const
return IP_Hdr((struct ip *) (data + hdr_size), false);
}
void Packet::Weird(const char* name, const EncapsulationStack* encap)
void Packet::Weird(const char* name, const std::shared_ptr<EncapsulationStack>& encap)
{
sessions->Weird(name, this, encap);
}

View file

@ -17,12 +17,12 @@ typedef struct timeval pkt_timeval;
#include "pcap.h" // For DLT_ constants
#include "zeek/NetVar.h" // For BifEnum::Tunnel
#include "zeek/TunnelEncapsulation.h"
ZEEK_FORWARD_DECLARE_NAMESPACED(ODesc, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(Val, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(RecordVal, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(IP_Hdr, zeek);
ZEEK_FORWARD_DECLARE_NAMESPACED(EncapsulationStack, zeek);
namespace zeek {
@ -132,7 +132,7 @@ public:
RecordVal* BuildPktHdrVal() const;
// Wrapper to generate a packet-level weird. Has to be public for llanalyzers to use it.
void Weird(const char* name, const EncapsulationStack* encap = nullptr);
void Weird(const char* name, const std::shared_ptr<EncapsulationStack>& encap = nullptr);
/**
* Maximal length of a layer 2 address.
@ -227,7 +227,7 @@ public:
* used by the tunnel analyzers to keep track of the encapsulations as
* processing occurs.
*/
EncapsulationStack* encap = nullptr;
std::shared_ptr<EncapsulationStack> encap = nullptr;
/**
* The IP header for this packet. This is filled in by the IP analyzer

View file

@ -42,8 +42,6 @@ GREAnalyzer::GREAnalyzer()
bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
{
EncapsulationStack* encapsulation = packet->encap;
if ( ! packet->ip_hdr )
{
reporter->InternalError("GREAnalyzer: ip_hdr not found in packet keystore");
@ -54,7 +52,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( ! BifConst::Tunnel::enable_gre )
{
sessions->Weird("GRE_tunnel", ip_hdr, encapsulation);
sessions->Weird("GRE_tunnel", ip_hdr, packet->encap);
return false;
}
@ -72,7 +70,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( gre_version != 0 && gre_version != 1 )
{
sessions->Weird("unknown_gre_version", ip_hdr, encapsulation,
sessions->Weird("unknown_gre_version", ip_hdr, packet->encap,
util::fmt("%d", gre_version));
return false;
}
@ -90,7 +88,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
}
else
{
sessions->Weird("truncated_GRE", ip_hdr, encapsulation);
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
return false;
}
}
@ -107,7 +105,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
}
else
{
sessions->Weird("truncated_GRE", ip_hdr, encapsulation);
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
return false;
}
}
@ -130,7 +128,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
erspan_len += 8;
else
{
sessions->Weird("truncated_GRE", ip_hdr, encapsulation);
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
return false;
}
}
@ -139,7 +137,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
}
else
{
sessions->Weird("truncated_GRE", ip_hdr, encapsulation);
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
return false;
}
}
@ -150,7 +148,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( proto_typ != 0x880b )
{
// Enhanced GRE payload must be PPP.
sessions->Weird("egre_protocol_type", ip_hdr, encapsulation,
sessions->Weird("egre_protocol_type", ip_hdr, packet->encap,
util::fmt("%d", proto_typ));
return false;
}
@ -161,20 +159,20 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
// RFC 2784 deprecates the variable length routing field
// specified by RFC 1701. It could be parsed here, but easiest
// to just skip for now.
sessions->Weird("gre_routing", ip_hdr, encapsulation);
sessions->Weird("gre_routing", ip_hdr, packet->encap);
return false;
}
if ( flags_ver & 0x0078 )
{
// Expect last 4 bits of flags are reserved, undefined.
sessions->Weird("unknown_gre_flags", ip_hdr, encapsulation);
sessions->Weird("unknown_gre_flags", ip_hdr, packet->encap);
return false;
}
if ( len < gre_len + ppp_len + eth_len + erspan_len )
{
sessions->Weird("truncated_GRE", ip_hdr, encapsulation);
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
return false;
}
@ -184,7 +182,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( ppp_proto != 0x0021 && ppp_proto != 0x0057 )
{
sessions->Weird("non_ip_packet_in_encap", ip_hdr, encapsulation);
sessions->Weird("non_ip_packet_in_encap", ip_hdr, packet->encap);
return false;
}

View file

@ -30,8 +30,6 @@ IPAnalyzer::~IPAnalyzer()
bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
{
EncapsulationStack* encapsulation = packet->encap;
// Check to make sure we have enough data left for an IP header to be here. Note we only
// check ipv4 here. We'll check ipv6 later once we determine we have an ipv6 header.
if ( len < sizeof(struct ip) )
@ -85,7 +83,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( total_len == 0 )
{
// TCP segmentation offloading can zero out the ip_len field.
packet->Weird("ip_hdr_len_zero", encapsulation);
packet->Weird("ip_hdr_len_zero", packet->encap);
// Cope with the zero'd out ip_len field by using the caplen.
total_len = packet->cap_len - packet->hdr_size;
@ -93,7 +91,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( packet->len < total_len + packet->hdr_size )
{
packet->Weird("truncated_IPv6", encapsulation);
packet->Weird("truncated_IPv6", packet->encap);
return false;
}
@ -102,13 +100,13 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
uint16_t ip_hdr_len = ip_hdr->HdrLen();
if ( ip_hdr_len > total_len )
{
sessions->Weird("invalid_IP_header_size", ip_hdr, encapsulation);
sessions->Weird("invalid_IP_header_size", ip_hdr, packet->encap);
return false;
}
if ( ip_hdr_len > len )
{
sessions->Weird("internally_truncated_header", ip_hdr, encapsulation);
sessions->Weird("internally_truncated_header", ip_hdr, packet->encap);
return false;
}
@ -137,7 +135,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( ! packet->l2_checksummed && ! detail::ignore_checksums && ip4 &&
detail::in_cksum(reinterpret_cast<const uint8_t*>(ip4), ip_hdr_len) != 0xffff )
{
sessions->Weird("bad_IP_checksum", packet, encapsulation);
sessions->Weird("bad_IP_checksum", packet, packet->encap);
return false;
}
@ -152,7 +150,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( len < total_len )
{
sessions->Weird("incompletely_captured_fragment", ip_hdr, encapsulation);
sessions->Weird("incompletely_captured_fragment", ip_hdr, packet->encap);
// Don't try to reassemble, that's doomed.
// Discard all except the first fragment (which
@ -162,7 +160,8 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
}
else
{
f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, ip_hdr, packet->data + packet->hdr_size);
f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, ip_hdr,
packet->data + packet->hdr_size);
IP_Hdr* ih = f->ReassembledPkt();
if ( ! ih )
// It didn't reassemble into anything yet.
@ -182,7 +181,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( ip_hdr_len > total_len )
{
sessions->Weird("invalid_IP_header_size", ip_hdr, encapsulation);
sessions->Weird("invalid_IP_header_size", ip_hdr, packet->encap);
return false;
}
}
@ -211,7 +210,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
if ( ! ignore_checksums && mobility_header_checksum(ip_hdr) != 0xffff )
{
sessions->Weird("bad_MH_checksum", packet, encapsulation);
sessions->Weird("bad_MH_checksum", packet, packet->encap);
return false;
}
@ -219,7 +218,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
event_mgr.Enqueue(mobile_ipv6_message, ip_hdr->ToPktHdrVal());
if ( ip_hdr->NextProto() != IPPROTO_NONE )
sessions->Weird("mobility_piggyback", packet, encapsulation);
sessions->Weird("mobility_piggyback", packet, packet->encap);
return true;
}
@ -248,14 +247,14 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
case IPPROTO_ICMPV6:
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
GetAnalyzerName(), proto);
sessions->DoNextPacket(run_state::processing_start_time, packet, ip_hdr, encapsulation);
sessions->DoNextPacket(run_state::processing_start_time, packet, ip_hdr);
break;
case IPPROTO_NONE:
// If the packet is encapsulated in Teredo, then it was a bubble and
// the Teredo analyzer may have raised an event for that, else we're
// not sure the reason for the No Next header in the packet.
if ( ! ( encapsulation &&
encapsulation->LastType() == BifEnum::Tunnel::TEREDO ) )
if ( ! ( packet->encap &&
packet->encap->LastType() == BifEnum::Tunnel::TEREDO ) )
{
sessions->Weird("ipv6_no_next", packet);
return_val = false;

View file

@ -20,8 +20,6 @@ IPTunnelAnalyzer::IPTunnelAnalyzer()
bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
{
EncapsulationStack* encapsulation = packet->encap;
if ( ! packet->ip_hdr )
{
reporter->InternalError("IPTunnelAnalyzer: ip_hdr not found in packet keystore");
@ -32,14 +30,14 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
if ( ! BifConst::Tunnel::enable_ip )
{
sessions->Weird("IP_tunnel", ip_hdr, encapsulation);
sessions->Weird("IP_tunnel", ip_hdr, packet->encap);
return false;
}
if ( encapsulation &&
encapsulation->Depth() >= BifConst::Tunnel::max_depth )
if ( packet->encap &&
packet->encap->Depth() >= BifConst::Tunnel::max_depth )
{
sessions->Weird("exceeded_tunnel_max_depth", ip_hdr, encapsulation);
sessions->Weird("exceeded_tunnel_max_depth", ip_hdr, packet->encap);
return false;
}
@ -55,11 +53,11 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
// Check for a valid inner packet first.
int result = sessions->ParseIPPacket(len, data, proto, inner);
if ( result == -2 )
sessions->Weird("invalid_inner_IP_version", ip_hdr, encapsulation);
sessions->Weird("invalid_inner_IP_version", ip_hdr, packet->encap);
else if ( result < 0 )
sessions->Weird("truncated_inner_IP", ip_hdr, encapsulation);
sessions->Weird("truncated_inner_IP", ip_hdr, packet->encap);
else if ( result > 0 )
sessions->Weird("inner_IP_payload_length_mismatch", ip_hdr, encapsulation);
sessions->Weird("inner_IP_payload_length_mismatch", ip_hdr, packet->encap);
if ( result != 0 )
{
@ -91,9 +89,9 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
if ( gre_version == 0 )
ProcessEncapsulatedPacket(run_state::processing_start_time, packet, len, len, data, gre_link_type,
encapsulation, ip_tunnels[tunnel_idx].first);
packet->encap, ip_tunnels[tunnel_idx].first);
else
ProcessEncapsulatedPacket(run_state::processing_start_time, packet, inner, encapsulation,
ProcessEncapsulatedPacket(run_state::processing_start_time, packet, inner, packet->encap,
ip_tunnels[tunnel_idx].first);
return true;
@ -103,7 +101,8 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
* Handles a packet that contains an IP header directly after the tunnel header.
*/
bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
const IP_Hdr* inner, const EncapsulationStack* prev,
const IP_Hdr* inner,
std::shared_ptr<EncapsulationStack> prev,
const EncapsulatingConn& ec)
{
uint32_t caplen, len;
@ -128,8 +127,7 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
else
data = (const u_char*) inner->IP6_Hdr();
EncapsulationStack* outer = prev ?
new EncapsulationStack(*prev) : new EncapsulationStack();
auto outer = prev ? prev : std::make_shared<EncapsulationStack>();
outer->Add(ec);
// Construct fake packet for DoNextPacket
@ -141,7 +139,6 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
bool return_val = ForwardPacket(len, data, &p);
delete inner;
delete outer;
return return_val;
}
@ -152,7 +149,7 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
uint32_t caplen, uint32_t len,
const u_char* data, int link_type,
const EncapsulationStack* prev,
std::shared_ptr<EncapsulationStack> prev,
const EncapsulatingConn& ec)
{
pkt_timeval ts;
@ -166,8 +163,7 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
((run_state::network_time - (double)ts.tv_sec) * 1000000);
}
EncapsulationStack* outer = prev ?
new EncapsulationStack(*prev) : new EncapsulationStack();
auto outer = prev ? prev : std::make_shared<EncapsulationStack>();
outer->Add(ec);
// Construct fake packet for DoNextPacket
@ -179,8 +175,6 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
// to the packet manager.
bool return_val = packet_mgr->ProcessInnerPacket(&p);
delete outer;
return return_val;
}

View file

@ -40,7 +40,8 @@ public:
* @param ec The most-recently found depth of encapsulation.
*/
bool ProcessEncapsulatedPacket(double t, const Packet *pkt,
const IP_Hdr* inner, const EncapsulationStack* prev,
const IP_Hdr* inner,
std::shared_ptr<EncapsulationStack> prev,
const EncapsulatingConn& ec);
/**
@ -62,7 +63,7 @@ public:
bool ProcessEncapsulatedPacket(double t, const Packet* pkt,
uint32_t caplen, uint32_t len,
const u_char* data, int link_type,
const EncapsulationStack* prev,
std::shared_ptr<EncapsulationStack> prev,
const EncapsulatingConn& ec);
protected: