From: Bhagya Tholpady (bbantwal) Date: Thu, 28 May 2020 22:00:02 +0000 (+0000) Subject: Merge pull request #2210 in SNORT/snort3 from ~SELYSENK/snort3:trace_filtering to... X-Git-Tag: 3.0.1-5~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee91cfa82c1f56752ad108fe840e927cce2b1c64;p=thirdparty%2Fsnort3.git Merge pull request #2210 in SNORT/snort3 from ~SELYSENK/snort3:trace_filtering to master Squashed commit of the following: commit 543e3edb95a0aaa87afa695efeec80bd41e92c7a Author: Serhii Lysenko Date: Thu Apr 23 07:09:54 2020 -0400 trace: filter traces by packet constraints trace_print/trace_printf now take a pointer to the Packet. Packet's state is lazily evaluated against packet constraints. packet_tracer uses packet constraints from framework instead of implementing its own. --- diff --git a/src/detection/context_switcher.cc b/src/detection/context_switcher.cc index 58e3b5459..842719ffc 100644 --- a/src/detection/context_switcher.cc +++ b/src/detection/context_switcher.cc @@ -72,7 +72,7 @@ void ContextSwitcher::start() c->context_num = ++global_context_num; - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, "(wire) %" PRIu64 " cs::start %" PRIu64 " (i=%zu, b=%zu)\n", get_packet_number(), c->context_num, idle.size(), busy.size()); @@ -96,8 +96,8 @@ void ContextSwitcher::stop() assert(!c->has_callbacks()); assert(!c->dependencies()); - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, - "(wire) %" PRIu64 " cs::stop %" PRIu64 " (i=%zu, b=%zu)\n", + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "(wire) %" PRIu64 " cs::stop %" PRIu64 " (i=%zu, b=%zu)\n", get_packet_number(), c->context_num, idle.size(), busy.size()); c->clear(); @@ -112,8 +112,8 @@ void ContextSwitcher::stop() void ContextSwitcher::abort() { - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, - "(wire) %" PRIu64 " cs::abort (i=%zu, b=%zu)\n", + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "(wire) %" PRIu64 " cs::abort (i=%zu, b=%zu)\n", get_packet_number(), idle.size(), busy.size()); busy.clear(); @@ -125,12 +125,12 @@ void ContextSwitcher::abort() case IpsContext::IDLE: continue; case IpsContext::BUSY: - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, "%" PRIu64 " cs::abort busy", - c->packet_number); + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "%" PRIu64 " cs::abort busy", c->packet_number); break; case IpsContext::SUSPENDED: - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, "%" PRIu64 " cs::abort suspended", - c->packet_number); + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "%" PRIu64 " cs::abort suspended", c->packet_number); break; } @@ -155,8 +155,8 @@ IpsContext* ContextSwitcher::interrupt() assert(c->state == IpsContext::IDLE); c->context_num = ++global_context_num; - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, - "%" PRIu64 " cs::interrupt %" PRIu64 " (i=%zu, b=%zu)\n", + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "%" PRIu64 " cs::interrupt %" PRIu64 " (i=%zu, b=%zu)\n", busy.empty() ? get_packet_number() : busy.back()->packet_number, busy.empty() ? 0 : busy.back()->context_num, idle.size(), busy.size()); @@ -178,8 +178,8 @@ IpsContext* ContextSwitcher::complete() assert(!c->dependencies()); assert(!c->has_callbacks()); - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, - "%" PRIu64 " cs::complete %" PRIu64 " (i=%zu, b=%zu)\n", + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "%" PRIu64 " cs::complete %" PRIu64 " (i=%zu, b=%zu)\n", c->packet_number, c->context_num, idle.size(), busy.size()); busy.pop_back(); @@ -200,7 +200,7 @@ void ContextSwitcher::suspend() IpsContext* c = busy.back(); assert(c->state == IpsContext::BUSY); - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, "%" PRIu64 " cs::suspend %" PRIu64 " (i=%zu, b=%zu, wh=%zu)\n", c->packet_number, c->context_num, idle.size(), busy.size(), contexts.size() - idle.size() - busy.size()); @@ -218,8 +218,8 @@ void ContextSwitcher::resume(IpsContext* c) { assert(c->state == IpsContext::SUSPENDED); - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, - "%" PRIu64 " cs::resume %" PRIu64 " (i=%zu)\n", + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "%" PRIu64 " cs::resume %" PRIu64 " (i=%zu)\n", c->packet_number, c->context_num, idle.size()); IpsContextChain& chain = c->packet->flow ? c->packet->flow->context_chain : non_flow_chain; diff --git a/src/detection/detect_trace.cc b/src/detection/detect_trace.cc index e12c8ee7e..6ccca1691 100644 --- a/src/detection/detect_trace.cc +++ b/src/detection/detect_trace.cc @@ -78,16 +78,17 @@ void print_pkt_info(Packet* p, const char* task) dst_port = p->ptrs.dp; } - debug_logf(detection_trace, TRACE_RULE_EVAL,"packet %" PRIu64 " %s %s:%u %s:%u (%s)\n", - p->context->packet_number, dir, src_addr, src_port, dst_addr, dst_port, task); + debug_logf(detection_trace, TRACE_RULE_EVAL, p, + "packet %" PRIu64 " %s %s:%u %s:%u (%s)\n", p->context->packet_number, + dir, src_addr, src_port, dst_addr, dst_port, task); } -void print_pattern(const PatternMatchData* pmd) +void print_pattern(const PatternMatchData* pmd, Packet* p) { string hex, txt, opts; get_pattern_info(pmd, pmd->pattern_buf, pmd->pattern_size, hex, txt, opts); - debug_logf(detection_trace, TRACE_RULE_EVAL, + debug_logf(detection_trace, TRACE_RULE_EVAL, p, "Fast pattern %s[%u] = '%s' |%s| %s\n", pm_type_strings[pmd->pm_type], pmd->pattern_size, txt.c_str(), hex.c_str(), opts.c_str()); @@ -100,7 +101,8 @@ void dump_buffer(const uint8_t* buff, unsigned len, Packet* p) if (len == 0) { - debug_log(detection_trace, TRACE_BUFFER, "Buffer dump - empty buffer\n"); + debug_log(detection_trace, TRACE_BUFFER, p, + "Buffer dump - empty buffer\n"); return; } @@ -114,13 +116,13 @@ void node_eval_trace(const detection_option_tree_node_t* node, const Cursor& cur if (node->option_type != RULE_OPTION_TYPE_LEAF_NODE ) { - debug_logf(detection_trace, TRACE_RULE_EVAL, + debug_logf(detection_trace, TRACE_RULE_EVAL, p, "Evaluating option %s, cursor name %s, cursor position %u\n", ((IpsOption*)node->option_data)->get_name(), name, pos); } else { - debug_logf(detection_trace, TRACE_RULE_EVAL, + debug_logf(detection_trace, TRACE_RULE_EVAL, p, "Reached leaf, cursor name %s, cursor position %u\n", name, pos); } @@ -148,7 +150,7 @@ void print_pkt_info(Packet*, const char*) { } -void print_pattern(const PatternMatchData*) +void print_pattern(const PatternMatchData*, Packet*) { } diff --git a/src/detection/detect_trace.h b/src/detection/detect_trace.h index 1f3527d76..e8afe5547 100644 --- a/src/detection/detect_trace.h +++ b/src/detection/detect_trace.h @@ -52,7 +52,7 @@ enum void clear_trace_cursor_info(); void print_pkt_info(snort::Packet* p, const char*); -void print_pattern(const PatternMatchData* pmd); +void print_pattern(const PatternMatchData* pmd, snort::Packet*); void dump_buffer(const uint8_t* buff, unsigned len, snort::Packet*); void node_eval_trace(const detection_option_tree_node_t* node, const Cursor& cursor, snort::Packet*); diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index ce388726e..14bb09920 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -326,8 +326,8 @@ void DetectionEngine::clear_replacement() void DetectionEngine::disable_all(Packet* p) { p->context->active_rules = IpsContext::NONE; - debug_logf(detection_trace, TRACE_PKT_DETECTION, "Disabled all detect, packet %" PRIu64"\n", - p->context->packet_number); + debug_logf(detection_trace, TRACE_PKT_DETECTION, p, + "Disabled all detect, packet %" PRIu64"\n", p->context->packet_number); } bool DetectionEngine::all_disabled(Packet* p) @@ -338,7 +338,7 @@ void DetectionEngine::disable_content(Packet* p) if ( p->context->active_rules == IpsContext::CONTENT ) p->context->active_rules = IpsContext::NON_CONTENT; - debug_logf(detection_trace, TRACE_PKT_DETECTION, + debug_logf(detection_trace, TRACE_PKT_DETECTION, p, "Disabled content detect, packet %" PRIu64"\n", p->context->packet_number); } @@ -371,7 +371,7 @@ bool DetectionEngine::do_offload(Packet* p) assert(p == p->context->packet); assert(p->context == sw->get_context()); - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, p, "%" PRIu64 " de::offload %" PRIu64 " (r=%d)\n", p->context->packet_number, p->context->context_num, offloader->count()); @@ -423,13 +423,14 @@ void DetectionEngine::idle() { while ( offloader->count() ) { - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, "(wire) %" PRIu64 " de::sleep\n", - get_packet_number()); + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "(wire) %" PRIu64 " de::sleep\n", get_packet_number()); onload(); } - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, "(wire) %" PRIu64 " de::idle (r=%d)\n", - get_packet_number(), offloader->count()); + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "(wire) %" PRIu64 " de::idle (r=%d)\n", get_packet_number(), + offloader->count()); offloader->stop(); } @@ -442,8 +443,8 @@ void DetectionEngine::onload(Flow* flow) while ( flow->is_suspended() ) { - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, - "(wire) %" PRIu64 " de::sleep\n", get_packet_number()); + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, nullptr, + "(wire) %" PRIu64 " de::sleep\n", get_packet_number()); resume_ready_suspends(flow->context_chain); // FIXIT-M makes onload reentrant-safe onload(); @@ -458,7 +459,7 @@ void DetectionEngine::onload() while (offloader->count() and offloader->get(p)) { - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, p, "%" PRIu64 " de::onload %" PRIu64 " (r=%d)\n", p->context->packet_number, p->context->context_num, offloader->count()); @@ -485,7 +486,7 @@ void DetectionEngine::resume_ready_suspends(const IpsContextChain& chain) void DetectionEngine::complete(Packet* p) { - debug_logf(detection_trace, TRACE_DETECTION_ENGINE, + debug_logf(detection_trace, TRACE_DETECTION_ENGINE, p, "%" PRIu64 " de::resume %" PRIu64 " (r=%d)\n", p->context->packet_number, p->context->context_num, offloader->count()); diff --git a/src/detection/detection_options.cc b/src/detection/detection_options.cc index 3a04febb6..4d76db919 100644 --- a/src/detection/detection_options.cc +++ b/src/detection/detection_options.cc @@ -315,7 +315,7 @@ void print_option_tree(detection_option_tree_node_t* node, int level) opt = buf; } - debug_logf(detection_trace, TRACE_OPTION_TREE, "%3d %3d %p %*s\n", + debug_logf(detection_trace, TRACE_OPTION_TREE, nullptr, "%3d %3d %p %*s\n", level, node->num_children, node->option_data, (int)(level + strlen(opt)), opt); for ( int i=0; inum_children; i++ ) @@ -383,7 +383,7 @@ int detection_option_node_evaluate( !(p->packet_flags & PKT_IP_RULE_2ND) && !p->is_udp_tunneled() ) { - debug_log(detection_trace, TRACE_RULE_EVAL, + debug_log(detection_trace, TRACE_RULE_EVAL, p, "Was evaluated before, returning last check result\n"); return last_check.result; } @@ -435,7 +435,7 @@ int detection_option_node_evaluate( if ( !sig_info.services.empty() and check_ports ) { - debug_logf(detection_trace, TRACE_RULE_EVAL, + debug_logf(detection_trace, TRACE_RULE_EVAL, p, "SID %u not matched because of service mismatch %d\n", sig_info.sid, snort_protocol_id); break; // out of case @@ -456,7 +456,7 @@ int detection_option_node_evaluate( if ( otn->detection_filter ) { - debug_log(detection_trace, TRACE_RULE_EVAL, + debug_log(detection_trace, TRACE_RULE_EVAL, p, "Evaluating detection filter\n"); f_result = !detection_filter_test(otn->detection_filter, p->ptrs.ip_api.get_src(), p->ptrs.ip_api.get_dst(), @@ -471,7 +471,7 @@ int detection_option_node_evaluate( { #ifdef DEBUG_MSGS const SigInfo& si = otn->sigInfo; - debug_logf(detection_trace, TRACE_RULE_EVAL, + debug_logf(detection_trace, TRACE_RULE_EVAL, p, "Matched rule gid:sid:rev %u:%u:%u\n", si.gid, si.sid, si.rev); #endif fpAddMatch(p->context->otnx, otn); @@ -481,7 +481,8 @@ int detection_option_node_evaluate( } #ifdef DEBUG_MSGS else - debug_log(detection_trace, TRACE_RULE_EVAL, "Header check failed\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, p, + "Header check failed\n"); #endif break; @@ -533,13 +534,13 @@ int detection_option_node_evaluate( if ( rval == (int)IpsOption::NO_MATCH ) { - debug_log(detection_trace, TRACE_RULE_EVAL, "no match\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, p, "no match\n"); state.last_check.result = result; return result; } else if ( rval == (int)IpsOption::FAILED_BIT ) { - debug_log(detection_trace, TRACE_RULE_EVAL, "failed bit\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, p, "failed bit\n"); eval_data.flowbit_failed = 1; // clear the timestamp so failed flowbit gets eval'd again state.last_check.flowbit_failed = 1; @@ -552,7 +553,7 @@ int detection_option_node_evaluate( // so nodes below this don't alert. tmp_noalert_flag = eval_data.flowbit_noalert; eval_data.flowbit_noalert = 1; - debug_log(detection_trace, TRACE_RULE_EVAL, "flowbit no alert\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, p, "flowbit no alert\n"); } // Back up byte_extract vars so they don't get overwritten between rules @@ -571,7 +572,7 @@ int detection_option_node_evaluate( safe_snprintf(var_buf, sizeof(var_buf), "var[%d]=%d ", i, tmp_byte_extract_vars[i]); rule_vars.append(var_buf); } - debug_logf(detection_trace, TRACE_RULE_VARS, "Rule options variables: %s\n", + debug_logf(detection_trace, TRACE_RULE_VARS, p, "Rule options variables: %s\n", rule_vars.c_str()); } #endif diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 2fa764732..634047b19 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -331,7 +331,7 @@ static int detection_option_tree_evaluate(detection_option_tree_root_t* root, Cursor c(eval_data.p); int rval = 0; - debug_log(detection_trace, TRACE_RULE_EVAL, "Starting tree eval\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, nullptr, "Starting tree eval\n"); for ( int i = 0; i < root->num_children; ++i ) { @@ -357,7 +357,7 @@ static int rule_tree_match( eval_data.flowbit_failed = 0; eval_data.flowbit_noalert = 0; - print_pattern(pmx->pmd); + print_pattern(pmx->pmd, eval_data.p); { /* NOTE: The otn will be the first one in the match state. If there are @@ -792,6 +792,7 @@ bool MpseStash::process(MpseMatch match, void* context) #ifdef DEBUG_MSGS if (count == 0) debug_log(detection_trace, TRACE_RULE_EVAL, + static_cast(context)->packet, "Fast pattern processing - no matches found\n"); #endif unsigned i = 0; @@ -800,7 +801,9 @@ bool MpseStash::process(MpseMatch match, void* context) Node& node = it; i++; // process a pattern - case is handled by otn processing - debug_logf(detection_trace, TRACE_RULE_EVAL,"Processing pattern match #%d\n", i); + debug_logf(detection_trace, TRACE_RULE_EVAL, + static_cast(context)->packet, + "Processing pattern match #%d\n", i); int res = match(node.user, node.tree, node.index, context, node.list); if ( res > 0 ) @@ -880,8 +883,9 @@ static inline int search_buffer( // Depending on where we are searching we call the appropriate mpse if ( MpseGroup* so = pg->mpsegrp[pmt] ) { - debug_logf(detection_trace, TRACE_FP_SEARCH, "%" PRIu64 " fp %s.%s[%d]\n", - p->context->packet_number, gadget->get_name(), pm_type_strings[pmt], buf.len); + debug_logf(detection_trace, TRACE_FP_SEARCH, p, + "%" PRIu64 " fp %s.%s[%d]\n", p->context->packet_number, + gadget->get_name(), pm_type_strings[pmt], buf.len); batch_search(so, p, buf.data, buf.len, cnt); } @@ -894,7 +898,7 @@ static int fp_search(PortGroup* port_group, Packet* p) Inspector* gadget = p->flow ? p->flow->gadget : nullptr; InspectionBuffer buf; - debug_log(detection_trace, TRACE_RULE_EVAL, "Fast pattern search\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, p, "Fast pattern search\n"); if ( p->data and p->dsize ) { @@ -903,8 +907,9 @@ static int fp_search(PortGroup* port_group, Packet* p) { if ( uint16_t pattern_match_size = p->get_detect_limit() ) { - debug_logf(detection_trace, TRACE_FP_SEARCH, "%" PRIu64 " fp %s[%u]\n", - p->context->packet_number, pm_type_strings[PM_TYPE_PKT], pattern_match_size); + debug_logf(detection_trace, TRACE_FP_SEARCH, p, + "%" PRIu64 " fp %s[%u]\n", p->context->packet_number, + pm_type_strings[PM_TYPE_PKT], pattern_match_size); batch_search(so, p, p->data, pattern_match_size, pc.pkt_searches); p->is_cooked() ? pc.cooked_searches++ : pc.raw_searches++; @@ -941,8 +946,9 @@ static int fp_search(PortGroup* port_group, Packet* p) if ( file_data.len ) { - debug_logf(detection_trace, TRACE_FP_SEARCH, "%" PRIu64 " fp search %s[%d]\n", - p->context->packet_number, pm_type_strings[PM_TYPE_FILE], file_data.len); + debug_logf(detection_trace, TRACE_FP_SEARCH, p, + "%" PRIu64 " fp search %s[%d]\n", p->context->packet_number, + pm_type_strings[PM_TYPE_FILE], file_data.len); batch_search(so, p, file_data.data, file_data.len, pc.file_searches); } @@ -1031,7 +1037,8 @@ static inline void eval_nfp( int rval = 0; { - debug_log(detection_trace, TRACE_RULE_EVAL, "Testing non-content rules\n"); + debug_log(detection_trace, TRACE_RULE_EVAL, p, + "Testing non-content rules\n"); rval = detection_option_tree_evaluate( (detection_option_tree_root_t*)port_group->nfp_tree, eval_data); } diff --git a/src/detection/tag.cc b/src/detection/tag.cc index 46a6ef9ac..b7c2c213a 100644 --- a/src/detection/tag.cc +++ b/src/detection/tag.cc @@ -330,7 +330,7 @@ static void AddTagNode(Packet* p, TagData* tag, int mode, uint32_t now, TagNode* returned; XHash* tag_cache_ptr = nullptr; - debug_log(detection_trace, TRACE_TAG, "Adding new Tag Head\n"); + debug_log(detection_trace, TRACE_TAG, nullptr, "Adding new Tag Head\n"); if ( tag->tag_metric & TAG_METRIC_SESSION ) { diff --git a/src/flow/flow.cc b/src/flow/flow.cc index 597bd3849..fd7cd595a 100644 --- a/src/flow/flow.cc +++ b/src/flow/flow.cc @@ -136,6 +136,7 @@ inline void Flow::clean() delete bitop; bitop = nullptr; } + filtering_state.clear(); } void Flow::reset(bool do_cleanup) diff --git a/src/flow/flow.h b/src/flow/flow.h index feafe1261..b0a7c11ee 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -109,6 +109,29 @@ struct Packet; typedef void (* StreamAppDataFree)(void*); +struct FilteringState +{ + uint8_t generation_id = 0; + bool matched = false; + + void clear() + { + generation_id = 0; + matched = false; + } + + bool was_checked(uint8_t id) const + { + return generation_id and (generation_id == id); + } + + void set_matched(uint8_t id, bool match) + { + generation_id = id; + matched = match; + } +}; + struct FlowStats { uint64_t client_pkts; @@ -431,6 +454,8 @@ public: // FIXIT-M privatize if possible FlowState flow_state; + FilteringState filtering_state; + private: void clean(); }; diff --git a/src/flow/flow_control.cc b/src/flow/flow_control.cc index 7d069a882..d32204d17 100644 --- a/src/flow/flow_control.cc +++ b/src/flow/flow_control.cc @@ -412,6 +412,7 @@ unsigned FlowControl::process(Flow* flow, Packet* p) set_inspection_policy(sc, flow->inspection_policy_id); set_ips_policy(sc, flow->ips_policy_id); set_network_policy(sc, flow->network_policy_id); + p->filtering_state = flow->filtering_state; } else diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index ba0274db9..f65de45c6 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -17,6 +17,7 @@ set (FRAMEWORK_INCLUDES module.h mpse.h mpse_batch.h + packet_constraints.h parameter.h range.h so_rule.h @@ -31,6 +32,7 @@ add_library ( framework OBJECT data_bus.cc inspector.cc ips_option.cc + packet_constraints.cc parameter.cc module.cc mpse.cc @@ -70,3 +72,4 @@ add_catch_test( range_test SOURCES range.cc ) + diff --git a/src/framework/dev_notes.txt b/src/framework/dev_notes.txt index c13906b55..7fd55e68c 100644 --- a/src/framework/dev_notes.txt +++ b/src/framework/dev_notes.txt @@ -10,3 +10,6 @@ attached to configuration with one element per packet thread, however those cases are rare and should only be needed by the framework code, not the plugins. +PacketConstraints allow you to match packets and flows against a 5-tuple. +( ip_proto; src_ip; dst_ip; src_port; dst_port) + diff --git a/src/framework/packet_constraints.cc b/src/framework/packet_constraints.cc new file mode 100644 index 000000000..757f60ed7 --- /dev/null +++ b/src/framework/packet_constraints.cc @@ -0,0 +1,174 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// packet_constraints.cc author Serhii Lysenko + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "packet_constraints.h" + +#include "protocols/packet.h" + +#include + +namespace { + +inline bool match(const snort::PacketConstraints& cs, const snort::SfIp& sip, + const snort::SfIp& dip, uint16_t sport, uint16_t dport) +{ + using SetBits = snort::PacketConstraints::SetBits; + + return (!(cs.set_bits & SetBits::SRC_PORT) or (sport == cs.src_port)) and + (!(cs.set_bits & SetBits::DST_PORT) or (dport == cs.dst_port)) and + (!(cs.set_bits & SetBits::SRC_IP) or (sip == cs.src_ip)) and + (!(cs.set_bits & SetBits::DST_IP) or (dip == cs.dst_ip)); +} + +} // namespace + +using namespace snort; + +bool PacketConstraints::operator==(const PacketConstraints& other) const +{ + return set_bits == other.set_bits + and ip_proto == other.ip_proto + and src_port == other.src_port + and dst_port == other.dst_port + and src_ip == other.src_ip + and dst_ip == other.dst_ip; +} + +bool PacketConstraints::packet_match(const Packet& p) const +{ + if ( !p.has_ip() ) + return false; + + if ( (set_bits & SetBits::IP_PROTO) and (p.get_ip_proto_next() != ip_proto) ) + return false; + + const auto& sip = *p.ptrs.ip_api.get_src(); + const auto& dip = *p.ptrs.ip_api.get_dst(); + const auto sp = p.ptrs.sp; + const auto dp = p.ptrs.dp; + + return match(*this, sip, dip, sp, dp) or match(*this, dip, sip, dp, sp); +} + +bool PacketConstraints::flow_match(const Flow& f) const +{ + if ( (set_bits & SetBits::IP_PROTO) and + (IpProtocol(f.ip_proto) != ip_proto) ) + return false; + + return match(*this, f.client_ip, f.server_ip, f.client_port, f.server_port); +} + +#ifdef UNIT_TEST + +#include + +TEST_CASE("Packet constraints matching", "[framework]") +{ + PacketConstraints cs; + + const auto proto = IpProtocol::TCP; + const uint16_t sport = 100; + const uint16_t dport = 200; + snort::SfIp sip, dip; + sip.set("10.1.1.1"); + dip.set("10.1.1.2"); + + + SECTION("full match") + { + cs.set_bits = PacketConstraints::SetBits::IP_PROTO; + cs.set_bits |= PacketConstraints::SetBits::SRC_PORT; + cs.set_bits |= PacketConstraints::SetBits::DST_PORT; + cs.set_bits |= PacketConstraints::SetBits::SRC_IP; + cs.set_bits |= PacketConstraints::SetBits::DST_IP; + + cs.ip_proto = proto; + cs.src_port = sport; + cs.dst_port = dport; + cs.src_ip = sip; + cs.dst_ip = dip; + + CHECK( match(cs, sip, dip, sport, dport) ); + } + + SECTION("backwards") + { + cs.set_bits = PacketConstraints::SetBits::IP_PROTO; + cs.set_bits |= PacketConstraints::SetBits::SRC_PORT; + cs.set_bits |= PacketConstraints::SetBits::DST_PORT; + cs.set_bits |= PacketConstraints::SetBits::SRC_IP; + cs.set_bits |= PacketConstraints::SetBits::DST_IP; + + cs.ip_proto = proto; + cs.src_port = sport; + cs.dst_port = dport; + cs.src_ip = sip; + cs.dst_ip = dip; + + CHECK( !match(cs, dip, sip, dport, sport) ); + } + + SECTION("any ip") + { + cs.set_bits = PacketConstraints::SetBits::IP_PROTO; + cs.set_bits |= PacketConstraints::SetBits::SRC_PORT; + cs.set_bits |= PacketConstraints::SetBits::DST_PORT; + + cs.ip_proto = proto; + cs.src_port = sport; + cs.dst_port = dport; + + CHECK( match(cs, sip, dip, sport, dport) ); + } + + SECTION("any port") + { + cs.set_bits = PacketConstraints::SetBits::IP_PROTO; + cs.set_bits |= PacketConstraints::SetBits::SRC_IP; + cs.set_bits |= PacketConstraints::SetBits::DST_IP; + + cs.ip_proto = proto; + cs.src_ip = sip; + cs.dst_ip = dip; + + CHECK( match(cs, sip, dip, sport, dport) ); + } + + SECTION("any src") + { + cs.set_bits = PacketConstraints::SetBits::IP_PROTO; + cs.set_bits |= PacketConstraints::SetBits::DST_PORT; + cs.set_bits |= PacketConstraints::SetBits::DST_IP; + + cs.ip_proto = proto; + cs.dst_port = dport; + cs.dst_ip = dip; + + CHECK( match(cs, sip, dip, sport, dport) ); + } + +} + +#endif + diff --git a/src/framework/packet_constraints.h b/src/framework/packet_constraints.h new file mode 100644 index 000000000..e25073b13 --- /dev/null +++ b/src/framework/packet_constraints.h @@ -0,0 +1,59 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// packet_constraints.h author Serhii Lysenko + +#ifndef PACKET_CONSTRAINTS_H +#define PACKET_CONSTRAINTS_H + +#include "protocols/protocol_ids.h" +#include "sfip/sf_ip.h" + +namespace snort +{ + +class Flow; +struct Packet; + +struct PacketConstraints +{ + enum SetBits : uint8_t { + IP_PROTO = 1, + SRC_IP = 1 << 1, + DST_IP = 1 << 2, + SRC_PORT = 1 << 3, + DST_PORT = 1 << 4, + }; + + bool operator==(const PacketConstraints& other) const; + + bool packet_match(const Packet& p) const; + bool flow_match(const Flow& f) const; + + IpProtocol ip_proto = IpProtocol::PROTO_NOT_SET; + uint16_t src_port = 0; + uint16_t dst_port = 0; + snort::SfIp src_ip; + snort::SfIp dst_ip; + + uint8_t set_bits = 0; +}; + +} // namespace snort + +#endif + diff --git a/src/latency/packet_latency.cc b/src/latency/packet_latency.cc index 4c5e66170..4cc62f0d0 100644 --- a/src/latency/packet_latency.cc +++ b/src/latency/packet_latency.cc @@ -208,7 +208,7 @@ static struct SnortEventHandler : public EventHandler assert(e.packet); std::ostringstream ss; ss << e; - debug_logf(latency_trace, "%s\n", ss.str().c_str()); + debug_logf(latency_trace, e.packet, "%s\n", ss.str().c_str()); DetectionEngine::queue_event(GID_LATENCY, LATENCY_EVENT_PACKET_FASTPATHED); } diff --git a/src/latency/rule_latency.cc b/src/latency/rule_latency.cc index c38e5dfa8..a14eca1d3 100644 --- a/src/latency/rule_latency.cc +++ b/src/latency/rule_latency.cc @@ -296,9 +296,11 @@ static struct SnortEventHandler : public EventHandler { void handle(const Event& e) override { + assert(e.packet); + std::ostringstream ss; ss << e; - debug_logf(latency_trace, "%s\n", ss.str().c_str()); + debug_logf(latency_trace, e.packet, "%s\n", ss.str().c_str()); switch ( e.type ) { diff --git a/src/main.cc b/src/main.cc index 9f3853e76..f79879915 100644 --- a/src/main.cc +++ b/src/main.cc @@ -214,7 +214,7 @@ bool Pig::queue_command(AnalyzerCommand* ac, bool orphan) #ifdef DEBUG_MSGS unsigned ac_ref_count = ac->get(); - debug_logf(snort_trace, "[%u] Queuing command %s for execution (refcount %u)\n", + debug_logf(snort_trace, nullptr, "[%u] Queuing command %s for execution (refcount %u)\n", idx, ac->stringify(), ac_ref_count); #else ac->get(); @@ -228,13 +228,13 @@ void Pig::reap_command(AnalyzerCommand* ac) unsigned ac_ref_count = ac->put(); if (ac_ref_count == 0) { - debug_logf(snort_trace, "[%u] Destroying completed command %s\n", + debug_logf(snort_trace, nullptr, "[%u] Destroying completed command %s\n", idx, ac->stringify()); delete ac; } #ifdef DEBUG_MSGS else - debug_logf(snort_trace, "[%u] Reaped ongoing command %s (refcount %u)\n", + debug_logf(snort_trace, nullptr, "[%u] Reaped ongoing command %s (refcount %u)\n", idx, ac->stringify(), ac_ref_count); #endif } @@ -296,7 +296,7 @@ void snort::main_broadcast_command(AnalyzerCommand* ac, bool from_shell) unsigned dispatched = 0; ac = get_command(ac, from_shell); - debug_logf(snort_trace, "Broadcasting %s command\n", ac->stringify()); + debug_logf(snort_trace, nullptr, "Broadcasting %s command\n", ac->stringify()); for (unsigned idx = 0; idx < max_pigs; ++idx) { @@ -374,7 +374,7 @@ int main_reload_config(lua_State* L) PluginManager::reload_so_plugins_cleanup(sc); SnortConfig::set_conf(sc); - TraceApi::thread_reinit(sc); + TraceApi::thread_reinit(sc->trace_config); proc_stats.conf_reloads++; bool from_shell = ( L != nullptr ); @@ -702,7 +702,7 @@ static void reap_commands() { AnalyzerCommand* ac = orphan_commands.front(); orphan_commands.pop(); - debug_logf(snort_trace, "Destroying orphan command %s\n", ac->stringify()); + debug_logf(snort_trace, nullptr, "Destroying orphan command %s\n", ac->stringify()); delete ac; } } diff --git a/src/main/analyzer.cc b/src/main/analyzer.cc index e381102de..fa6be4d21 100644 --- a/src/main/analyzer.cc +++ b/src/main/analyzer.cc @@ -596,7 +596,7 @@ void Analyzer::init_unprivileged() // This should be called as soon as possible // to handle all trace log messages - TraceApi::thread_init(sc); + TraceApi::thread_init(sc->trace_config); CodecManager::thread_init(sc); @@ -630,7 +630,7 @@ void Analyzer::reinit(const SnortConfig* sc) { InspectorManager::thread_reinit(sc); ActionManager::thread_reinit(sc); - TraceApi::thread_reinit(sc); + TraceApi::thread_reinit(sc->trace_config); } void Analyzer::term() diff --git a/src/main/snort.cc b/src/main/snort.cc index 0349a8d5b..881f79212 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -155,7 +155,7 @@ void Snort::init(int argc, char** argv) // This call must be immediately after "SnortConfig::set_conf(sc)" // since the first trace call may happen somewhere after this point - TraceApi::thread_init(sc); + TraceApi::thread_init(sc->trace_config); PluginManager::load_so_plugins(sc); diff --git a/src/main/snort_debug.cc b/src/main/snort_debug.cc index 3327e59cd..47ff7cf27 100644 --- a/src/main/snort_debug.cc +++ b/src/main/snort_debug.cc @@ -163,7 +163,7 @@ TEST_CASE("debug_log, debug_logf", "[trace]") test_trace.set("all", 0); testing_dump[0] = '\0'; - debug_log(&test_trace, "my message"); + debug_log(&test_trace, nullptr, "my message"); CHECK( testing_dump[0] == '\0' ); test_trace.set("all", 1); @@ -179,67 +179,67 @@ TEST_CASE("debug_log, debug_logf", "[trace]") message[STD_BUF_SIZE] = '\0'; testing_dump[0] = '\0'; - debug_log(&test_trace, message); + debug_log(&test_trace, nullptr, message); CHECK( (strlen(testing_dump) == STD_BUF_SIZE - 1) ); testing_dump[0] = '\0'; - debug_log(3, &test_opt_trace, TEST_TRACE_OPTION3, message); + debug_log(3, &test_opt_trace, TEST_TRACE_OPTION3, nullptr, message); CHECK( (strlen(testing_dump) == STD_BUF_SIZE - 1) ); testing_dump[0] = '\0'; - debug_log(6, &test_opt_trace, TEST_TRACE_OPTION3, message); + debug_log(6, &test_opt_trace, TEST_TRACE_OPTION3, nullptr, message); CHECK( (strlen(testing_dump) == 0) ); testing_dump[0] = '\0'; - debug_log(&test_trace, "my message"); + debug_log(&test_trace, nullptr, "my message"); CHECK( !strcmp(testing_dump, "test_module:all:1: my message") ); testing_dump[0] = '\0'; - debug_logf(&test_trace, "%s %s", "my", "message"); + debug_logf(&test_trace, nullptr, "%s %s", "my", "message"); CHECK( !strcmp(testing_dump, "test_module:all:1: my message") ); testing_dump[0] = '\0'; - debug_log(&test_opt_trace, TEST_TRACE_OPTION1, "log option1 message"); + debug_log(&test_opt_trace, TEST_TRACE_OPTION1, nullptr, "log option1 message"); CHECK( !strcmp(testing_dump, "test_opt_module:option1:1: log option1 message") ); testing_dump[0] = '\0'; - debug_logf(&test_opt_trace, TEST_TRACE_OPTION1, "%s %s %s", "log", "option1", "message"); + debug_logf(&test_opt_trace, TEST_TRACE_OPTION1, nullptr, "%s %s %s", "log", "option1", "message"); CHECK( !strcmp(testing_dump, "test_opt_module:option1:1: log option1 message") ); testing_dump[0] = '\0'; - debug_log(3, &test_opt_trace, TEST_TRACE_OPTION2, "log option2 message"); + debug_log(3, &test_opt_trace, TEST_TRACE_OPTION2, nullptr, "log option2 message"); CHECK( testing_dump[0] == '\0' ); testing_dump[0] = '\0'; - debug_log(&test_opt_trace, TEST_TRACE_OPTION2, "log option2 message"); + debug_log(&test_opt_trace, TEST_TRACE_OPTION2, nullptr, "log option2 message"); CHECK( !strcmp(testing_dump, "test_opt_module:option2:1: log option2 message") ); testing_dump[0] = '\0'; - debug_logf(&test_opt_trace, TEST_TRACE_OPTION2, "%s %s %s", "log", "option2", "message"); + debug_logf(&test_opt_trace, TEST_TRACE_OPTION2, nullptr, "%s %s %s", "log", "option2", "message"); CHECK( !strcmp(testing_dump, "test_opt_module:option2:1: log option2 message") ); testing_dump[0] = '\0'; - debug_log(6, &test_opt_trace, TEST_TRACE_OPTION3, "log option3 message"); + debug_log(6, &test_opt_trace, TEST_TRACE_OPTION3, nullptr, "log option3 message"); CHECK( testing_dump[0] == '\0' ); testing_dump[0] = '\0'; - debug_log(3, &test_opt_trace, TEST_TRACE_OPTION3, "log option3 message"); + debug_log(3, &test_opt_trace, TEST_TRACE_OPTION3, nullptr, "log option3 message"); CHECK( !strcmp(testing_dump, "test_opt_module:option3:3: log option3 message") ); testing_dump[0] = '\0'; - debug_logf(3, &test_opt_trace, TEST_TRACE_OPTION3, "%s %s %s", "log", "option3", "message"); + debug_logf(3, &test_opt_trace, TEST_TRACE_OPTION3, nullptr, "%s %s %s", "log", "option3", "message"); CHECK( !strcmp(testing_dump, "test_opt_module:option3:3: log option3 message") ); - + testing_dump[0] = '\0'; - debug_log(2, &test_opt_trace, TEST_TRACE_OPTION4, "log option4 message"); + debug_log(2, &test_opt_trace, TEST_TRACE_OPTION4, nullptr, "log option4 message"); CHECK( !strcmp(testing_dump, "test_opt_module:option4:2: log option4 message") ); testing_dump[0] = '\0'; - debug_logf(2, &test_opt_trace, TEST_TRACE_OPTION4, "%s %s %s", "log", "option4", "message"); + debug_logf(2, &test_opt_trace, TEST_TRACE_OPTION4, nullptr, "%s %s %s", "log", "option4", "message"); CHECK( !strcmp(testing_dump, "test_opt_module:option4:2: log option4 message") ); testing_dump[0] = '\0'; - debug_log(4, &test_opt_trace, TEST_TRACE_OPTION5, "log option5 message"); + debug_log(4, &test_opt_trace, TEST_TRACE_OPTION5, nullptr, "log option5 message"); CHECK( testing_dump[0] == '\0' ); } diff --git a/src/main/snort_debug.h b/src/main/snort_debug.h index af7457731..d228da602 100644 --- a/src/main/snort_debug.h +++ b/src/main/snort_debug.h @@ -27,12 +27,26 @@ #include +#include "protocols/packet.h" #include "trace/trace.h" +#include "trace/trace_api.h" static inline bool trace_enabled(const snort::Trace* trace, - TraceOptionID trace_option_id, TraceLevel log_level = DEFAULT_TRACE_LOG_LEVEL) + TraceOptionID trace_option_id, + TraceLevel log_level = DEFAULT_TRACE_LOG_LEVEL, + const snort::Packet* p = nullptr) { - return trace && trace->enabled(trace_option_id, log_level); + if ( !trace or !trace->enabled(trace_option_id, log_level) ) + return false; + + if ( !p ) + return true; + + const auto gid = snort::TraceApi::get_constraints_generation(); + if ( !p->filtering_state.was_checked(gid) ) + snort::TraceApi::filter(*p); + + return p->filtering_state.matched; } namespace snort @@ -44,109 +58,124 @@ SO_PUBLIC void trace_vprintf(const char* name, TraceLevel log_level, using trace_func = void(const char*, TraceLevel, const char*, const char*, va_list); template -static inline void trace_printf(TraceLevel log_level, const snort::Trace* trace, - TraceOptionID trace_option_id, const char* fmt, ...) __attribute__((format (printf, 4, 5))); +static inline void trace_printf(TraceLevel log_level, + const snort::Trace* trace, TraceOptionID trace_option_id, + const snort::Packet* p, const char* fmt, ...) + __attribute__((format (printf, 5, 6))); template -static inline void trace_printf(TraceLevel log_level, const snort::Trace* trace, - TraceOptionID trace_option_id, const char* fmt, ...) +static inline void trace_printf(TraceLevel log_level, + const snort::Trace* trace, TraceOptionID trace_option_id, + const snort::Packet* p, const char* fmt, ...) { - if ( !trace_enabled(trace, trace_option_id, log_level) ) + if ( !trace_enabled(trace, trace_option_id, log_level, p) ) return; va_list ap; va_start(ap, fmt); const char* trace_option_name = trace->option_name(trace_option_id); - trace_vprintf(trace->module_name(), log_level, trace_option_name, fmt, ap); + trace_vprintf(trace->module_name(), log_level, trace_option_name, + fmt, ap); va_end(ap); } template -static inline void trace_printf(TraceLevel log_level, const snort::Trace* trace, - const char* fmt, ...) __attribute__((format (printf, 3, 4))); +static inline void trace_printf(TraceLevel log_level, + const snort::Trace* trace, const snort::Packet* p, + const char* fmt, ...) __attribute__((format (printf, 4, 5))); template -static inline void trace_printf(TraceLevel log_level, const snort::Trace* trace, +static inline void trace_printf(TraceLevel log_level, + const snort::Trace* trace, const snort::Packet* p, const char* fmt, ...) { - if ( !trace_enabled(trace, DEFAULT_TRACE_OPTION_ID, log_level) ) + if ( !trace_enabled(trace, DEFAULT_TRACE_OPTION_ID, log_level, p) ) return; va_list ap; va_start(ap, fmt); const char* trace_option_name = trace->option_name(DEFAULT_TRACE_OPTION_ID); - trace_vprintf(trace->module_name(), log_level, trace_option_name, fmt, ap); + trace_vprintf(trace->module_name(), log_level, trace_option_name, + fmt, ap); va_end(ap); } template static inline void trace_printf(const snort::Trace* trace, - TraceOptionID trace_option_id, const char* fmt, ...) __attribute__((format (printf, 3, 4))); + TraceOptionID trace_option_id, const snort::Packet* p, + const char* fmt, ...) __attribute__((format (printf, 4, 5))); template static inline void trace_printf(const snort::Trace* trace, - TraceOptionID trace_option_id, const char* fmt, ...) + TraceOptionID trace_option_id, const snort::Packet* p, const char* fmt, ...) { - if ( !trace_enabled(trace, trace_option_id) ) + if ( !trace_enabled(trace, trace_option_id, DEFAULT_TRACE_LOG_LEVEL, p) ) return; va_list ap; va_start(ap, fmt); const char* trace_option_name = trace->option_name(trace_option_id); - trace_vprintf(trace->module_name(), DEFAULT_TRACE_LOG_LEVEL, trace_option_name, fmt, ap); + trace_vprintf(trace->module_name(), DEFAULT_TRACE_LOG_LEVEL, + trace_option_name, fmt, ap); va_end(ap); } template static inline void trace_printf(const snort::Trace* trace, - const char* fmt, ...) __attribute__((format (printf, 2, 3))); + const snort::Packet* p, const char* fmt, ...) + __attribute__((format (printf, 3, 4))); template -static inline void trace_printf(const snort::Trace* trace, const char* fmt, ...) +static inline void trace_printf(const snort::Trace* trace, + const snort::Packet* p, const char* fmt, ...) { - if ( !trace_enabled(trace, DEFAULT_TRACE_OPTION_ID) ) + if ( !trace_enabled(trace, DEFAULT_TRACE_OPTION_ID, DEFAULT_TRACE_LOG_LEVEL, p) ) return; va_list ap; va_start(ap, fmt); const char* trace_option_name = trace->option_name(DEFAULT_TRACE_OPTION_ID); - trace_vprintf(trace->module_name(), DEFAULT_TRACE_LOG_LEVEL, trace_option_name, fmt, ap); + trace_vprintf(trace->module_name(), DEFAULT_TRACE_LOG_LEVEL, + trace_option_name, fmt, ap); va_end(ap); } template -static inline void trace_print(TraceLevel log_level, const snort::Trace* trace, - TraceOptionID trace_option_id, const char* msg) +static inline void trace_print(TraceLevel log_level, + const snort::Trace* trace, TraceOptionID trace_option_id, + const snort::Packet* p, const char* msg) { - trace_printf(log_level, trace, trace_option_id, "%s", msg); + trace_printf(log_level, trace, trace_option_id, p, + "%s", msg); } template static inline void trace_print(const snort::Trace* trace, - TraceOptionID trace_option_id, const char* msg) + TraceOptionID trace_option_id, const snort::Packet* p, const char* msg) { - trace_printf(trace, trace_option_id, "%s", msg); + trace_printf(trace, trace_option_id, p, "%s", msg); } template -static inline void trace_print(TraceLevel log_level, const snort::Trace* trace, - const char* msg) +static inline void trace_print(TraceLevel log_level, + const snort::Trace* trace, const snort::Packet* p, const char* msg) { - trace_printf(log_level, trace, "%s", msg); + trace_printf(log_level, trace, p, "%s", msg); } template -static inline void trace_print(const snort::Trace* trace, const char* msg) +static inline void trace_print(const snort::Trace* trace, const snort::Packet* p, + const char* msg) { - trace_printf(trace, "%s", msg); + trace_printf(trace, p, "%s", msg); } #define trace_print trace_print @@ -164,3 +193,4 @@ static inline void trace_print(const snort::Trace* trace, const char* msg) #endif #endif + diff --git a/src/network_inspectors/appid/detector_plugins/detector_pattern.cc b/src/network_inspectors/appid/detector_plugins/detector_pattern.cc index 1d0f09b6a..739961ce8 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_pattern.cc +++ b/src/network_inspectors/appid/detector_plugins/detector_pattern.cc @@ -40,12 +40,12 @@ static void dump_patterns(const char* name, PatternService* pList) { UNUSED(name); - debug_logf(appid_trace, "Adding pattern for \"%s\"\n", name); + debug_logf(appid_trace, nullptr, "Adding pattern for \"%s\"\n", name); for (PatternService* ps = pList; ps; ps = ps->next) for (Pattern* pattern = ps->pattern; pattern; pattern = pattern->next) if (pattern->data && pattern->length) { - debug_logf(appid_trace, "\t\t%s, %u\n",pattern->data, pattern->length); + debug_logf(appid_trace, nullptr, "\t\t%s, %u\n",pattern->data, pattern->length); } } diff --git a/src/network_inspectors/appid/lua_detector_api.cc b/src/network_inspectors/appid/lua_detector_api.cc index aefacc26e..4b131c548 100644 --- a/src/network_inspectors/appid/lua_detector_api.cc +++ b/src/network_inspectors/appid/lua_detector_api.cc @@ -301,7 +301,7 @@ static int detector_log_message(lua_State* L) break; case LUA_LOG_TRACE: - debug_logf(appid_trace, "%s:%s\n", name.c_str(), message); + debug_logf(appid_trace, nullptr, "%s:%s\n", name.c_str(), message); break; default: diff --git a/src/network_inspectors/packet_tracer/packet_tracer.cc b/src/network_inspectors/packet_tracer/packet_tracer.cc index 1aa9648e5..a027f90bb 100644 --- a/src/network_inspectors/packet_tracer/packet_tracer.cc +++ b/src/network_inspectors/packet_tracer/packet_tracer.cc @@ -163,7 +163,7 @@ bool PacketTracer::is_paused() return false; } -void PacketTracer::set_constraints(const PTSessionConstraints* constraints) +void PacketTracer::set_constraints(const PacketConstraints* constraints) { if (!s_pkt_trace) return; @@ -222,26 +222,11 @@ void PacketTracer::activate(const Packet& p) } else { - if (s_pkt_trace->shell_enabled) + if (s_pkt_trace->shell_enabled and + !s_pkt_trace->constraints.packet_match(p)) { - uint16_t sport = p.ptrs.sp; - uint16_t dport = p.ptrs.dp; - - const SfIp *actual_sip = p.ptrs.ip_api.get_src(); - const SfIp *actual_dip = p.ptrs.ip_api.get_dst(); - - const uint32_t *sip_ptr = actual_sip->get_ip6_ptr(); - const uint32_t *dip_ptr = actual_dip->get_ip6_ptr(); - - IpProtocol proto = p.get_ip_proto_next(); - - if (!(s_pkt_trace->info.proto_match(proto) and - ((s_pkt_trace->info.port_match(sport, dport) and s_pkt_trace->info.ip_match(sip_ptr, dip_ptr)) or - (s_pkt_trace->info.port_match(dport, sport) and s_pkt_trace->info.ip_match(dip_ptr, sip_ptr))))) - { - s_pkt_trace->active = false; - return; - } + s_pkt_trace->active = false; + return; } s_pkt_trace->active = true; s_pkt_trace->add_ip_header_info(p); @@ -382,17 +367,18 @@ void PacketTracer::add_eth_header_info(const Packet& p) } } -void PacketTracer::update_constraints(const PTSessionConstraints* constraints) +void PacketTracer::update_constraints(const PacketConstraints* cs) { char sipstr[INET6_ADDRSTRLEN]; char dipstr[INET6_ADDRSTRLEN]; - info.set(*constraints); - info.sip.ntop(sipstr, sizeof(sipstr)); - info.dip.ntop(dipstr, sizeof(dipstr)); + constraints = *cs; + constraints.src_ip.ntop(sipstr, sizeof(sipstr)); + constraints.dst_ip.ntop(dipstr, sizeof(dipstr)); LogMessage("Debugging packet tracer with %s-%hu and %s-%hu %hhu\n", - sipstr, info.sport, dipstr, info.dport, static_cast(info.protocol)); + sipstr, constraints.src_port, dipstr, constraints.dst_port, + static_cast(constraints.ip_proto)); shell_enabled = true; diff --git a/src/network_inspectors/packet_tracer/packet_tracer.h b/src/network_inspectors/packet_tracer/packet_tracer.h index 3db4abac4..16fef4ff4 100644 --- a/src/network_inspectors/packet_tracer/packet_tracer.h +++ b/src/network_inspectors/packet_tracer/packet_tracer.h @@ -26,6 +26,7 @@ #include #include +#include "framework/packet_constraints.h" #include "main/snort_types.h" #include "main/thread.h" #include "protocols/ipv6.h" @@ -36,45 +37,6 @@ // IPv6 Port -> IPv6 Port Proto AS=ASNum ID=InstanceNum #define PT_DEBUG_SESSION_ID_SIZE ((39+1+5+1+2+1+39+1+5+1+3+1+2+1+10+1+2+1+10)+1) -struct PTSessionConstraints -{ - snort::SfIp sip; - int sip_flag = 0; - snort::SfIp dip; - int dip_flag = 0; - uint16_t sport; - uint16_t dport; - IpProtocol protocol = IpProtocol::PROTO_NOT_SET; - - bool proto_match(const IpProtocol& proto) const - { - return (protocol == IpProtocol::PROTO_NOT_SET or protocol == proto); - } - bool port_match(uint16_t p1, uint16_t p2) const - { - return (!sport or sport == p1) and (!dport or dport == p2); - } - bool ip_match(const uint32_t* ip1, const uint32_t* ip2) const - { - return - ((!sip_flag or !memcmp(sip.get_ip6_ptr(), ip1, sizeof(snort::ip::snort_in6_addr))) and - (!dip_flag or !memcmp(dip.get_ip6_ptr(), ip2, sizeof(snort::ip::snort_in6_addr)))); - } - - void set(const PTSessionConstraints& src); -}; - -inline void PTSessionConstraints::set(const PTSessionConstraints& src) -{ - if ((sip_flag = src.sip_flag)) - sip = src.sip; - if ((dip_flag = src.dip_flag)) - dip = src.dip; - sport = src.sport; - dport = src.dport; - protocol = src.protocol; -} - namespace snort { struct Packet; @@ -104,7 +66,7 @@ public: static void dump(Packet*); static void configure(bool status, const std::string& file_name); - static void set_constraints(const PTSessionConstraints* constraints); + static void set_constraints(const PacketConstraints* constraints); static void activate(const snort::Packet&); static SO_PUBLIC void pause(); @@ -136,7 +98,7 @@ protected: bool active = false; char debug_session[PT_DEBUG_SESSION_ID_SIZE]; - PTSessionConstraints info; + PacketConstraints constraints; // static functions template static void _thread_init(); @@ -146,7 +108,7 @@ protected: void add_ip_header_info(const snort::Packet&); void add_eth_header_info(const snort::Packet&); void add_packet_type_info(const snort::Packet&); - void update_constraints(const PTSessionConstraints* constraints); + void update_constraints(const PacketConstraints* constraints); const char *get_debug_session() { return debug_session; } virtual void open_file(); diff --git a/src/network_inspectors/packet_tracer/packet_tracer_module.cc b/src/network_inspectors/packet_tracer/packet_tracer_module.cc index 161bee514..07b90da78 100644 --- a/src/network_inspectors/packet_tracer/packet_tracer_module.cc +++ b/src/network_inspectors/packet_tracer/packet_tracer_module.cc @@ -70,16 +70,16 @@ static const Command packet_tracer_cmds[] = class PacketTracerDebug : public AnalyzerCommand { public: - PacketTracerDebug(PTSessionConstraints* cs); + PacketTracerDebug(PacketConstraints* cs); bool execute(Analyzer&, void**) override; const char *stringify() override { return "PACKET_TRACER_DEBUG"; } private: - PTSessionConstraints constraints = {}; + PacketConstraints constraints; bool enable = false; }; -PacketTracerDebug::PacketTracerDebug(PTSessionConstraints* cs) +PacketTracerDebug::PacketTracerDebug(PacketConstraints* cs) { if (cs) { @@ -122,26 +122,32 @@ static int enable(lua_State* L) LogMessage("Invalid destination IP address provided: %s\n", dipstr); } - PTSessionConstraints constraints = {}; + PacketConstraints constraints = {}; if (proto) - constraints.protocol = (IpProtocol)proto; + { + constraints.ip_proto = (IpProtocol)proto; + constraints.set_bits |= PacketConstraints::SetBits::IP_PROTO; + } if (sip.is_set()) { - constraints.sip = sip; - constraints.sip_flag = true; + constraints.src_ip = sip; + constraints.set_bits |= PacketConstraints::SetBits::SRC_IP; } if (dip.is_set()) { - constraints.dip = dip; - constraints.dip_flag = true; + constraints.dst_ip = dip; + constraints.set_bits |= PacketConstraints::SetBits::DST_IP; } - constraints.sport = sport; - constraints.dport = dport; - + constraints.src_port = sport; + constraints.dst_port = dport; + if ( sport ) + constraints.set_bits |= PacketConstraints::SetBits::SRC_PORT; + if ( dport ) + constraints.set_bits |= PacketConstraints::SetBits::DST_PORT; main_broadcast_command(new PacketTracerDebug(&constraints), true); return 0; } diff --git a/src/protocols/packet.cc b/src/protocols/packet.cc index 67e6dcb69..49fc79dbe 100644 --- a/src/protocols/packet.cc +++ b/src/protocols/packet.cc @@ -92,6 +92,7 @@ void Packet::reset() user_ips_policy_id = 0; user_network_policy_id = 0; vlan_idx = 0; + filtering_state.clear(); } void Packet::release_helpers() diff --git a/src/protocols/packet.h b/src/protocols/packet.h index 5f1e4b4a3..564a11575 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -132,8 +132,9 @@ struct SO_PUBLIC Packet // FIXIT-M Consider moving ip_proto_next below `pkth`. IpProtocol ip_proto_next; /* the protocol ID after IP and all IP6 extension */ bool disable_inspect; - // nothing after this point is zeroed by reset() ... + mutable FilteringState filtering_state; + // nothing after this point is zeroed by reset() ... IpsContext* context; Active* active; Active* active_inst; diff --git a/src/protocols/packet_manager.cc b/src/protocols/packet_manager.cc index ffcd685d8..e70caf140 100644 --- a/src/protocols/packet_manager.cc +++ b/src/protocols/packet_manager.cc @@ -157,7 +157,7 @@ void PacketManager::decode( // loop until the protocol id is no longer valid while (CodecManager::s_protocols[mapped_prot]->decode(raw, codec_data, p->ptrs)) { - debug_logf(decode_trace, "Codec %s (protocol_id: %hu) " + debug_logf(decode_trace, nullptr, "Codec %s (protocol_id: %hu) " "ip header starts at: %p, length is %d\n", CodecManager::s_protocols[mapped_prot]->get_name(), static_cast(codec_data.next_prot_id), pkt, codec_data.lyr_len); @@ -247,7 +247,7 @@ void PacketManager::decode( codec_data.proto_bits = 0; } - debug_logf(decode_trace, "Codec %s (protocol_id: %hu) ip header" + debug_logf(decode_trace, nullptr, "Codec %s (protocol_id: %hu) ip header" " starts at: %p, length is %lu\n", CodecManager::s_protocols[mapped_prot]->get_name(), static_cast(prev_prot_id), pkt, (unsigned long)codec_data.lyr_len); diff --git a/src/service_inspectors/dce_rpc/dce_smb2.cc b/src/service_inspectors/dce_rpc/dce_smb2.cc index 9b5075d3a..f2adcdbbb 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2.cc @@ -71,7 +71,7 @@ static inline DCE2_Ret DCE2_Smb2InsertTid(DCE2_SmbSsnData* ssd, const uint32_t t (ssd->max_file_depth == -1 and DCE2_ScSmbFileDepth((dce2SmbProtoConf*)ssd->sd.config) == -1) ) { - debug_logf(dce_smb_trace, "Not inserting TID (%u) for DISK share type " + debug_logf(dce_smb_trace, nullptr, "Not inserting TID (%u) for DISK share type " "as mandatory configuration max_file_depth is not present." "This will result in non-inspection of file data.\n", tid); return ret; @@ -680,7 +680,7 @@ static void DCE2_Smb2Inspect(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr, const } else { - debug_logf(dce_smb_trace, "Not handling create request for IPC with TID (%u)\n", + debug_logf(dce_smb_trace, nullptr, "Not handling create request for IPC with TID (%u)\n", Smb2Tid(smb_hdr)); } break; diff --git a/src/service_inspectors/dce_rpc/dce_smb_transaction.cc b/src/service_inspectors/dce_rpc/dce_smb_transaction.cc index 33e0fffb6..17df814d7 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_transaction.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_transaction.cc @@ -528,7 +528,7 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd, if (DCE2_SsnIsWindowsPolicy(&ssd->sd) && ssd->cur_rtracker->ftracker->fp_byte_mode) { - debug_log(dce_smb_trace, "Pipe is in byte mode - TRANS_TRANSACT_NMPIPE won't work\n"); + debug_log(dce_smb_trace, nullptr, "Pipe is in byte mode - TRANS_TRANSACT_NMPIPE won't work\n"); return DCE2_RET__ERROR; } data_params = DCE2_SMB_TRANS__DATA; @@ -588,7 +588,7 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd, && (DCE2_SmbTransactionGetName(nb_ptr, nb_len, byte_count, SmbUnicode(smb_hdr)) != DCE2_RET__SUCCESS)) { - debug_log(dce_smb_trace, "Failed to validate pipe name for Samba.\n"); + debug_log(dce_smb_trace, nullptr, "Failed to validate pipe name for Samba.\n"); return DCE2_RET__ERROR; } break; @@ -1071,7 +1071,7 @@ DCE2_Ret DCE2_SmbTransaction(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr, if (DCE2_ComInfoIsRequest(com_info) && !DCE2_SmbIsTransactionComplete(ttracker)) { - debug_log(dce_smb_trace, "Got new transaction request " + debug_log(dce_smb_trace, nullptr, "Got new transaction request " "that matches an in progress transaction - not inspecting.\n"); return DCE2_RET__ERROR; } @@ -1080,7 +1080,7 @@ DCE2_Ret DCE2_SmbTransaction(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr, if (DCE2_ComInfoIsRequest(com_info) && (DCE2_ComInfoWordCount(com_info) != 16)) { - debug_log(dce_smb_trace, "\\PIPE\\LANMAN request - not inspecting\n"); + debug_log(dce_smb_trace, nullptr, "\\PIPE\\LANMAN request - not inspecting\n"); return DCE2_RET__IGNORE; } @@ -1192,7 +1192,7 @@ DCE2_Ret DCE2_SmbTransaction2(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr, if (DCE2_ComInfoIsRequest(com_info) && !DCE2_SmbIsTransactionComplete(ttracker)) { - debug_log(dce_smb_trace, "Got new transaction request " + debug_log(dce_smb_trace, nullptr, "Got new transaction request " "that matches an in progress transaction - not inspecting.\n"); return DCE2_RET__ERROR; } @@ -1450,7 +1450,7 @@ DCE2_Ret DCE2_SmbNtTransact(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr, if (DCE2_ComInfoIsRequest(com_info) && !DCE2_SmbIsTransactionComplete(ttracker)) { - debug_log(dce_smb_trace, "Got new transaction request " + debug_log(dce_smb_trace, nullptr, "Got new transaction request " "that matches an in progress transaction - not inspecting.\n"); return DCE2_RET__ERROR; } diff --git a/src/service_inspectors/dce_rpc/dce_smb_utils.cc b/src/service_inspectors/dce_rpc/dce_smb_utils.cc index fab99ac0a..bcaf0bd5a 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_utils.cc @@ -838,7 +838,7 @@ void DCE2_SmbInsertTid(DCE2_SmbSsnData* ssd, if ( !is_ipc and ssd->max_file_depth == -1 and DCE2_ScSmbFileDepth((dce2SmbProtoConf*)ssd->sd.config) == -1 ) { - debug_logf(dce_smb_trace, "Not inserting TID (%hu) " + debug_logf(dce_smb_trace, nullptr, "Not inserting TID (%hu) " "because it's not IPC and not inspecting normal file data.\n", tid); return; } @@ -1534,7 +1534,7 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd, if (!file_flows->file_process(p, data_ptr, (int)data_len, position, upload, DCE2_SmbIsVerdictSuspend(upload, position))) { - debug_logf(dce_smb_trace, "File API returned FAILURE for (0x%02X) %s\n", + debug_logf(dce_smb_trace, nullptr, "File API returned FAILURE for (0x%02X) %s\n", ftracker->fid_v1, upload ? "UPLOAD" : "DOWNLOAD"); // Failure. Abort tracking this file under file API @@ -1781,7 +1781,7 @@ void DCE2_SmbProcessFileData(DCE2_SmbSsnData* ssd, } else if (ftracker->ff_file_offset < ftracker->ff_bytes_processed) { - debug_logf(dce_smb_trace, "File offset %" PRIu64 " is " + debug_logf(dce_smb_trace, nullptr, "File offset %" PRIu64 " is " "less than bytes processed %" PRIu64 " - aborting.\n", ftracker->ff_file_offset, ftracker->ff_bytes_processed); diff --git a/src/service_inspectors/dce_rpc/dce_udp_processing.cc b/src/service_inspectors/dce_rpc/dce_udp_processing.cc index d1ce5fa63..12720abd3 100644 --- a/src/service_inspectors/dce_rpc/dce_udp_processing.cc +++ b/src/service_inspectors/dce_rpc/dce_udp_processing.cc @@ -154,7 +154,7 @@ void DCE2_ClProcess(DCE2_SsnData* sd, DCE2_ClTracker* clt) case DCERPC_PDU_TYPE__RESPONSE: { - debug_log(dce_udp_trace, "Response from client. Changing stream direction.\n"); + debug_log(dce_udp_trace, p, "Response from client. Changing stream direction.\n"); ip::IpApi* ip_api = &p->ptrs.ip_api; p->flow->session->update_direction(SSN_DIR_FROM_SERVER, diff --git a/src/service_inspectors/dce_rpc/smb_message.cc b/src/service_inspectors/dce_rpc/smb_message.cc index 27bc1a360..e635e8b80 100644 --- a/src/service_inspectors/dce_rpc/smb_message.cc +++ b/src/service_inspectors/dce_rpc/smb_message.cc @@ -807,7 +807,7 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr com_info.cmd_size = 0; com_info.byte_count = 0; DCE2_SmbCheckCommand(ssd, smb_hdr, smb_com, nb_ptr, nb_len, com_info); - debug_logf(dce_smb_trace, "Processing command: %s (0x%02X)\n", + debug_logf(dce_smb_trace, nullptr, "Processing command: %s (0x%02X)\n", get_smb_com_string(smb_com), smb_com); // Note that even if the command shouldn't be processed, some of @@ -832,7 +832,7 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr if (smb_com2 == SMB_COM_NO_ANDX_COMMAND) break; - debug_logf(dce_smb_trace, "Chained SMB command: %s\n", get_smb_com_string(smb_com2)); + debug_logf(dce_smb_trace, nullptr, "Chained SMB command: %s\n", get_smb_com_string(smb_com2)); num_chained++; if (DCE2_ScSmbMaxChain((dce2SmbProtoConf*)ssd->sd.config) && @@ -1033,7 +1033,7 @@ static DCE2_SmbRequestTracker* DCE2_SmbInspect(DCE2_SmbSsnData* ssd, const SmbNt { int smb_com = SmbCom(smb_hdr); - debug_logf(dce_smb_trace, "SMB command: %s (0x%02X)\n", get_smb_com_string(smb_com), smb_com); + debug_logf(dce_smb_trace, nullptr, "SMB command: %s (0x%02X)\n", get_smb_com_string(smb_com), smb_com); if (smb_com_funcs[smb_com] == nullptr) { @@ -1628,7 +1628,7 @@ static void DCE2_Smb1Process(DCE2_SmbSsnData* ssd) rtracker = DCE2_SmbInspect(ssd, smb_hdr); if (rtracker == nullptr) { - debug_log(dce_smb_trace, "Not inspecting SMB packet.\n"); + debug_log(dce_smb_trace, nullptr, "Not inspecting SMB packet.\n"); if (DCE2_BufferIsEmpty(*seg_buf)) { diff --git a/src/service_inspectors/gtp/gtp_parser.cc b/src/service_inspectors/gtp/gtp_parser.cc index 4d50137c1..98ffbd411 100644 --- a/src/service_inspectors/gtp/gtp_parser.cc +++ b/src/service_inspectors/gtp/gtp_parser.cc @@ -111,7 +111,7 @@ static void printInfoElements(GTP_IEData* info_elements, GTPMsg* msg) char buf[STD_BUF]; convertToHex( (char*)buf, sizeof(buf), msg->gtp_header + info_elements[i].shift, info_elements[i].length); - debug_logf(gtp_inspect_trace, "Info type: %.3d, content: %s\n", i, buf); + debug_logf(gtp_inspect_trace, nullptr, "Info type: %.3d, content: %s\n", i, buf); } } } diff --git a/src/service_inspectors/wizard/wizard.cc b/src/service_inspectors/wizard/wizard.cc index 7c35cedcc..3585b1c21 100644 --- a/src/service_inspectors/wizard/wizard.cc +++ b/src/service_inspectors/wizard/wizard.cc @@ -171,7 +171,7 @@ StreamSplitter::Status MagicSplitter::scan( if ( wizard->cast_spell(wand, pkt->flow, data, len) ) { - trace_logf(wizard_trace, "service set to %s\n", pkt->flow->service); + trace_logf(wizard_trace, pkt, "service set to %s\n", pkt->flow->service); count_hit(pkt->flow); } @@ -249,7 +249,7 @@ void Wizard::eval(Packet* p) if ( cast_spell(wand, p->flow, p->data, p->dsize) ) { - trace_logf(wizard_trace, "service set to %s\n", p->flow->service); + trace_logf(wizard_trace, p, "service set to %s\n", p->flow->service); ++tstats.udp_hits; } diff --git a/src/stream/ip/ip_defrag.cc b/src/stream/ip/ip_defrag.cc index d7498f24c..93f50a8b9 100644 --- a/src/stream/ip/ip_defrag.cc +++ b/src/stream/ip/ip_defrag.cc @@ -291,7 +291,7 @@ static inline int FragCheckFirstLast( { ft->frag_flags |= FRAG_GOT_FIRST; - debug_log(stream_ip_trace,"Got first frag\n"); + debug_log(stream_ip_trace, p, "Got first frag\n"); } else if ((!(p->ptrs.decode_flags & DECODE_MF)) && (frag_offset > 0)) /* set for last frag too */ @@ -306,7 +306,7 @@ static inline int FragCheckFirstLast( if (ft->frag_flags & FRAG_GOT_LAST) { - debug_log(stream_ip_trace,"Got last frag again!\n"); + debug_log(stream_ip_trace, p, "Got last frag again!\n"); switch (ft->frag_policy) { case FRAG_POLICY_BSD: @@ -371,7 +371,7 @@ static inline int FragCheckFirstLast( { ft->calculated_size = endOfThisFrag; - debug_logf(stream_ip_trace,"Got last frag, Bytes: %u, Calculated size: %u\n", + debug_logf(stream_ip_trace, p, "Got last frag, Bytes: %u, Calculated size: %u\n", ft->frag_bytes, ft->calculated_size); } } @@ -381,7 +381,7 @@ static inline int FragCheckFirstLast( ft->frag_flags |= FRAG_NO_BSD_VULN; } - debug_logf(stream_ip_trace,"Frag Status: %s:%s\n", + debug_logf(stream_ip_trace, p, "Frag Status: %s:%s\n", (ft->frag_flags&FRAG_GOT_FIRST) ? "FIRST" : "No FIRST", (ft->frag_flags&FRAG_GOT_LAST) ? "LAST" : "No LAST"); return retVal; @@ -488,7 +488,7 @@ static inline int checkTinyFragments( { if (p->dsize <= engine->min_fragment_length) { - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, p, "Frag: Received fragment size(%d) is not more than configured min_fragment_length (%u)\n", p->dsize, engine->min_fragment_length); EventTinyFragments(engine); @@ -498,7 +498,7 @@ static inline int checkTinyFragments( ///detect tiny fragments after processing overlaps. if (trimmedLength <= engine->min_fragment_length) { - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, p, "Frag: # of New octets in Received fragment(%u) is not more than configured min_fragment_length (%u)\n", trimmedLength, engine->min_fragment_length); EventTinyFragments(engine); @@ -521,7 +521,7 @@ static inline int checkTinyFragments( */ static inline int FragIsComplete(FragTracker* ft) { - debug_log(stream_ip_trace, "[$] Checking completion criteria\n"); + debug_log(stream_ip_trace, nullptr, "[$] Checking completion criteria\n"); /* * check to see if the first and last frags have arrived @@ -529,7 +529,7 @@ static inline int FragIsComplete(FragTracker* ft) if ((ft->frag_flags & FRAG_GOT_FIRST) && (ft->frag_flags & FRAG_GOT_LAST)) { - debug_log(stream_ip_trace, " Got First and Last frags\n"); + debug_log(stream_ip_trace, nullptr, " Got First and Last frags\n"); /* * if we've accumulated enough data to match the calculated size @@ -537,7 +537,7 @@ static inline int FragIsComplete(FragTracker* ft) */ if (ft->frag_bytes == ft->calculated_size) { - debug_log(stream_ip_trace, " [!] frag_bytes = calculated_size!\n"); + debug_log(stream_ip_trace, nullptr, " [!] frag_bytes = calculated_size!\n"); ip_stats.trackers_completed++; @@ -546,14 +546,14 @@ static inline int FragIsComplete(FragTracker* ft) if (ft->frag_bytes > ft->calculated_size) { - debug_log(stream_ip_trace, " [!] frag_bytes > calculated_size!\n"); + debug_log(stream_ip_trace, nullptr, " [!] frag_bytes > calculated_size!\n"); ip_stats.trackers_completed++; return 1; } - debug_logf(stream_ip_trace, " Calc size (%u) != frag bytes (%u)\n", + debug_logf(stream_ip_trace, nullptr, " Calc size (%u) != frag bytes (%u)\n", ft->calculated_size, ft->frag_bytes); /* @@ -562,7 +562,7 @@ static inline int FragIsComplete(FragTracker* ft) return 0; } - debug_logf(stream_ip_trace, " Missing First or Last frags (frag_flags: 0x%X)\n", + debug_logf(stream_ip_trace, nullptr, " Missing First or Last frags (frag_flags: 0x%X)\n", ft->frag_flags); return 0; @@ -595,7 +595,7 @@ static void FragRebuild(FragTracker* ft, Packet* p) /* Adjust the IP header size in pseudo packet for the new length */ uint8_t new_ip_hlen = ip::IP4_HEADER_LEN + ft->ip_options_len; - debug_logf(stream_ip_trace, "Adjusting IP Header to %d bytes\n", + debug_logf(stream_ip_trace, p, "Adjusting IP Header to %d bytes\n", new_ip_hlen); iph->set_hlen(new_ip_hlen >> 2); @@ -616,7 +616,7 @@ static void FragRebuild(FragTracker* ft, Packet* p) iph->ip_off = 0x0000; dpkt->ptrs.decode_flags &= ~DECODE_FRAG; - debug_log(stream_ip_trace, "[^^] Walking fraglist:\n"); + debug_log(stream_ip_trace, p, "[^^] Walking fraglist:\n"); } /* @@ -624,7 +624,7 @@ static void FragRebuild(FragTracker* ft, Packet* p) */ for ( Fragment* frag = ft->fraglist; frag; frag = frag->next ) { - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, nullptr, " frag: %p\n" " frag->data: %p\n" " frag->offset: %d\n" @@ -702,7 +702,7 @@ static void FragRebuild(FragTracker* ft, Packet* p) /* * process the packet through the detection engine */ - debug_log(stream_ip_trace, "Processing rebuilt packet:\n"); + debug_log(stream_ip_trace, nullptr, "Processing rebuilt packet:\n"); ip_stats.reassembles++; ip_stats.reassembled_bytes += dpkt->pktlen; @@ -721,7 +721,7 @@ static void FragRebuild(FragTracker* ft, Packet* p) Analyzer::get_local_analyzer()->process_rebuilt_packet(dpkt, dpkt->pkth, dpkt->pkt, dpkt->pktlen); de.set_encode_packet(nullptr); - debug_log(stream_ip_trace,"Done with rebuilt packet, marking rebuilt...\n"); + debug_log(stream_ip_trace, nullptr, "Done with rebuilt packet, marking rebuilt...\n"); ft->frag_flags |= FRAG_REBUILT; } @@ -763,7 +763,7 @@ static inline void add_node(FragTracker* ft, Fragment* prev, Fragment* node) static inline void delete_node(FragTracker* ft, Fragment* node) { - debug_logf(stream_ip_trace,"Deleting list node %p (p %p n %p)\n", + debug_logf(stream_ip_trace, nullptr, "Deleting list node %p (p %p n %p)\n", (void*) node, (void*) node->prev, (void*) node->next); if (node->prev) @@ -796,7 +796,7 @@ static void delete_tracker(FragTracker* ft) Fragment* idx = ft->fraglist; /* pointer to the fraglist to delete */ Fragment* dump_me = nullptr; /* ptr to the Fragment element to drop */ - debug_logf(stream_ip_trace, "delete_tracker %d nodes to dump\n", ft->fraglist_count); + debug_logf(stream_ip_trace, nullptr, "delete_tracker %d nodes to dump\n", ft->fraglist_count); /* * delete all the nodes in a fraglist @@ -899,7 +899,7 @@ void Defrag::process(Packet* p, FragTracker* ft) #ifdef DEBUG_MSGS if ( p->is_ip4() ) { - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, p, "[FRAG] Fragment discarded due to low TTL " "[0x%X->0x%X], TTL: %d " "Offset: %d Length: %hu\n", ntohl(p->ptrs.ip_api.get_ip4h()->get_src()), @@ -960,7 +960,7 @@ void Defrag::process(Packet* p, FragTracker* ft) switch (insert_return) { case FRAG_INSERT_FAILED: - debug_logf(stream_ip_trace,"WARNING: Insert into Fraglist failed, (offset: %hu).\n", + debug_logf(stream_ip_trace, p, "WARNING: Insert into Fraglist failed, (offset: %hu).\n", frag_offset); return; @@ -969,7 +969,7 @@ void Defrag::process(Packet* p, FragTracker* ft) #ifdef DEBUG_MSGS if ( p->is_ip4() ) { - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, p, "[FRAG] Fragment discarded due to large TTL Delta " "[0x%X->0x%X], TTL: %d orig TTL: %d " "Offset: %hu Length: %hu\n", @@ -988,12 +988,12 @@ void Defrag::process(Packet* p, FragTracker* ft) return; case FRAG_INSERT_TIMEOUT: - debug_logf(stream_ip_trace,"WARNING: Insert into Fraglist failed due to timeout, " + debug_logf(stream_ip_trace, p, "WARNING: Insert into Fraglist failed due to timeout, " "(offset: %hu).\n", frag_offset); return; case FRAG_INSERT_OVERLAP_LIMIT: - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, p, "WARNING: Excessive IP fragment overlap, " "(More: %d, offset: %d, offsetSize: %hu).\n", (p->ptrs.decode_flags & DECODE_MF), @@ -1011,7 +1011,7 @@ void Defrag::process(Packet* p, FragTracker* ft) */ if (FragIsComplete(ft)) { - debug_log(stream_ip_trace,"[*] Fragment is complete, rebuilding!\n"); + debug_log(stream_ip_trace, p, "[*] Fragment is complete, rebuilding!\n"); /* * if the frag completes but it's bad we're just going to drop it @@ -1105,7 +1105,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) if (IP_MAXPACKET - frag_offset < fragLength) { - debug_log(stream_ip_trace,"[..] Oversize frag!\n"); + debug_log(stream_ip_trace, p, "[..] Oversize frag!\n"); EventAnomBadsizeLg(fe); ft->frag_flags |= FRAG_BAD; return FRAG_INSERT_ANOMALY; @@ -1139,7 +1139,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) /* * bonk/boink/jolt/etc attack... */ - debug_log(stream_ip_trace, "[..] Short frag (Bonk, etc) attack!\n"); + debug_log(stream_ip_trace, p, "[..] Short frag (Bonk, etc) attack!\n"); EventAnomShortFrag(fe); @@ -1162,7 +1162,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) if (ft->frag_flags & FRAG_GOT_LAST) { /* oversize frag attack */ - debug_log(stream_ip_trace, "[..] Oversize frag pkt!\n"); + debug_log(stream_ip_trace, p, "[..] Oversize frag pkt!\n"); EventAnomOversize(fe); @@ -1177,7 +1177,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) /* * zero size frag... */ - debug_log(stream_ip_trace, "[..] Zero size frag!\n"); + debug_log(stream_ip_trace, p, "[..] Zero size frag!\n"); EventAnomZeroFrag(fe); @@ -1194,7 +1194,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) ft->frag_pkts++; - debug_logf(stream_ip_trace, "Walking frag list (%d nodes), new frag %d@%d\n", + debug_logf(stream_ip_trace, p, "Walking frag list (%d nodes), new frag %d@%d\n", ft->fraglist_count, fragLength, frag_offset); /* @@ -1206,7 +1206,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) i++; right = idx; - debug_logf(stream_ip_trace, "%d right o %d s %d ptr %p prv %p nxt %p\n", + debug_logf(stream_ip_trace, p, "%d right o %d s %d ptr %p prv %p nxt %p\n", i, right->offset, right->size, (void*) right, (void*) right->prev, (void*) right->next); @@ -1229,7 +1229,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) */ if (left) { - debug_logf(stream_ip_trace, "Dealing with previous (left) frag %d@%d\n", + debug_logf(stream_ip_trace, p, "Dealing with previous (left) frag %d@%d\n", left->size, left->offset); /* @@ -1255,7 +1255,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) /* * teardrop attack... */ - debug_log(stream_ip_trace, "[..] Teardrop attack!\n"); + debug_log(stream_ip_trace, p, "[..] Teardrop attack!\n"); EventAttackTeardrop(fe); @@ -1284,7 +1284,7 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) frag_offset += (int16_t)overlap; slide = (int16_t)overlap; - debug_logf(stream_ip_trace, "left overlap, new frag moves: %d bytes, slide: %d\n", + debug_logf(stream_ip_trace, p, "left overlap, new frag moves: %d bytes, slide: %d\n", overlap, slide); if (frag_end <= frag_offset) @@ -1292,14 +1292,14 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) /* * zero size frag */ - debug_log(stream_ip_trace, "zero size frag\n"); + debug_log(stream_ip_trace, p, "zero size frag\n"); EventAnomZeroFrag(fe); return FRAG_INSERT_ANOMALY; } - debug_logf(stream_ip_trace,"left overlap, truncating new pkt (slide: %d)\n", + debug_logf(stream_ip_trace, p, "left overlap, truncating new pkt (slide: %d)\n", slide); break; @@ -1354,15 +1354,15 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) } left_overlap_last: - debug_logf(stream_ip_trace,"[!!] left overlap, " + debug_logf(stream_ip_trace, p, "[!!] left overlap, " "truncating old pkt (offset: %d overlap: %d)\n", left->offset, overlap); if (left->size == 0) { dump_me = left; - debug_logf(stream_ip_trace,"retrans, dumping old frag (offset: %d overlap: %d)\n", - dump_me->offset, overlap); + debug_logf(stream_ip_trace, p, "retrans, dumping old frag " + "(offset: %d overlap: %d)\n", dump_me->offset, overlap); left = left->prev; @@ -1377,7 +1377,7 @@ left_overlap_last: */ if (frag_end < frag_offset) { - debug_log(stream_ip_trace, "frag_end < frag_offset!"); + debug_log(stream_ip_trace, p, "frag_end < frag_offset!"); EventAnomBadsizeSm(fe); @@ -1386,13 +1386,13 @@ left_overlap_last: } else { - debug_log(stream_ip_trace,"No left overlap!\n"); + debug_log(stream_ip_trace, p, "No left overlap!\n"); } } if ((uint16_t)fragLength > p->context->conf->daq_config->get_mru_size()) { - debug_logf(stream_ip_trace, "Overly large fragment %d 0x%x 0x%x %d\n", + debug_logf(stream_ip_trace, p, "Overly large fragment %d 0x%x 0x%x %d\n", fragLength, p->ptrs.ip_api.dgram_len(), p->ptrs.ip_api.off(), net_frag_offset); return FRAG_INSERT_FAILED; @@ -1406,7 +1406,7 @@ left_overlap_last: */ while (right && (right->offset < frag_end) && !done) { - debug_logf(stream_ip_trace, "Next (right)fragment %d@%d\n", + debug_logf(stream_ip_trace, p, "Next (right)fragment %d@%d\n", right->size, right->offset); trunc = 0; @@ -1423,7 +1423,7 @@ left_overlap_last: /* * teardrop attack... */ - debug_log(stream_ip_trace, "[..] Teardrop attack!\n"); + debug_log(stream_ip_trace, p, "[..] Teardrop attack!\n"); EventAttackTeardrop(fe); @@ -1442,7 +1442,7 @@ left_overlap_last: ip_stats.overlaps++; ft->overlap_count++; - debug_logf(stream_ip_trace, "Right-side overlap %d bytes\n", overlap); + debug_logf(stream_ip_trace, p, "Right-side overlap %d bytes\n", overlap); /* * once again, engine-based policy processing @@ -1468,16 +1468,16 @@ left_overlap_last: right->size -= (int16_t)overlap; ft->frag_bytes -= (int16_t)overlap; } - debug_logf(stream_ip_trace,"[!!] right overlap, " + debug_logf(stream_ip_trace, p, "[!!] right overlap, " "truncating old frag (offset: %d, " "overlap: %d)\n", right->offset, overlap); - debug_log(stream_ip_trace, "Exiting right overlap loop...\n"); + debug_log(stream_ip_trace, p, "Exiting right overlap loop...\n"); if (right->size == 0) { dump_me = right; - debug_logf(stream_ip_trace,"retrans, dumping old frag (offset: %d overlap: %d)\n", - dump_me->offset, overlap); + debug_logf(stream_ip_trace, p, "retrans, dumping old frag " + "(offset: %d overlap: %d)\n", dump_me->offset, overlap); right = right->next; @@ -1493,9 +1493,9 @@ left_overlap_last: case FRAG_POLICY_SOLARIS: case FRAG_POLICY_BSD_RIGHT: trunc = (int16_t)overlap; - debug_logf(stream_ip_trace,"[!!] right overlap, " + debug_logf(stream_ip_trace, p, "[!!] right overlap, " "truncating new frag (offset: %d overlap: %d)\n", right->offset, overlap); - debug_log(stream_ip_trace, "Exiting right overlap loop...\n"); + debug_log(stream_ip_trace, p, "Exiting right overlap loop...\n"); break; } @@ -1543,8 +1543,8 @@ left_overlap_last: dump_me = right; ft->frag_bytes -= right->size; - debug_logf(stream_ip_trace,"retrans, dumping old frag (offset: %d overlap: %d)\n", - dump_me->offset, overlap); + debug_logf(stream_ip_trace, p, "retrans, dumping old frag " + "(offset: %d overlap: %d)\n", dump_me->offset, overlap); right = right->next; @@ -1590,7 +1590,7 @@ left_overlap_last: trunc = (int16_t)overlap; } - debug_logf(stream_ip_trace,"right overlap, rejecting new overlap data (overlap: %d, " + debug_logf(stream_ip_trace, p, "right overlap, rejecting new overlap data (overlap: %d, " "trunc: %d)\n", overlap, trunc); if (frag_end - trunc <= frag_offset) @@ -1598,7 +1598,7 @@ left_overlap_last: /* * zero size frag */ - debug_logf(stream_ip_trace, "zero size frag (len: %d overlap: %d)\n", + debug_logf(stream_ip_trace, p, "zero size frag (len: %d overlap: %d)\n", fragLength, overlap); ip_stats.discards++; @@ -1684,7 +1684,7 @@ right_overlap_last: dump_me = right; ft->frag_bytes -= right->size; - debug_logf(stream_ip_trace,"retrans, dumping old frag (offset: %d overlap: %d)\n", + debug_logf(stream_ip_trace, p, "retrans, dumping old frag (offset: %d overlap: %d)\n", dump_me->offset, overlap); right = right->next; @@ -1703,7 +1703,7 @@ right_overlap_last: (ft->overlap_count >= fe->max_overlaps)) { // overlap limit exceeded. Raise event on all subsequent fragments - debug_log(stream_ip_trace,"Reached overlap limit.\n"); + debug_log(stream_ip_trace, p, "Reached overlap limit.\n"); EventExcessiveOverlap(fe); @@ -1717,10 +1717,10 @@ right_overlap_last: } else { - debug_log(stream_ip_trace, "Fully truncated right overlap\n"); + debug_log(stream_ip_trace, p, "Fully truncated right overlap\n"); } - debug_log(stream_ip_trace, "insert(): returning normally\n"); + debug_log(stream_ip_trace, p, "insert(): returning normally\n"); return ret; } @@ -1752,7 +1752,7 @@ int Defrag::new_tracker(Packet* p, FragTracker* ft) /* Just to double check */ if (!fragLength or fragLength > p->context->conf->daq_config->get_mru_size()) { - debug_logf(stream_ip_trace, "Bad fragment length:%d(0x%x) off:0x%x(%d)\n", + debug_logf(stream_ip_trace, p, "Bad fragment length:%d(0x%x) off:0x%x(%d)\n", fragLength, p->ptrs.ip_api.dgram_len(), p->ptrs.ip_api.off(), p->ptrs.ip_api.off()); @@ -1818,7 +1818,7 @@ int Defrag::new_tracker(Packet* p, FragTracker* ft) /* * bonk/boink/jolt/etc attack... */ - debug_log(stream_ip_trace, "[..] Short frag (Bonk, etc) attack!\n"); + debug_log(stream_ip_trace, p, "[..] Short frag (Bonk, etc) attack!\n"); EventAnomShortFrag(&engine); @@ -1890,7 +1890,7 @@ int Defrag::add_frag_node( /* * zero size frag */ - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, nullptr, "zero size frag after left & right trimming " "(len: %d slide: %d trunc: %d)\n", len, slide, trunc); @@ -1901,7 +1901,7 @@ int Defrag::add_frag_node( newfrag = ft->fraglist; while (newfrag) { - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, nullptr, "Size: %d, offset: %d, len %d, " "Prev: 0x%p, Next: 0x%p, This: 0x%p, Ord: %d, %s\n", newfrag->size, newfrag->offset, @@ -1925,7 +1925,7 @@ int Defrag::add_frag_node( newfrag->offset = frag_offset; newfrag->last = lastfrag; - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, nullptr, "[+] Adding new frag, offset %d, size %d\n" " nf->data = nf->fptr(%p) + slide (%d)\n" " nf->size = len(%d) - slide(%d) - trunc(%d)\n", @@ -1937,7 +1937,7 @@ int Defrag::add_frag_node( */ add_node(ft, left, newfrag); - debug_logf(stream_ip_trace, "[*] Inserted new frag %d@%d ptr %p data %p prv %p nxt %p\n", + debug_logf(stream_ip_trace, nullptr, "[*] Inserted new frag %d@%d ptr %p data %p prv %p nxt %p\n", newfrag->size, newfrag->offset, (void*) newfrag, newfrag->data, (void*) newfrag->prev, (void*) newfrag->next); @@ -1946,7 +1946,7 @@ int Defrag::add_frag_node( */ ft->frag_bytes += newfrag->size; - debug_logf(stream_ip_trace, "[#] accumulated bytes on FragTracker %u, count %d\n", + debug_logf(stream_ip_trace, nullptr, "[#] accumulated bytes on FragTracker %u, count %d\n", ft->frag_bytes, ft->fraglist_count); *retFrag = newfrag; @@ -1970,7 +1970,7 @@ int Defrag::dup_frag_node( FragTracker* ft, Fragment* left, Fragment** retFrag) add_node(ft, left, newfrag); - debug_logf(stream_ip_trace, + debug_logf(stream_ip_trace, nullptr, "[*] Inserted new frag %d@%d ptr %p data %p prv %p nxt %p\n", newfrag->size, newfrag->offset, (void*) newfrag, newfrag->data, (void*) newfrag->prev, (void*) newfrag->next); @@ -1980,7 +1980,7 @@ int Defrag::dup_frag_node( FragTracker* ft, Fragment* left, Fragment** retFrag) */ ft->frag_bytes += newfrag->size; - debug_logf(stream_ip_trace, "[#] accumulated bytes on FragTracker %u, count %d\n", + debug_logf(stream_ip_trace, nullptr, "[#] accumulated bytes on FragTracker %u, count %d\n", ft->frag_bytes, ft->fraglist_count); *retFrag = newfrag; diff --git a/src/stream/stream.cc b/src/stream/stream.cc index 603f3d5e8..430fd3100 100644 --- a/src/stream/stream.cc +++ b/src/stream/stream.cc @@ -221,7 +221,7 @@ void Stream::stop_inspection( { assert(flow && flow->session); - debug_logf(stream_trace, "stop inspection on flow, dir %s \n", + debug_logf(stream_trace, p, "stop inspection on flow, dir %s \n", dir == SSN_DIR_BOTH ? "BOTH" : ((dir == SSN_DIR_FROM_CLIENT) ? "FROM_CLIENT" : "FROM_SERVER")); diff --git a/src/stream/user/user_session.cc b/src/stream/user/user_session.cc index 2a312aa95..83b7cfa11 100644 --- a/src/stream/user/user_session.cc +++ b/src/stream/user/user_session.cc @@ -166,7 +166,7 @@ void UserTracker::detect( up->packet_flags |= (p->packet_flags & (PKT_FROM_CLIENT|PKT_FROM_SERVER)); up->packet_flags |= (p->packet_flags & (PKT_STREAM_EST|PKT_STREAM_UNEST_UNI)); - debug_logf(stream_user_trace, "detect[%d]\n", up->dsize); + debug_logf(stream_user_trace, up, "detect[%d]\n", up->dsize); Analyzer::get_local_analyzer()->inspect_rebuilt(up); } @@ -186,7 +186,7 @@ int UserTracker::scan(Packet* p, uint32_t& flags) flags = p->packet_flags & (PKT_FROM_CLIENT|PKT_FROM_SERVER); unsigned len = us->get_unused_len(); - debug_logf(stream_user_trace, "scan[%d]\n", len); + debug_logf(stream_user_trace, p, "scan[%d]\n", len); int32_t flush_amt = paf_check( splitter, &paf_state, p, us->get_unused_data(), len, @@ -211,7 +211,7 @@ int UserTracker::scan(Packet* p, uint32_t& flags) void UserTracker::flush(Packet* p, unsigned flush_amt, uint32_t flags) { unsigned bytes_flushed = 0; - debug_logf(stream_user_trace, "flush[%d]\n", flush_amt); + debug_logf(stream_user_trace, p, "flush[%d]\n", flush_amt); uint32_t rflags = flags & ~PKT_PDU_TAIL; Packet* up = DetectionEngine::set_next_packet(p); @@ -231,7 +231,7 @@ void UserTracker::flush(Packet* p, unsigned flush_amt, uint32_t flags) len = flush_amt; } - debug_logf(stream_user_trace, "reassemble[%d]\n", len); + debug_logf(stream_user_trace, p, "reassemble[%d]\n", len); StreamBuffer sb = splitter->reassemble( p->flow, flush_amt, bytes_flushed, data, len, rflags, bytes_copied); @@ -276,7 +276,7 @@ void UserTracker::process(Packet* p) void UserTracker::add_data(Packet* p) { - debug_logf(stream_user_trace, "add[%d]\n", p->dsize); + debug_logf(stream_user_trace, p, "add[%d]\n", p->dsize); unsigned avail = 0; if ( !seg_list.empty() ) diff --git a/src/trace/dev_notes.txt b/src/trace/dev_notes.txt index 5e866f632..2949148bf 100644 --- a/src/trace/dev_notes.txt +++ b/src/trace/dev_notes.txt @@ -29,6 +29,7 @@ This directory contains the trace logger framework. This module provides configuration for trace logs: output - create a concrete logger factory based on the output value (stdout/syslog). + constraints - set packet constraints to use for trace filtering. modules - set modules trace level verbosity. This is a built-in module (from coreinit.lua) @@ -36,12 +37,12 @@ This directory contains the trace logger framework. The module placed into "trace_module.h/trace_module.cc". TraceModule ctor should be called after all existed modules due to TraceModule - dynamic params restriction. + dynamic params restriction. * TraceApi TraceApi is a facade API class used to init/reinit/term thread-local trace logger and module's - trace pointers. + trace pointers and to match packets and flows against trace filtering constraints. TraceApi placed into "trace_api.h/trace_api.cc" diff --git a/src/trace/trace_api.cc b/src/trace/trace_api.cc index fd6f79f84..2537c4008 100644 --- a/src/trace/trace_api.cc +++ b/src/trace/trace_api.cc @@ -23,8 +23,10 @@ #include "trace_api.h" +#include "framework/packet_constraints.h" #include "main/snort_config.h" #include "main/thread.h" +#include "protocols/packet.h" #include "trace_config.h" #include "trace_log_base.h" @@ -32,24 +34,44 @@ using namespace snort; static THREAD_LOCAL TraceLogger* g_trace_logger = nullptr; +static THREAD_LOCAL PacketConstraints* g_packet_constraints = nullptr; +static THREAD_LOCAL uint8_t g_constraints_generation = 0; -void TraceApi::thread_init(const SnortConfig* sc) +static void update_constraints(PacketConstraints* new_cs) { - if ( sc->trace_config->logger_factory ) - g_trace_logger = sc->trace_config->logger_factory->instantiate(); + if (!g_packet_constraints and !new_cs) + return; - sc->trace_config->setup_module_trace(); + bool different_constraints = g_packet_constraints and new_cs and + !(*g_packet_constraints == *new_cs); + + if ( !g_packet_constraints or !new_cs or different_constraints ) + g_constraints_generation++; + + g_packet_constraints = new_cs; +} + +void TraceApi::thread_init(const TraceConfig* trace_config) +{ + if ( trace_config->logger_factory ) + g_trace_logger = trace_config->logger_factory->instantiate(); + + update_constraints(trace_config->constraints); + trace_config->setup_module_trace(); } void TraceApi::thread_term() { + g_packet_constraints = nullptr; + delete g_trace_logger; g_trace_logger = nullptr; } -void TraceApi::thread_reinit(const SnortConfig* sc) +void TraceApi::thread_reinit(const TraceConfig* trace_config) { - sc->trace_config->setup_module_trace(); + update_constraints(trace_config->constraints); + trace_config->setup_module_trace(); } void TraceApi::log(const char* log_msg, const char* name, @@ -58,3 +80,25 @@ void TraceApi::log(const char* log_msg, const char* name, g_trace_logger->log(log_msg, name, log_level, trace_option); } +void TraceApi::filter(const Packet& p) +{ + if ( !g_packet_constraints ) + p.filtering_state.set_matched(g_constraints_generation, true); + else + { + const bool matched = p.flow + ? g_packet_constraints->flow_match(*p.flow) + : g_packet_constraints->packet_match(p); + + p.filtering_state.set_matched(g_constraints_generation, matched); + } + + if ( p.flow ) + p.flow->filtering_state = p.filtering_state; +} + +uint8_t TraceApi::get_constraints_generation() +{ + return g_constraints_generation; +} + diff --git a/src/trace/trace_api.h b/src/trace/trace_api.h index ffedd0848..074b30b6d 100644 --- a/src/trace/trace_api.h +++ b/src/trace/trace_api.h @@ -22,19 +22,25 @@ #include +#include "main/snort_types.h" + +class TraceConfig; + namespace snort { -struct SnortConfig; +struct Packet; -class TraceApi +class SO_PUBLIC TraceApi { public: - static void thread_init(const SnortConfig* sc); - static void thread_reinit(const SnortConfig* sc); + static void thread_init(const TraceConfig* tc); + static void thread_reinit(const TraceConfig* tc); static void thread_term(); static void log(const char* log_msg, const char* name, uint8_t log_level, const char* trace_option); + static void filter(const Packet& p); + static uint8_t get_constraints_generation(); }; } diff --git a/src/trace/trace_config.cc b/src/trace/trace_config.cc index 46b35f542..0fd1684fa 100644 --- a/src/trace/trace_config.cc +++ b/src/trace/trace_config.cc @@ -26,6 +26,7 @@ #include #include "framework/module.h" +#include "framework/packet_constraints.h" #include "managers/module_manager.h" #include "trace_log_base.h" @@ -44,6 +45,9 @@ TraceConfig::~TraceConfig() { delete logger_factory; logger_factory = nullptr; + + delete constraints; + constraints = nullptr; } bool TraceConfig::set_trace(const std::string& module_name, const std::string& trace_option_name, diff --git a/src/trace/trace_config.h b/src/trace/trace_config.h index 8142dd400..d229d620b 100644 --- a/src/trace/trace_config.h +++ b/src/trace/trace_config.h @@ -24,6 +24,7 @@ namespace snort { +struct PacketConstraints; class TraceLoggerFactory; } @@ -40,6 +41,7 @@ public: const std::string& trace_option_name, uint8_t trace_level); snort::TraceLoggerFactory* logger_factory = nullptr; + snort::PacketConstraints* constraints = nullptr; private: bool trace_snort_enabled = false; diff --git a/src/trace/trace_module.cc b/src/trace/trace_module.cc index a496bf408..c98b7f4f8 100644 --- a/src/trace/trace_module.cc +++ b/src/trace/trace_module.cc @@ -25,6 +25,7 @@ #include +#include "framework/packet_constraints.h" #include "main/snort_config.h" #include "managers/module_manager.h" @@ -81,10 +82,33 @@ void TraceModule::generate_params() modules_params.emplace_back(nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr); + const static Parameter trace_constraints_params[] = + { + { "ip_proto", Parameter::PT_INT, "0:255", nullptr, + "numerical IP protocol ID filter" }, + + { "src_ip", Parameter::PT_STRING, nullptr, nullptr, + "source IP address filter" }, + + { "src_port", Parameter::PT_INT, "0:65535", nullptr, + "source port filter" }, + + { "dst_ip", Parameter::PT_STRING, nullptr, nullptr, + "destination IP address filter" }, + + { "dst_port", Parameter::PT_INT, "0:65535", nullptr, + "destination port filter" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } + }; + const static Parameter trace_params[] = { { "modules", Parameter::PT_TABLE, modules_params.data(), nullptr, "modules trace option" }, + { "constraints", Parameter::PT_TABLE, trace_constraints_params, + nullptr, "trace filtering constraints" }, + { "output", Parameter::PT_ENUM, "stdout | syslog", nullptr, "output method for trace log messages" }, @@ -108,7 +132,6 @@ bool TraceModule::begin(const char* fqn, int, SnortConfig* sc) reset_configured_trace_options(); } - return true; } @@ -137,7 +160,6 @@ bool TraceModule::set(const char* fqn, Value& v, SnortConfig* sc) default: return false; } - return true; } else if ( strstr(fqn, "trace.modules.") == fqn ) @@ -149,7 +171,6 @@ bool TraceModule::set(const char* fqn, Value& v, SnortConfig* sc) for ( const auto& trace_option : trace_options ) if ( !trace_option.second ) sc->trace_config->set_trace(module_name, trace_option.first, v.get_uint8()); - return true; } else @@ -159,6 +180,47 @@ bool TraceModule::set(const char* fqn, Value& v, SnortConfig* sc) return res; } } + else if ( strstr(fqn, "trace.constraints.") == fqn ) + { + if ( !sc->trace_config->constraints ) + sc->trace_config->constraints = new snort::PacketConstraints; + + auto& cs = *sc->trace_config->constraints; + + if ( v.is("ip_proto") ) + { + cs.ip_proto = static_cast(v.get_uint8()); + cs.set_bits |= PacketConstraints::SetBits::IP_PROTO; + } + else if ( v.is("src_port") ) + { + cs.src_port = v.get_uint16(); + cs.set_bits |= PacketConstraints::SetBits::SRC_PORT; + } + else if ( v.is("dst_port") ) + { + cs.dst_port = v.get_uint16(); + cs.set_bits |= PacketConstraints::SetBits::DST_PORT; + } + else if ( v.is("src_ip") ) + { + const char* str = v.get_string(); + if ( cs.src_ip.set(str) != SFIP_SUCCESS ) + return false; + + cs.set_bits |= PacketConstraints::SetBits::SRC_IP; + } + else if ( v.is("dst_ip") ) + { + const char* str = v.get_string(); + if ( cs.dst_ip.set(str) != SFIP_SUCCESS ) + return false; + + cs.set_bits |= PacketConstraints::SetBits::DST_IP; + } + + return true; + } return false; } diff --git a/src/trace/trace_module.h b/src/trace/trace_module.h index d99f57c2d..9c369d3b6 100644 --- a/src/trace/trace_module.h +++ b/src/trace/trace_module.h @@ -56,7 +56,6 @@ private: std::vector> module_ranges; std::vector modules_help; std::map> configured_trace_options; - }; #endif // TRACE_MODULE_H