src_port - match all packets with a flow that has this source port
dst_ip - match all packets with a flow that has this server IP address (passed as a string)
dst_port - match all packets with a flow that has this destination port
+ match - boolean flag to enable/disable whether constraints will ever match (enabled by default)
The following lines placed in snort.lua will enable all trace messages for
detection filtered by ip_proto, dst_ip, src_port and dst_port:
}
}
+To create constraints that will never successfully match, set the *match*
+parameter to 'false'. This is useful for situations where one is relying on
+external packet filtering from the DAQ module, or for preventing all trace
+messages in the context of a packet. The following is an example of such
+configuration:
+
+ trace =
+ {
+ modules =
+ {
+ snort = { all = 1 }
+ },
+ constraints =
+ {
+ match = false
+ }
+ }
+
==== Trace module - configuring trace output method
There is a capability to configure the output method for trace messages.
namespace {
-inline bool match(const snort::PacketConstraints& cs, const snort::SfIp& sip,
- const snort::SfIp& dip, uint16_t sport, uint16_t dport)
+inline bool match_constraints(const snort::PacketConstraints& cs,
+ const snort::SfIp& sip, const snort::SfIp& dip, uint16_t sport,
+ uint16_t dport)
{
using SetBits = snort::PacketConstraints::SetBits;
bool PacketConstraints::packet_match(const Packet& p) const
{
+ if ( !match )
+ return false;
+
if ( !p.has_ip() )
return false;
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);
+ return match_constraints(*this, sip, dip, sp, dp) or
+ match_constraints(*this, dip, sip, dp, sp);
}
bool PacketConstraints::flow_match(const Flow& f) const
{
+ if ( !match )
+ return false;
+
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);
+ return match_constraints(*this, f.client_ip, f.server_ip, f.client_port,
+ f.server_port);
}
#ifdef UNIT_TEST
cs.src_ip = sip;
cs.dst_ip = dip;
- CHECK( match(cs, sip, dip, sport, dport) );
+ CHECK( match_constraints(cs, sip, dip, sport, dport) );
}
SECTION("backwards")
cs.src_ip = sip;
cs.dst_ip = dip;
- CHECK( !match(cs, dip, sip, dport, sport) );
+ CHECK( !match_constraints(cs, dip, sip, dport, sport) );
}
SECTION("any ip")
cs.src_port = sport;
cs.dst_port = dport;
- CHECK( match(cs, sip, dip, sport, dport) );
+ CHECK( match_constraints(cs, sip, dip, sport, dport) );
}
SECTION("any port")
cs.src_ip = sip;
cs.dst_ip = dip;
- CHECK( match(cs, sip, dip, sport, dport) );
+ CHECK( match_constraints(cs, sip, dip, sport, dport) );
}
SECTION("any src")
cs.dst_port = dport;
cs.dst_ip = dip;
- CHECK( match(cs, sip, dip, sport, dport) );
+ CHECK( match_constraints(cs, sip, dip, sport, dport) );
}
-
}
#endif
snort::SfIp dst_ip;
uint8_t set_bits = 0;
+
+ bool match = true;
};
} // namespace snort
To create specific TraceLogger/TraceLoggerFactory pair just inherit base classes placed
into "trace_log_base.h" and init TraceConfig with a new factory during configuration.
+* Disabling packet constraints matching
+
+ Constraints matching can be disabled by setting "trace.constraints.match = false" during
+ configuration. This is effectively saying all packets don't pass the trace filter. It may be
+ useful in case of using external packet filtering, such as filtering by the DAQ, or to block
+ printing for all trace messages in the context of a packet.
+
void TraceApi::filter(const Packet& p)
{
- if ( !g_packet_constraints )
+
+ if ( p.pkth->flags & DAQ_PKT_FLAG_DEBUG_ENABLED )
p.filtering_state.set_matched(g_constraints_generation, true);
else
{
- const bool matched = p.flow
+ bool matched;
+ if ( !g_packet_constraints )
+ matched = true;
+ else
+ {
+ 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);
}
#include <syslog.h>
+#include "framework/packet_constraints.h"
#include "main/snort_config.h"
#include "managers/module_manager.h"
{ "dst_port", Parameter::PT_INT, "0:65535", nullptr,
"destination port filter" },
+ { "match", Parameter::PT_BOOL, nullptr, "true",
+ "use constraints to filter traces" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
}
+ trace_parser->finalize_constraints();
+
delete trace_parser;
trace_parser = nullptr;
}
#include "trace_parser.h"
#include "framework/module.h"
-#include "framework/packet_constraints.h"
#include "managers/module_manager.h"
#include "trace_config.h"
bool TraceParser::set_constraints(const Value& val)
{
- if ( !trace_config->constraints )
- trace_config->constraints = new PacketConstraints;
-
- auto& cs = *trace_config->constraints;
-
if ( val.is("ip_proto") )
{
- cs.ip_proto = static_cast<IpProtocol>(val.get_uint8());
- cs.set_bits |= PacketConstraints::SetBits::IP_PROTO;
+ parsed_constraints.ip_proto = static_cast<IpProtocol>(val.get_uint8());
+ parsed_constraints.set_bits |= PacketConstraints::SetBits::IP_PROTO;
}
else if ( val.is("src_port") )
{
- cs.src_port = val.get_uint16();
- cs.set_bits |= PacketConstraints::SetBits::SRC_PORT;
+ parsed_constraints.src_port = val.get_uint16();
+ parsed_constraints.set_bits |= PacketConstraints::SetBits::SRC_PORT;
}
else if ( val.is("dst_port") )
{
- cs.dst_port = val.get_uint16();
- cs.set_bits |= PacketConstraints::SetBits::DST_PORT;
+ parsed_constraints.dst_port = val.get_uint16();
+ parsed_constraints.set_bits |= PacketConstraints::SetBits::DST_PORT;
}
else if ( val.is("src_ip") )
{
const char* str = val.get_string();
- if ( cs.src_ip.set(str) != SFIP_SUCCESS )
+ if ( parsed_constraints.src_ip.set(str) != SFIP_SUCCESS )
return false;
- cs.set_bits |= PacketConstraints::SetBits::SRC_IP;
+ parsed_constraints.set_bits |= PacketConstraints::SetBits::SRC_IP;
}
else if ( val.is("dst_ip") )
{
const char* str = val.get_string();
- if ( cs.dst_ip.set(str) != SFIP_SUCCESS )
+ if ( parsed_constraints.dst_ip.set(str) != SFIP_SUCCESS )
return false;
- cs.set_bits |= PacketConstraints::SetBits::DST_IP;
+ parsed_constraints.set_bits |= PacketConstraints::SetBits::DST_IP;
}
+ else if ( val.is("match") )
+ parsed_constraints.match = val.get_bool();
else
return false;
return true;
}
+void TraceParser::finalize_constraints()
+{
+ if ( !parsed_constraints.match or parsed_constraints.set_bits )
+ trace_config->constraints = new PacketConstraints(parsed_constraints);
+}
+
void TraceParser::clear_traces()
{ trace_config->clear_traces(); }
#include <map>
#include <string>
+#include "framework/packet_constraints.h"
+
namespace snort
{
class Module;
bool set_traces(const std::string& module_name, const snort::Value& val);
bool set_constraints(const snort::Value& val);
+ void finalize_constraints();
void clear_traces();
void clear_constraints();
private:
TraceConfig* trace_config = nullptr;
+ snort::PacketConstraints parsed_constraints;
static std::map<std::string, std::map<std::string, bool>> s_configured_trace_options;
};
#include <lua.hpp>
#include "framework/module.h"
+#include "framework/packet_constraints.h"
#include "log/messages.h"
#include "main/analyzer_command.h"
#include "main/snort_config.h"
lua_pushnil(L);
while ( lua_next(L, 1) )
{
- const char* root_tbl_name = luaL_checkstring(L, -2);
- const Parameter* root_tbl_param = Parameter::find(params_tree, root_tbl_name);
+ const char* root_element_key = luaL_checkstring(L, -2);
+ const Parameter* root_parameter = Parameter::find(params_tree, root_element_key);
- if ( !lua_istable(L, -1) or !root_tbl_param )
+ if ( !lua_istable(L, -1) or !root_parameter )
{
- LogMessage("== invalid table is provided: %s\n", root_tbl_name);
+ LogMessage("== invalid table is provided: %s\n", root_element_key);
parse_err = true;
lua_pop(L, 1);
continue;
}
// "modules" table traversal
- if ( !strcmp(root_tbl_name, params_tree[0].name) )
+ else if ( !strcmp(root_element_key, params_tree[0].name) )
{
set_traces = true;
trace_parser.clear_traces();
- const Parameter* modules_param = (const Parameter*)root_tbl_param->range;
+ const Parameter* modules_param = (const Parameter*)root_parameter->range;
int modules_tbl_idx = lua_gettop(L);
lua_pushnil(L);
if ( !lua_istable(L, -1) or !module_param )
{
- LogMessage("== invalid table is provided: %s.%s\n", root_tbl_name,
+ LogMessage("== invalid table is provided: %s.%s\n", root_element_key,
module_name);
parse_err = true;
!trace_parser.set_traces(module_name, val) )
{
LogMessage("== invalid trace value is provided: %s.%s.%s = %s\n",
- root_tbl_name, module_name, val_name, val.get_as_string());
+ root_element_key, module_name, val_name, val.get_as_string());
parse_err = true;
}
}
}
// "constraints" table traversal
- else if ( !strcmp(root_tbl_name, params_tree[1].name) )
+ else if ( !strcmp(root_element_key, params_tree[1].name) )
{
set_constraints = true;
trace_parser.clear_constraints();
- const Parameter* constraints_param = (const Parameter*)root_tbl_param->range;
+ const Parameter* constraints_param = (const Parameter*)root_parameter->range;
int constraints_tbl_idx = lua_gettop(L);
lua_pushnil(L);
if ( lua_isnumber(L, -1) )
val.set((double)lua_tointeger(L, -1));
+ else if ( lua_isboolean(L, -1) )
+ val.set(bool(lua_toboolean(L, -1)));
else
val.set(luaL_checkstring(L, -1));
!trace_parser.set_constraints(val) )
{
LogMessage("== invalid constraints value is provided: %s.%s = %s\n",
- root_tbl_name, val_name, val.get_as_string());
+ root_element_key, val_name, val.get_as_string());
parse_err = true;
}
trace_parser.clear_constraints();
}
+ if ( set_constraints )
+ trace_parser.finalize_constraints();
+
main_broadcast_command(new TraceSwap(
trace_parser.get_trace_config(), set_traces, set_constraints),
true);
{
// Create an empty overlay TraceConfig
// It will be set in a SnortConfig during TraceSwap execution and owned by it after
- main_broadcast_command(new TraceSwap(new TraceConfig()), true);
+ main_broadcast_command(new TraceSwap(new TraceConfig), true);
return 0;
}