diff --git a/src/analyzer/protocol/vxlan/VXLAN.cc b/src/analyzer/protocol/vxlan/VXLAN.cc index 2469c94575..85c598dcf1 100644 --- a/src/analyzer/protocol/vxlan/VXLAN.cc +++ b/src/analyzer/protocol/vxlan/VXLAN.cc @@ -77,7 +77,8 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, ts.tv_sec = (time_t) run_state::current_timestamp; ts.tv_usec = (suseconds_t) ((run_state::current_timestamp - (double)ts.tv_sec) * 1000000); Packet pkt(DLT_EN10MB, &ts, caplen, len, data); - pkt.key_store["encap"] = outer; + pkt.encap = outer; + packet_mgr->ProcessPacket(&pkt); if ( ! pkt.l2_valid ) diff --git a/src/iosource/Packet.h b/src/iosource/Packet.h index 91bb95a64a..ba91b2642f 100644 --- a/src/iosource/Packet.h +++ b/src/iosource/Packet.h @@ -15,6 +15,9 @@ typedef struct bpf_timeval pkt_timeval; typedef struct timeval pkt_timeval; #endif +#include "pcap.h" // For DLT_ constants +#include "NetVar.h" // For BifEnum::Tunnel + ZEEK_FORWARD_DECLARE_NAMESPACED(ODesc, zeek); ZEEK_FORWARD_DECLARE_NAMESPACED(Val, zeek); ZEEK_FORWARD_DECLARE_NAMESPACED(RecordVal, zeek); @@ -214,10 +217,15 @@ public: */ mutable bool dump_packet; - /** - * Key/value store for use by the packet analyzers to pass information between them. - */ - std::map key_store; + // These are fields passed between various packet analyzers. They're best + // stored with the packet so they stay available as the packet is passed + // around. + EncapsulationStack* encap = nullptr; + IP_Hdr* ip_hdr = nullptr; + int proto = -1; + BifEnum::Tunnel::Type tunnel_type = BifEnum::Tunnel::IP; + int gre_version = -1; + int gre_link_type = DLT_RAW; // 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); diff --git a/src/packet_analysis/protocol/gre/GRE.cc b/src/packet_analysis/protocol/gre/GRE.cc index 756fa50add..81bb44f8e7 100644 --- a/src/packet_analysis/protocol/gre/GRE.cc +++ b/src/packet_analysis/protocol/gre/GRE.cc @@ -42,24 +42,15 @@ GREAnalyzer::GREAnalyzer() bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) { - EncapsulationStack* encapsulation = nullptr; - auto it = packet->key_store.find("encap"); - if ( it != packet->key_store.end() ) - encapsulation = std::any_cast(it->second); + EncapsulationStack* encapsulation = packet->encap; - it = packet->key_store.find("ip_hdr"); - if ( it == packet->key_store.end() ) + if ( ! packet->ip_hdr ) { reporter->InternalError("GREAnalyzer: ip_hdr not found in packet keystore"); return false; } - IP_Hdr* ip_hdr = std::any_cast(it->second); - - int proto = -1; - it = packet->key_store.find("proto"); - if ( it != packet->key_store.end() ) - proto = std::any_cast(proto); + IP_Hdr* ip_hdr = packet->ip_hdr; if ( ! BifConst::Tunnel::enable_gre ) { @@ -67,6 +58,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) return false; } + int proto = packet->proto; int gre_link_type = DLT_RAW; uint16_t flags_ver = ntohs(*((uint16_t*)(data + 0))); @@ -205,12 +197,10 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) // Treat GRE tunnel like IP tunnels, fallthrough to logic below now // that GRE header is stripped and only payload packet remains. // The only thing different is the tunnel type enum value to use. - BifEnum::Tunnel::Type tunnel_type = BifEnum::Tunnel::GRE; - - packet->key_store["tunnel_type"] = tunnel_type; - packet->key_store["gre_version"] = gre_version; - packet->key_store["gre_link_type"] = gre_link_type; - packet->key_store["proto"] = proto; + packet->tunnel_type = BifEnum::Tunnel::GRE; + packet->gre_version = gre_version; + packet->gre_link_type = gre_link_type; + packet->proto = proto; ForwardPacket(len, data, packet); diff --git a/src/packet_analysis/protocol/ip/IP.cc b/src/packet_analysis/protocol/ip/IP.cc index 89680b9aac..ade5b69155 100644 --- a/src/packet_analysis/protocol/ip/IP.cc +++ b/src/packet_analysis/protocol/ip/IP.cc @@ -30,10 +30,7 @@ IPAnalyzer::~IPAnalyzer() bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) { - EncapsulationStack* encapsulation = nullptr; - auto it = packet->key_store.find("encap"); - if ( it != packet->key_store.end() ) - encapsulation = std::any_cast(it->second); + 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. @@ -53,6 +50,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) auto ip = (const struct ip *)data; uint32_t protocol = ip->ip_v; + // This is a unique pointer because of the mass of early returns from this method. std::unique_ptr ip_hdr = nullptr; if ( protocol == 4 ) { @@ -254,8 +252,8 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) break; default: // The tunnel analyzer needs this data. - packet->key_store["ip_hdr"] = ip_hdr.get(); - packet->key_store["proto"] = proto; + packet->ip_hdr = ip_hdr.get(); + packet->proto = proto; // For everything else, pass it on to another analyzer. If there's no one to handle that, // it'll report a Weird. diff --git a/src/packet_analysis/protocol/iptunnel/IPTunnel.cc b/src/packet_analysis/protocol/iptunnel/IPTunnel.cc index 285557274c..8279ba87c2 100644 --- a/src/packet_analysis/protocol/iptunnel/IPTunnel.cc +++ b/src/packet_analysis/protocol/iptunnel/IPTunnel.cc @@ -20,39 +20,15 @@ IPTunnelAnalyzer::IPTunnelAnalyzer() bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) { - EncapsulationStack* encapsulation = nullptr; - auto it = packet->key_store.find("encap"); - if ( it != packet->key_store.end() ) - encapsulation = std::any_cast(it->second); + EncapsulationStack* encapsulation = packet->encap; - it = packet->key_store.find("ip_hdr"); - if ( it == packet->key_store.end() ) + if ( ! packet->ip_hdr ) { reporter->InternalError("IPTunnelAnalyzer: ip_hdr not found in packet keystore"); return false; } - IP_Hdr* ip_hdr = std::any_cast(it->second); - - int proto = -1; - it = packet->key_store.find("proto"); - if ( it != packet->key_store.end() ) - proto = std::any_cast(it->second); - - int gre_version = -1; - it = packet->key_store.find("gre_version"); - if ( it != packet->key_store.end() ) - gre_version = std::any_cast(it->second); - - BifEnum::Tunnel::Type tunnel_type = BifEnum::Tunnel::IP; - it = packet->key_store.find("tunnel_type"); - if ( it != packet->key_store.end() ) - tunnel_type = std::any_cast(it->second); - - int gre_link_type = DLT_RAW; - it = packet->key_store.find("gre_link_type"); - if ( it != packet->key_store.end() ) - gre_link_type = std::any_cast(it->second); + IP_Hdr* ip_hdr = packet->ip_hdr; if ( ! BifConst::Tunnel::enable_ip ) { @@ -67,6 +43,11 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa return false; } + int proto = packet->proto; + int gre_version = packet->gre_version; + BifEnum::Tunnel::Type tunnel_type = packet->tunnel_type; + int gre_link_type = packet->gre_link_type; + IP_Hdr* inner = nullptr; if ( gre_version != 0 ) @@ -154,8 +135,7 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt, // Construct fake packet for DoNextPacket Packet p; p.Init(DLT_RAW, &ts, caplen, len, data, false, ""); - p.key_store["encap"] = outer; - p.key_store["encap_inner_ip"] = inner; + p.encap = outer; // Forward the packet back to the IP analyzer. bool return_val = ForwardPacket(len, data, &p); @@ -193,7 +173,7 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt, // Construct fake packet for DoNextPacket Packet p; p.Init(link_type, &ts, caplen, len, data, false, ""); - p.key_store["encap"] = outer; + p.encap = outer; // Process the packet as if it was a brand new packet by passing it back // to the packet manager.