diff --git a/src/packet_analysis/protocol/iptunnel/IPTunnel.cc b/src/packet_analysis/protocol/iptunnel/IPTunnel.cc index dadce0a4b5..699572a950 100644 --- a/src/packet_analysis/protocol/iptunnel/IPTunnel.cc +++ b/src/packet_analysis/protocol/iptunnel/IPTunnel.cc @@ -4,6 +4,7 @@ #include // For DLT_ constants +#include "zeek/Conn.h" #include "zeek/IP.h" #include "zeek/RunState.h" #include "zeek/TunnelEncapsulation.h" @@ -170,6 +171,37 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt, ui return return_val; } +std::unique_ptr build_inner_packet(Packet* outer_pkt, int* encap_index, + std::shared_ptr encap_stack, + uint32_t len, const u_char* data, int link_type, + BifEnum::Tunnel::Type tunnel_type, + const Tag& analyzer_tag) + { + auto inner_pkt = std::make_unique(); + + pkt_timeval ts; + ts.tv_sec = static_cast(run_state::current_timestamp); + ts.tv_usec = static_cast( + (run_state::current_timestamp - static_cast(ts.tv_sec)) * 1000000); + inner_pkt->Init(link_type, &ts, len, len, data); + + *encap_index = 0; + if ( outer_pkt->session ) + { + EncapsulatingConn inner(static_cast(outer_pkt->session), tunnel_type); + + if ( ! outer_pkt->encap ) + outer_pkt->encap = encap_stack != nullptr ? encap_stack + : std::make_shared(); + + outer_pkt->encap->Add(inner); + inner_pkt->encap = outer_pkt->encap; + *encap_index = outer_pkt->encap->Depth(); + } + + return inner_pkt; + } + namespace detail { diff --git a/src/packet_analysis/protocol/iptunnel/IPTunnel.h b/src/packet_analysis/protocol/iptunnel/IPTunnel.h index 71c7be7b7a..dcb528fb29 100644 --- a/src/packet_analysis/protocol/iptunnel/IPTunnel.h +++ b/src/packet_analysis/protocol/iptunnel/IPTunnel.h @@ -78,6 +78,31 @@ protected: IPTunnelMap ip_tunnels; }; +/** + * Utility function for packet analyzers for encapsulation/tunnel protocols. This + * builds a new packet object containing the encapsulated/tunneled packet, as well + * as adding to the associated encapsulation stack for the tunnel. + * + * @param outer_pkt The packet containing the encapsulation. This packet should contain + * @param encap_index A return value for the current index into the encapsulation stack. + * This is returned to allow analzyers to know what point in the stack they were operating + * on as the packet analysis chain unwinds as it returns. + * @param encap_stack Tracks the encapsulations as the new encapsulations are discovered + * in the inner packets. + * @param len The byte length of the packet data containing in the inner packet. + * @param data A pointer to the first byte of the inner packet. + * @param link_type The link type (DLT_*) for the outer packet. If not known, DLT_RAW can + * be passed for this value. + * @param tunnel_type The type of tunnel the inner packet is stored in. + * @param analyzer_tag The tag for the analyzer calling this method. + * return A new packet object describing the encapsulated packet and data. + */ +extern std::unique_ptr build_inner_packet(Packet* outer_pkt, int* encap_index, + std::shared_ptr encap_stack, + uint32_t len, const u_char* data, int link_type, + BifEnum::Tunnel::Type tunnel_type, + const Tag& analyzer_tag); + namespace detail {