diff --git a/src/packet_analysis/protocol/icmp/CMakeLists.txt b/src/packet_analysis/protocol/icmp/CMakeLists.txt index 875b3597ec..cf60b3925e 100644 --- a/src/packet_analysis/protocol/icmp/CMakeLists.txt +++ b/src/packet_analysis/protocol/icmp/CMakeLists.txt @@ -4,6 +4,6 @@ include(ZeekPlugin) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) zeek_plugin_begin(Zeek ICMP) -zeek_plugin_cc(ICMP.cc Plugin.cc) +zeek_plugin_cc(ICMP.cc ICMPSessionAdapter.cc Plugin.cc) zeek_plugin_bif(events.bif) zeek_plugin_end() diff --git a/src/packet_analysis/protocol/icmp/ICMP.cc b/src/packet_analysis/protocol/icmp/ICMP.cc index 2a68497874..b4ef187cd3 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.cc +++ b/src/packet_analysis/protocol/icmp/ICMP.cc @@ -12,6 +12,7 @@ #include "zeek/analyzer/Manager.h" #include "zeek/session/Manager.h" #include "zeek/analyzer/protocol/conn-size/ConnSize.h" +#include "zeek/packet_analysis/protocol/icmp/ICMPSessionAdapter.h" #include "zeek/ZeekString.h" @@ -801,76 +802,6 @@ zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* dat return vv; } -void ICMPSessionAdapter::AddExtraAnalyzers(Connection* conn) - { - static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); - - if ( analyzer_mgr->IsEnabled(analyzer_connsize) ) - // Add ConnSize analyzer. Needs to see packets, not stream. - AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); - } - -void ICMPSessionAdapter::UpdateConnVal(zeek::RecordVal* conn_val) - { - const auto& orig_endp = conn_val->GetField("orig"); - const auto& resp_endp = conn_val->GetField("resp"); - - UpdateEndpointVal(orig_endp, true); - UpdateEndpointVal(resp_endp, false); - - analyzer::Analyzer::UpdateConnVal(conn_val); - } - -void ICMPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) - { - Conn()->EnableStatusUpdateTimer(); - - int size = is_orig ? request_len : reply_len; - auto endp = endp_arg->AsRecordVal(); - - if ( size < 0 ) - { - endp->Assign(0, val_mgr->Count(0)); - endp->Assign(1, val_mgr->Count(int(ICMP_INACTIVE))); - } - else - { - endp->Assign(0, val_mgr->Count(size)); - endp->Assign(1, val_mgr->Count(int(ICMP_ACTIVE))); - } - } - -void ICMPSessionAdapter::UpdateLength(bool is_orig, int len) - { - int& len_stat = is_orig ? request_len : reply_len; - if ( len_stat < 0 ) - len_stat = len; - else - len_stat += len; - } - -void ICMPSessionAdapter::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig) - { - if ( zeek::detail::rule_matcher ) - { - if ( ! matcher_state.MatcherInitialized(is_orig) ) - matcher_state.InitEndpointMatcher(this, ip_hdr, len, is_orig, nullptr); - } - } - -void ICMPSessionAdapter::MatchEndpoint(const u_char* data, int len, bool is_orig) - { - if ( zeek::detail::rule_matcher ) - matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig, - false, false, true); - } - -void ICMPSessionAdapter::Done() - { - SessionAdapter::Done(); - matcher_state.FinishEndpointMatcher(); - } - namespace zeek::packet_analysis::ICMP { int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way) diff --git a/src/packet_analysis/protocol/icmp/ICMP.h b/src/packet_analysis/protocol/icmp/ICMP.h index eec1eaaac6..259faa9ebf 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.h +++ b/src/packet_analysis/protocol/icmp/ICMP.h @@ -7,7 +7,6 @@ #include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h" #include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" #include "zeek/analyzer/Analyzer.h" -#include "zeek/RuleMatcher.h" namespace zeek { @@ -101,35 +100,6 @@ private: void UpdateEndpointVal(const ValPtr& endp, bool is_orig); }; -class ICMPSessionAdapter final : public IP::SessionAdapter { - -public: - - ICMPSessionAdapter(Connection* conn) : - IP::SessionAdapter("ICMP", conn) { } - - static zeek::analyzer::Analyzer* Instantiate(Connection* conn) - { - return new ICMPSessionAdapter(conn); - } - - void AddExtraAnalyzers(Connection* conn) override; - void UpdateConnVal(RecordVal* conn_val) override; - void UpdateEndpointVal(const ValPtr& endp, bool is_orig); - - void UpdateLength(bool is_orig, int len); - void Done() override; - - void InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig); - void MatchEndpoint(const u_char* data, int len, bool is_orig); - -private: - - detail::RuleMatcherState matcher_state; - int request_len = -1; - int reply_len = -1; -}; - // Returns the counterpart type to the given type (e.g., the counterpart // to ICMP_ECHOREPLY is ICMP_ECHO). extern int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way); diff --git a/src/packet_analysis/protocol/icmp/ICMPSessionAdapter.cc b/src/packet_analysis/protocol/icmp/ICMPSessionAdapter.cc new file mode 100644 index 0000000000..2e28bda845 --- /dev/null +++ b/src/packet_analysis/protocol/icmp/ICMPSessionAdapter.cc @@ -0,0 +1,84 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/packet_analysis/protocol/icmp/ICMPSessionAdapter.h" + +#include "zeek/analyzer/Manager.h" +#include "zeek/analyzer/protocol/conn-size/ConnSize.h" + +using namespace zeek::packet_analysis::ICMP; +using namespace zeek::packet_analysis::IP; + +enum ICMP_EndpointState { + ICMP_INACTIVE, // no packet seen + ICMP_ACTIVE, // packets seen +}; + +void ICMPSessionAdapter::AddExtraAnalyzers(Connection* conn) + { + static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); + + if ( analyzer_mgr->IsEnabled(analyzer_connsize) ) + // Add ConnSize analyzer. Needs to see packets, not stream. + AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); + } + +void ICMPSessionAdapter::UpdateConnVal(zeek::RecordVal* conn_val) + { + const auto& orig_endp = conn_val->GetField("orig"); + const auto& resp_endp = conn_val->GetField("resp"); + + UpdateEndpointVal(orig_endp, true); + UpdateEndpointVal(resp_endp, false); + + analyzer::Analyzer::UpdateConnVal(conn_val); + } + +void ICMPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) + { + Conn()->EnableStatusUpdateTimer(); + + int size = is_orig ? request_len : reply_len; + auto endp = endp_arg->AsRecordVal(); + + if ( size < 0 ) + { + endp->Assign(0, val_mgr->Count(0)); + endp->Assign(1, val_mgr->Count(int(ICMP_INACTIVE))); + } + else + { + endp->Assign(0, val_mgr->Count(size)); + endp->Assign(1, val_mgr->Count(int(ICMP_ACTIVE))); + } + } + +void ICMPSessionAdapter::UpdateLength(bool is_orig, int len) + { + int& len_stat = is_orig ? request_len : reply_len; + if ( len_stat < 0 ) + len_stat = len; + else + len_stat += len; + } + +void ICMPSessionAdapter::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig) + { + if ( zeek::detail::rule_matcher ) + { + if ( ! matcher_state.MatcherInitialized(is_orig) ) + matcher_state.InitEndpointMatcher(this, ip_hdr, len, is_orig, nullptr); + } + } + +void ICMPSessionAdapter::MatchEndpoint(const u_char* data, int len, bool is_orig) + { + if ( zeek::detail::rule_matcher ) + matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig, + false, false, true); + } + +void ICMPSessionAdapter::Done() + { + SessionAdapter::Done(); + matcher_state.FinishEndpointMatcher(); + } diff --git a/src/packet_analysis/protocol/icmp/ICMPSessionAdapter.h b/src/packet_analysis/protocol/icmp/ICMPSessionAdapter.h new file mode 100644 index 0000000000..f4085cb2f1 --- /dev/null +++ b/src/packet_analysis/protocol/icmp/ICMPSessionAdapter.h @@ -0,0 +1,39 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" +#include "zeek/RuleMatcher.h" + +namespace zeek::packet_analysis::ICMP { + +class ICMPSessionAdapter final : public IP::SessionAdapter { + +public: + + ICMPSessionAdapter(Connection* conn) : + IP::SessionAdapter("ICMP", conn) { } + + static zeek::analyzer::Analyzer* Instantiate(Connection* conn) + { + return new ICMPSessionAdapter(conn); + } + + void AddExtraAnalyzers(Connection* conn) override; + void UpdateConnVal(RecordVal* conn_val) override; + void UpdateEndpointVal(const ValPtr& endp, bool is_orig); + + void UpdateLength(bool is_orig, int len); + void Done() override; + + void InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig); + void MatchEndpoint(const u_char* data, int len, bool is_orig); + +private: + + detail::RuleMatcherState matcher_state; + int request_len = -1; + int reply_len = -1; +}; + +} // namespace zeek::packet_analysis::ICMP diff --git a/src/packet_analysis/protocol/icmp/Plugin.cc b/src/packet_analysis/protocol/icmp/Plugin.cc index ffd27aed7c..7e875b4684 100644 --- a/src/packet_analysis/protocol/icmp/Plugin.cc +++ b/src/packet_analysis/protocol/icmp/Plugin.cc @@ -3,6 +3,7 @@ #include "zeek/plugin/Plugin.h" #include "zeek/packet_analysis/Component.h" #include "zeek/packet_analysis/protocol/icmp/ICMP.h" +#include "zeek/packet_analysis/protocol/icmp/ICMPSessionAdapter.h" #include "zeek/analyzer/Component.h" namespace zeek::plugin::Zeek_ICMP { diff --git a/src/packet_analysis/protocol/udp/CMakeLists.txt b/src/packet_analysis/protocol/udp/CMakeLists.txt index 47140a9df2..94952c0256 100644 --- a/src/packet_analysis/protocol/udp/CMakeLists.txt +++ b/src/packet_analysis/protocol/udp/CMakeLists.txt @@ -4,6 +4,6 @@ include(ZeekPlugin) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) zeek_plugin_begin(Zeek UDP) -zeek_plugin_cc(UDP.cc Plugin.cc) +zeek_plugin_cc(UDP.cc UDPSessionAdapter.cc Plugin.cc) zeek_plugin_bif(events.bif) zeek_plugin_end() diff --git a/src/packet_analysis/protocol/udp/Plugin.cc b/src/packet_analysis/protocol/udp/Plugin.cc index c9aee77b25..2933b5b8c4 100644 --- a/src/packet_analysis/protocol/udp/Plugin.cc +++ b/src/packet_analysis/protocol/udp/Plugin.cc @@ -3,6 +3,7 @@ #include "zeek/plugin/Plugin.h" #include "zeek/packet_analysis/Component.h" #include "zeek/packet_analysis/protocol/udp/UDP.h" +#include "zeek/packet_analysis/protocol/udp/UDPSessionAdapter.h" #include "zeek/analyzer/Component.h" namespace zeek::plugin::Zeek_UDP { diff --git a/src/packet_analysis/protocol/udp/UDP.cc b/src/packet_analysis/protocol/udp/UDP.cc index 6f9a001212..f798229118 100644 --- a/src/packet_analysis/protocol/udp/UDP.cc +++ b/src/packet_analysis/protocol/udp/UDP.cc @@ -7,6 +7,7 @@ #include "zeek/analyzer/Manager.h" #include "zeek/analyzer/protocol/pia/PIA.h" #include "zeek/analyzer/protocol/conn-size/ConnSize.h" +#include "zeek/packet_analysis/protocol/udp/UDPSessionAdapter.h" #include "zeek/packet_analysis/protocol/udp/events.bif.h" @@ -18,11 +19,6 @@ constexpr uint32_t HIST_RESP_DATA_PKT = 0x2; constexpr uint32_t HIST_ORIG_CORRUPT_PKT = 0x4; constexpr uint32_t HIST_RESP_CORRUPT_PKT = 0x8; -enum UDP_EndpointState { - UDP_INACTIVE, // no packet seen - UDP_ACTIVE, // packets seen -}; - UDPAnalyzer::UDPAnalyzer() : IPBasedAnalyzer("UDP", TRANSPORT_UDP, UDP_PORT_MASK, false) { } @@ -236,97 +232,3 @@ bool UDPAnalyzer::ValidateChecksum(const IP_Hdr* ip, const udphdr* up, int len) return sum == 0xffff; } - -void UDPSessionAdapter::AddExtraAnalyzers(Connection* conn) - { - static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); - - if ( analyzer_mgr->IsEnabled(analyzer_connsize) ) - // Add ConnSize analyzer. Needs to see packets, not stream. - AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); - } - -void UDPSessionAdapter::UpdateConnVal(RecordVal* conn_val) - { - auto orig_endp = conn_val->GetField("orig"); - auto resp_endp = conn_val->GetField("resp"); - - UpdateEndpointVal(orig_endp, true); - UpdateEndpointVal(resp_endp, false); - - // Call children's UpdateConnVal - Analyzer::UpdateConnVal(conn_val); - } - -void UDPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) - { - bro_int_t size = is_orig ? request_len : reply_len; - auto endp = endp_arg->AsRecordVal(); - - if ( size < 0 ) - { - endp->Assign(0, val_mgr->Count(0)); - endp->Assign(1, UDP_INACTIVE); - } - - else - { - endp->Assign(0, static_cast(size)); - endp->Assign(1, UDP_ACTIVE); - } - } - -void UDPSessionAdapter::UpdateLength(bool is_orig, int len) - { - if ( is_orig ) - { - if ( request_len < 0 ) - request_len = len; - else - { - request_len += len; -#ifdef DEBUG - if ( request_len < 0 ) - reporter->Warning("wrapping around for UDP request length"); -#endif - } - } - else - { - if ( reply_len < 0 ) - reply_len = len; - else - { - reply_len += len; -#ifdef DEBUG - if ( reply_len < 0 ) - reporter->Warning("wrapping around for UDP reply length"); -#endif - } - } - } - -void UDPSessionAdapter::HandleBadChecksum(bool is_orig) - { - Weird("bad_UDP_checksum"); - - if ( is_orig ) - { - uint32_t t = req_chk_thresh; - - if ( Conn()->ScaledHistoryEntry('C', req_chk_cnt, req_chk_thresh) ) - ChecksumEvent(is_orig, t); - } - else - { - uint32_t t = rep_chk_thresh; - - if ( Conn()->ScaledHistoryEntry('c', rep_chk_cnt, rep_chk_thresh) ) - ChecksumEvent(is_orig, t); - } - } - -void UDPSessionAdapter::ChecksumEvent(bool is_orig, uint32_t threshold) - { - Conn()->HistoryThresholdEvent(udp_multiple_checksum_errors, is_orig, threshold); - } diff --git a/src/packet_analysis/protocol/udp/UDP.h b/src/packet_analysis/protocol/udp/UDP.h index f8d20e1c25..bec3b8b9ba 100644 --- a/src/packet_analysis/protocol/udp/UDP.h +++ b/src/packet_analysis/protocol/udp/UDP.h @@ -64,38 +64,4 @@ private: std::vector vxlan_ports; }; -class UDPSessionAdapter final : public IP::SessionAdapter { - -public: - - UDPSessionAdapter(Connection* conn) : - IP::SessionAdapter("UDP", conn) { } - - static zeek::analyzer::Analyzer* Instantiate(Connection* conn) - { - return new UDPSessionAdapter(conn); - } - - void AddExtraAnalyzers(Connection* conn) override; - void UpdateConnVal(RecordVal* conn_val) override; - - void UpdateLength(bool is_orig, int len); - void HandleBadChecksum(bool is_orig); - - // For tracking checksum history. These are connection-specific so they - // need to be stored in the session adapter created for each connection. - uint32_t req_chk_cnt = 0; - uint32_t req_chk_thresh = 1; - uint32_t rep_chk_cnt = 0; - uint32_t rep_chk_thresh = 1; - -private: - - void UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig); - void ChecksumEvent(bool is_orig, uint32_t threshold); - - bro_int_t request_len = -1; - bro_int_t reply_len = -1; -}; - } diff --git a/src/packet_analysis/protocol/udp/UDPSessionAdapter.cc b/src/packet_analysis/protocol/udp/UDPSessionAdapter.cc new file mode 100644 index 0000000000..cd2754612a --- /dev/null +++ b/src/packet_analysis/protocol/udp/UDPSessionAdapter.cc @@ -0,0 +1,109 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/packet_analysis/protocol/udp/UDPSessionAdapter.h" + +#include "zeek/analyzer/Manager.h" +#include "zeek/analyzer/protocol/conn-size/ConnSize.h" +#include "zeek/packet_analysis/protocol/udp/events.bif.h" + +using namespace zeek::packet_analysis::UDP; +using namespace zeek::packet_analysis::IP; + +enum UDP_EndpointState { + UDP_INACTIVE, // no packet seen + UDP_ACTIVE, // packets seen +}; + +void UDPSessionAdapter::AddExtraAnalyzers(Connection* conn) + { + static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); + + if ( analyzer_mgr->IsEnabled(analyzer_connsize) ) + // Add ConnSize analyzer. Needs to see packets, not stream. + AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); + } + +void UDPSessionAdapter::UpdateConnVal(RecordVal* conn_val) + { + auto orig_endp = conn_val->GetField("orig"); + auto resp_endp = conn_val->GetField("resp"); + + UpdateEndpointVal(orig_endp, true); + UpdateEndpointVal(resp_endp, false); + + // Call children's UpdateConnVal + Analyzer::UpdateConnVal(conn_val); + } + +void UDPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) + { + bro_int_t size = is_orig ? request_len : reply_len; + auto endp = endp_arg->AsRecordVal(); + + if ( size < 0 ) + { + endp->Assign(0, val_mgr->Count(0)); + endp->Assign(1, UDP_INACTIVE); + } + + else + { + endp->Assign(0, static_cast(size)); + endp->Assign(1, UDP_ACTIVE); + } + } + +void UDPSessionAdapter::UpdateLength(bool is_orig, int len) + { + if ( is_orig ) + { + if ( request_len < 0 ) + request_len = len; + else + { + request_len += len; +#ifdef DEBUG + if ( request_len < 0 ) + reporter->Warning("wrapping around for UDP request length"); +#endif + } + } + else + { + if ( reply_len < 0 ) + reply_len = len; + else + { + reply_len += len; +#ifdef DEBUG + if ( reply_len < 0 ) + reporter->Warning("wrapping around for UDP reply length"); +#endif + } + } + } + +void UDPSessionAdapter::HandleBadChecksum(bool is_orig) + { + Weird("bad_UDP_checksum"); + + if ( is_orig ) + { + uint32_t t = req_chk_thresh; + + if ( Conn()->ScaledHistoryEntry('C', req_chk_cnt, req_chk_thresh) ) + ChecksumEvent(is_orig, t); + } + else + { + uint32_t t = rep_chk_thresh; + + if ( Conn()->ScaledHistoryEntry('c', rep_chk_cnt, rep_chk_thresh) ) + ChecksumEvent(is_orig, t); + } + } + +void UDPSessionAdapter::ChecksumEvent(bool is_orig, uint32_t threshold) + { + Conn()->HistoryThresholdEvent(udp_multiple_checksum_errors, is_orig, threshold); + } diff --git a/src/packet_analysis/protocol/udp/UDPSessionAdapter.h b/src/packet_analysis/protocol/udp/UDPSessionAdapter.h new file mode 100644 index 0000000000..bd6e40c8b6 --- /dev/null +++ b/src/packet_analysis/protocol/udp/UDPSessionAdapter.h @@ -0,0 +1,43 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" + +namespace zeek::packet_analysis::UDP { + +class UDPSessionAdapter final : public IP::SessionAdapter { + +public: + + UDPSessionAdapter(Connection* conn) : + IP::SessionAdapter("UDP", conn) { } + + static zeek::analyzer::Analyzer* Instantiate(Connection* conn) + { + return new UDPSessionAdapter(conn); + } + + void AddExtraAnalyzers(Connection* conn) override; + void UpdateConnVal(RecordVal* conn_val) override; + + void UpdateLength(bool is_orig, int len); + void HandleBadChecksum(bool is_orig); + + // For tracking checksum history. These are connection-specific so they + // need to be stored in the session adapter created for each connection. + uint32_t req_chk_cnt = 0; + uint32_t req_chk_thresh = 1; + uint32_t rep_chk_cnt = 0; + uint32_t rep_chk_thresh = 1; + +private: + + void UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig); + void ChecksumEvent(bool is_orig, uint32_t threshold); + + bro_int_t request_len = -1; + bro_int_t reply_len = -1; +}; + +} // namespace zeek::packet_analysis::UDP