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());
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();
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();
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;
}
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());
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();
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());
{
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;
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());
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;
}
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);
}
{
}
-void print_pattern(const PatternMatchData*)
+void print_pattern(const PatternMatchData*, Packet*)
{
}
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*);
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)
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);
}
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());
{
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();
}
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();
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());
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());
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; i<node->num_children; i++ )
!(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;
}
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
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(),
{
#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);
}
#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;
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;
// 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
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
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 )
{
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
#ifdef DEBUG_MSGS
if (count == 0)
debug_log(detection_trace, TRACE_RULE_EVAL,
+ static_cast<snort::IpsContext*>(context)->packet,
"Fast pattern processing - no matches found\n");
#endif
unsigned i = 0;
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<snort::IpsContext*>(context)->packet,
+ "Processing pattern match #%d\n", i);
int res = match(node.user, node.tree, node.index, context, node.list);
if ( res > 0 )
// 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);
}
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 )
{
{
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++;
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);
}
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);
}
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 )
{
delete bitop;
bitop = nullptr;
}
+ filtering_state.clear();
}
void Flow::reset(bool do_cleanup)
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;
FlowState flow_state;
+ FilteringState filtering_state;
+
private:
void clean();
};
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
module.h
mpse.h
mpse_batch.h
+ packet_constraints.h
parameter.h
range.h
so_rule.h
data_bus.cc
inspector.cc
ips_option.cc
+ packet_constraints.cc
parameter.cc
module.cc
mpse.cc
SOURCES
range.cc
)
+
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)
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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 <selysenk@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "packet_constraints.h"
+
+#include "protocols/packet.h"
+
+#include <cstring>
+
+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 <catch/snort_catch.h>
+
+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
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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 <selysenk@cisco.com>
+
+#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
+
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);
}
{
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 )
{
#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();
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
}
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)
{
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 );
{
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;
}
}
// 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);
{
InspectorManager::thread_reinit(sc);
ActionManager::thread_reinit(sc);
- TraceApi::thread_reinit(sc);
+ TraceApi::thread_reinit(sc->trace_config);
}
void Analyzer::term()
// 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);
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);
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' );
}
#include <cstdarg>
+#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
using trace_func = void(const char*, TraceLevel, const char*, const char*, va_list);
template <trace_func>
-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 <trace_func trace_vprintf = snort::trace_vprintf>
-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 <trace_func>
-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 <trace_func trace_vprintf = snort::trace_vprintf>
-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 <trace_func>
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 <trace_func trace_vprintf = snort::trace_vprintf>
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 <trace_func>
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 <trace_func trace_vprintf = snort::trace_vprintf>
-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 <trace_func trace_vprintf = snort::trace_vprintf>
-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<trace_vprintf>(log_level, trace, trace_option_id, "%s", msg);
+ trace_printf<trace_vprintf>(log_level, trace, trace_option_id, p,
+ "%s", msg);
}
template <trace_func trace_vprintf = snort::trace_vprintf>
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_vprintf>(trace, trace_option_id, "%s", msg);
+ trace_printf<trace_vprintf>(trace, trace_option_id, p, "%s", msg);
}
template <trace_func trace_vprintf = snort::trace_vprintf>
-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<trace_vprintf>(log_level, trace, "%s", msg);
+ trace_printf<trace_vprintf>(log_level, trace, p, "%s", msg);
}
template <trace_func trace_vprintf = snort::trace_vprintf>
-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_vprintf>(trace, "%s", msg);
+ trace_printf<trace_vprintf>(trace, p, "%s", msg);
}
#define trace_print trace_print<snort::trace_vprintf>
#endif
#endif
+
{
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);
}
}
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:
return false;
}
-void PacketTracer::set_constraints(const PTSessionConstraints* constraints)
+void PacketTracer::set_constraints(const PacketConstraints* constraints)
{
if (!s_pkt_trace)
return;
}
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);
}
}
-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<uint8_t>(info.protocol));
+ sipstr, constraints.src_port, dipstr, constraints.dst_port,
+ static_cast<uint8_t>(constraints.ip_proto));
shell_enabled = true;
#include <cstring>
#include <vector>
+#include "framework/packet_constraints.h"
#include "main/snort_types.h"
#include "main/thread.h"
#include "protocols/ipv6.h"
// 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;
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();
bool active = false;
char debug_session[PT_DEBUG_SESSION_ID_SIZE];
- PTSessionConstraints info;
+ PacketConstraints constraints;
// static functions
template<typename T = PacketTracer> static void _thread_init();
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();
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)
{
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;
}
user_ips_policy_id = 0;
user_network_policy_id = 0;
vlan_idx = 0;
+ filtering_state.clear();
}
void Packet::release_helpers()
// 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;
// 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<uint16_t>(codec_data.next_prot_id), pkt, codec_data.lyr_len);
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<uint16_t>(prev_prot_id), pkt, (unsigned long)codec_data.lyr_len);
(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;
}
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;
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;
&& (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;
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;
}
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;
}
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;
}
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;
}
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;
}
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
}
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);
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,
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
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) &&
{
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)
{
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))
{
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);
}
}
}
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);
}
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;
}
{
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
*/
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:
{
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);
}
}
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;
{
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);
///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);
*/
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
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
*/
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++;
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);
/*
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;
/* 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);
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");
}
/*
*/
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"
/*
* 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;
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;
}
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)
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
#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()),
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;
#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",
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),
*/
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
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;
/*
* 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);
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);
/*
* zero size frag...
*/
- debug_log(stream_ip_trace, "[..] Zero size frag!\n");
+ debug_log(stream_ip_trace, p, "[..] Zero size frag!\n");
EventAnomZeroFrag(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);
/*
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);
*/
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);
/*
/*
* teardrop attack...
*/
- debug_log(stream_ip_trace, "[..] Teardrop attack!\n");
+ debug_log(stream_ip_trace, p, "[..] Teardrop attack!\n");
EventAttackTeardrop(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)
/*
* 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;
}
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;
*/
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);
}
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;
*/
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;
/*
* teardrop attack...
*/
- debug_log(stream_ip_trace, "[..] Teardrop attack!\n");
+ debug_log(stream_ip_trace, p, "[..] Teardrop attack!\n");
EventAttackTeardrop(fe);
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
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;
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;
}
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;
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)
/*
* 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++;
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;
(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);
}
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;
}
/* 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());
/*
* 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);
/*
* 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);
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,
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",
*/
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);
*/
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;
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);
*/
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;
{
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"));
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);
}
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,
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);
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);
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() )
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)
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"
#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"
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,
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;
+}
+
#include <cstdint>
+#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();
};
}
#include <cstring>
#include "framework/module.h"
+#include "framework/packet_constraints.h"
#include "managers/module_manager.h"
#include "trace_log_base.h"
{
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,
namespace snort
{
+struct PacketConstraints;
class TraceLoggerFactory;
}
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;
#include <syslog.h>
+#include "framework/packet_constraints.h"
#include "main/snort_config.h"
#include "managers/module_manager.h"
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" },
reset_configured_trace_options();
}
-
return true;
}
default:
return false;
}
-
return true;
}
else if ( strstr(fqn, "trace.modules.") == fqn )
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
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<IpProtocol>(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;
}
std::vector<std::vector<snort::Parameter>> module_ranges;
std::vector<std::string> modules_help;
std::map<std::string, std::map<std::string, bool>> configured_trace_options;
-
};
#endif // TRACE_MODULE_H