set ( _LARGEFILE_SOURCE ${ENABLE_LARGE_PCAP} )
set ( USE_STDLOG ${ENABLE_STDLOG} )
set ( USE_TSC_CLOCK ${ENABLE_TSC_CLOCK} )
+set ( NO_PROFILER ${DISABLE_SNORT_PROFILER} )
+set ( DEEP_PROFILING ${ENABLE_DEEP_PROFILING} )
+set ( NO_MEM_MGR ${DISABLE_MEMORY_MANAGER} )
if ( ENABLE_LARGE_PCAP )
set ( _FILE_OFFSET_BITS 64 )
option ( ENABLE_DEBUG "Enable debugging options (bugreports and developers only)" OFF )
option ( ENABLE_GDB "Enable gdb debugging information" ON )
option ( ENABLE_PROFILE "Enable profiling options (developers only)" OFF )
+option ( DISABLE_SNORT_PROFILER "Disable snort Profiler (developers only)" OFF )
+option ( ENABLE_DEEP_PROFILING "Enable deep profiling of snort functions (developers only)" OFF )
+option ( DISABLE_MEMORY_MANAGER "Disable snort memory manager (developers only)" OFF )
option ( ENABLE_ADDRESS_SANITIZER "enable address sanitizer support" OFF )
option ( ENABLE_THREAD_SANITIZER "enable thread sanitizer support" OFF )
option ( ENABLE_UB_SANITIZER "enable undefined behavior sanitizer support" OFF )
set(DAQ_CPPFLAGS "-I${DAQ_INCLUDE_DIR}")
endif()
+if(DISABLE_MEMORY_MANAGER)
+ set(NO_MEM_MGR_CPPFLAGS "-DNO_MEM_MGR")
+endif()
+
+if(DISABLE_SNORT_PROFILER)
+ set(NO_PROFILER_CPPFLAGS "-DNO_PROFILER")
+endif()
+
if(DNET_INCLUDE_DIR)
set(DNET_CPPFLAGS "-I${DNET_INCLUDE_DIR}")
endif()
+if(ENABLE_APPID_THIRD_PARTY)
+ set(TP_APPID_CPPFLAGS "-DENABLE_APPID_THIRD_PARTY")
+endif()
+
+if(ENABLE_DEEP_PROFILING)
+ set(DEEP_PROFILING_CPPFLAGS "-DDEEP_PROFILING")
+endif()
+
+if(ENABLE_TSC_CLOCK)
+ set(TSC_CPPFLAGS "-DUSE_TSC_CLOCK")
+endif()
+
if(FLATBUFFERS_INCLUDE_DIR)
set(FLATBUFFERS_CPPFLAGS "-I${FLATBUFFERS_INCLUDE_DIR}")
endif()
set(UUID_CPPFLAGS "-I${UUID_INCLUDE_DIR}")
endif()
-if(ENABLE_APPID_THIRD_PARTY)
- set(TP_APPID_CPPFLAGS "-DENABLE_APPID_THIRD_PARTY")
-endif()
# create & install pkgconfig file
configure_file(
/* enable tsc clock */
#cmakedefine USE_TSC_CLOCK 1
+/* disable snort profiler */
+#cmakedefine NO_PROFILER 1
+
+/* disable snort memory manager */
+#cmakedefine NO_MEM_MGR 1
+
+/* enable deep profiling */
+#cmakedefine DEEP_PROFILING 1
+
/* signal to dump stats */
#cmakedefine SIGNAL_SNORT_DUMP_STATS @SIGNAL_SNORT_DUMP_STATS@
only)
--disable-gdb disable gdb debugging information
--enable-gprof-profile enable gprof profiling options (developers only)
+ --disable-snort-profiler
+ disable snort performance profiling (cpu and memory) (developers only)
+ --enable-deep-profiling
+ enabled detailed snort performance profiling (developers only)
+ --disable-memory-manager
+ disable snort memory manager (developers only)
--disable-corefiles prevent Snort from generating core files
--enable-address-sanitizer
enable address sanitizer support
--enable-tsc-clock)
append_cache_entry ENABLE_TSC_CLOCK BOOL true
;;
+ --disable-snort-profiler)
+ append_cache_entry DISABLE_SNORT_PROFILER BOOL true
+ ;;
+ --enable-deep-profiling)
+ append_cache_entry ENABLE_DEEP_PROFILING BOOL true
+ ;;
+ --disable-memory-manager)
+ append_cache_entry DISABLE_MEMORY_MANAGER BOOL true
+ ;;
--disable-large-pcap)
append_cache_entry ENABLE_LARGE_PCAP BOOL false
;;
infodir=@infodir@
cpp_opts=DAQ LUAJIT
-cpp_opts_other=DNET FLATBUFFERS HWLOC HYPERSCAN LZMA OPENSSL PCAP PCRE UUID TP_APPID
+cpp_opts_other=DNET FLATBUFFERS HWLOC HYPERSCAN LZMA OPENSSL PCAP PCRE UUID
-TP_APPID_CPPFLAGS=@TP_APPID_CPPFLAGS@
PCAP_CPPFLAGS=@PCAP_CPPFLAGS@
LUAJIT_CPPFLAGS=@LUAJIT_CPPFLAGS@
DNET_CPPFLAGS=@DNET_CPPFLAGS@
URL: www.snort.org
Version: @VERSION@
Libs: -L${libdir}/snort
-Cflags: -I${includedir}/snort
+Cflags: -I${includedir}/snort @DEEP_PROFILING_CPPFLAGS@ @NO_MEM_MGR_CPPFLAGS@ @NO_PROFILER_CPPFLAGS@ @TP_APPID_CPPFLAGS@ @TSC_CPPFLAGS@
if ( msb_src == ip::IP4_MULTICAST )
codec_event(codec, DECODE_IP4_SRC_MULTICAST);
- if ( msb_src == ip::IP4_RESERVED || sfvar_ip_in(MulticastReservedIp, snort.ip_api.get_src()) )
- codec_event(codec, DECODE_IP4_SRC_RESERVED);
+ if ( SnortConfig::is_address_anomaly_check_enabled() )
+ {
+ if ( msb_src == ip::IP4_RESERVED || sfvar_ip_in(MulticastReservedIp, snort.ip_api.get_src()) )
+ codec_event(codec, DECODE_IP4_SRC_RESERVED);
- if ( msb_dst == ip::IP4_RESERVED || sfvar_ip_in(MulticastReservedIp, snort.ip_api.get_dst()) )
- codec_event(codec, DECODE_IP4_DST_RESERVED);
+ if ( msb_dst == ip::IP4_RESERVED || sfvar_ip_in(MulticastReservedIp, snort.ip_api.get_dst()) )
+ codec_event(codec, DECODE_IP4_DST_RESERVED);
+ }
}
/* IPv4-layer decoder rules */
}
}
- if ( sfvar_ip_in(SynToMulticastDstIp, snort.ip_api.get_dst()) )
- codec_event(codec, DECODE_SYN_TO_MULTICAST);
+ if ( SnortConfig::is_address_anomaly_check_enabled() )
+ {
+ if ( sfvar_ip_in(SynToMulticastDstIp, snort.ip_api.get_dst()) )
+ codec_event(codec, DECODE_SYN_TO_MULTICAST);
+ }
if ( (tcph->th_flags & TH_RST) )
codec_event(codec, DECODE_TCP_SYN_RST);
static inline bool latency_set(Value& v, PacketLatencyConfig& config)
{
- using std::chrono::duration_cast;
- using std::chrono::microseconds;
-
if ( v.is("max_time") )
{
long t = clock_ticks(v.get_long());
- config.max_time = duration_cast<decltype(config.max_time)>(microseconds(t));
+ config.max_time = TO_DURATION(config.max_time, t);
}
-
else if ( v.is("fastpath") )
config.fastpath = v.get_bool();
else if ( v.is("action") )
config.action =
static_cast<decltype(config.action)>(v.get_long());
-
else
return false;
static inline bool latency_set(Value& v, RuleLatencyConfig& config)
{
- using std::chrono::duration_cast;
- using std::chrono::microseconds;
- using std::chrono::milliseconds;
-
if ( v.is("max_time") )
{
long t = clock_ticks(v.get_long());
- config.max_time = duration_cast<decltype(config.max_time)>(microseconds(t));
+ config.max_time = TO_DURATION(config.max_time, t);
}
else if ( v.is("suspend") )
config.suspend = v.get_bool();
else if ( v.is("max_suspend_time") )
{
long t = clock_ticks(v.get_long());
- config.max_suspend_time = duration_cast<decltype(config.max_time)>(milliseconds(t));
+ config.max_suspend_time = TO_DURATION(config.max_time, t);
}
else if ( v.is("action") )
config.action =
static_cast<decltype(config.action)>(v.get_long());
-
else
return false;
static inline std::ostream& operator<<(std::ostream& os, const Event& e)
{
- using std::chrono::duration_cast;
- using std::chrono::microseconds;
-
os << "latency: " << pc.total_from_daq << " packet";
if ( e.fastpathed )
else
os << " timed out: ";
- os << clock_usecs(duration_cast<microseconds>(e.elapsed).count()) << " usec, ";
+ os << clock_usecs(TO_USECS(e.elapsed)) << " usec, ";
if ( e.packet->is_cooked() )
os << e.packet->get_pseudo_type();
template<typename Clock>
inline void Impl<Clock>::push()
{
- using std::chrono::duration_cast;
- auto max_time = duration_cast<typename Clock::duration>(config->max_time);
- timers.emplace_back(max_time);
+ timers.emplace_back(config->max_time);
}
template<typename Clock>
event_handler.handle(e);
}
- // FIXIT-H this is fugly and inefficient
- using std::chrono::duration_cast;
- using std::chrono::microseconds;
- elapsed = clock_usecs(duration_cast<microseconds>(timer.elapsed()).count());
+ elapsed = clock_usecs(TO_USECS(timer.elapsed()));
timers.pop_back();
return timed_out;
ALERT_AND_LOG = ALERT | LOG
};
- hr_duration max_time = 0_ticks;
+ hr_duration max_time = CLOCK_ZERO;
bool fastpath = false;
Action action = NONE;
- bool enabled() const { return max_time > 0_ticks; }
+ bool enabled() const { return max_time > CLOCK_ZERO; }
};
#endif
break;
}
- os << clock_usecs(duration_cast<microseconds>(e.elapsed).count()) << " usec, ";
+ os << clock_usecs(TO_USECS(e.elapsed)) << " usec, ";
os << e.root->otn->sigInfo.gid << ":" << e.root->otn->sigInfo.sid << ":"
<< e.root->otn->sigInfo.rev;
{ "pcre_match_limit_recursion", Parameter::PT_INT, "-1:10000", "1500",
"limit pcre stack consumption, -1 = max, 0 = off" },
+ { "enable_address_anomaly_checks", Parameter::PT_BOOL, nullptr, "false",
+ "enable check and alerting of address anomalies" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
/* *INDENT-ON* */
else if ( v.is("pcre_match_limit_recursion") )
sc->pcre_match_limit_recursion = v.get_long();
+ else if ( v.is("enable_address_anomaly_checks") )
+ sc->address_anomaly_check_enabled = v.get_bool();
+
else
return Module::set(fqn, v, sc);
uint8_t num_layers = 0;
uint8_t max_ip6_extensions = 0;
uint8_t max_ip_layers = 0;
+ bool address_anomaly_check_enabled = false;
//------------------------------------------------------
// active stuff
static bool esp_decoding()
{ return get_conf()->enable_esp; }
+ static bool is_address_anomaly_check_enabled()
+ { return get_conf()->address_anomaly_check_enabled; }
+
// mode related
static bool test_mode()
{ return get_conf()->run_flags & RUN_FLAG__TEST; }
#ifdef NO_PROFILER
using Profile = ProfileDisabled;
+using DeepProfile = ProfileDisabled;
using NoProfile = ProfileDisabled;
#else
#ifdef NO_MEM_MGR
using Profile = NoMemContext;
using NoProfile = NoMemExclude;
+#ifdef DEEP_PROFILING
+using DeepProfile = NoMemContext;
+#else
+using DeepProfile = ProfileDisabled;
+#endif
#else
using Profile = ProfileContext;
using NoProfile = ProfileExclude;
+#ifdef DEEP_PROFILING
+using DeepProfile = ProfileContext;
+#else
+using DeepProfile = ProfileDisabled;
+#endif
#endif
#endif
hr_duration time_per(hr_duration d, uint64_t v) const
{
if ( v == 0 )
- return 0_ticks;
+ return CLOCK_ZERO;
- return hr_duration(d.count() / v);
+ return hr_duration(d / v);
}
hr_duration avg_match() const
{
"total_time",
[](const View& lhs, const View& rhs)
- { return lhs.elapsed().count() >= rhs.elapsed().count(); }
+ { return TO_TICKS(lhs.elapsed()) >= TO_TICKS(rhs.elapsed()); }
},
{
"matches",
table << v.matches();
table << v.alerts();
- table << clock_usecs(duration_cast<microseconds>(v.elapsed()).count());
- table << clock_usecs(duration_cast<microseconds>(v.avg_check()).count());
- table << clock_usecs(duration_cast<microseconds>(v.avg_match()).count());
- table << clock_usecs(duration_cast<microseconds>(v.avg_no_match()).count());
+ table << clock_usecs(TO_USECS(v.elapsed()));
+ table << clock_usecs(TO_USECS(v.avg_check()));
+ table << clock_usecs(TO_USECS(v.avg_match()));
+ table << clock_usecs(TO_USECS(v.avg_no_match()));
table << v.timeouts();
table << v.suspends();
{ return stats.checks; }
hr_duration avg_check() const
- { return checks() ? hr_duration(elapsed().count() / checks()) : 0_ticks; }
+ { return checks() ? hr_duration(TO_TICKS(elapsed()) / checks()) : 0_ticks; }
double pct_of(const TimeProfilerStats& o) const
{
if ( o.elapsed <= 0_ticks )
return 0.0;
- return double(elapsed().count()) / double(o.elapsed.count()) * 100.0;
+ return double(TO_TICKS(elapsed())) / double(TO_TICKS(o.elapsed)) * 100.0;
}
double pct_caller() const
t << v.checks();
// total time
- t << clock_usecs(duration_cast<microseconds>(v.elapsed()).count());
+ t << clock_usecs(TO_USECS(v.elapsed()));
// avg/check
- t << clock_usecs(duration_cast<microseconds>(v.avg_check()).count());
+ t << clock_usecs(TO_USECS(v.avg_check()));
}
} // namespace time_stats
*/
static void FragRebuild(FragTracker* ft, Packet* p)
{
- Profile profile(fragRebuildPerfStats);
+ DeepProfile profile(fragRebuildPerfStats);
size_t offset = 0;
Packet* dpkt = DetectionEngine::set_next_packet();
void TcpStreamTracker::init_on_syn_sent(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_CLIENT);
if ( tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE) )
void TcpStreamTracker::init_on_syn_recv(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
irs = tsd.get_seg_seq();
// FIXIT-H can we really set the vars below now?
void TcpStreamTracker::init_on_synack_sent(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_SERVER);
if (tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE))
void TcpStreamTracker::init_on_synack_recv(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
iss = tsd.get_seg_ack() - 1;
irs = tsd.get_seg_seq();
void TcpStreamTracker::init_on_3whs_ack_sent(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_CLIENT);
void TcpStreamTracker::init_on_3whs_ack_recv(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
iss = tsd.get_seg_ack() - 1;
irs = tsd.get_seg_seq();
void TcpStreamTracker::init_on_data_seg_sent(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
Flow* flow = tsd.get_flow();
void TcpStreamTracker::init_on_data_seg_recv(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpNewSessPerfStats);
+ DeepProfile profile(s5TcpNewSessPerfStats);
iss = tsd.get_seg_ack();
irs = tsd.get_seg_seq();
return NO_MATCH;
{
- Profile profile(streamReassembleRuleOptionPerfStats);
+ DeepProfile profile(streamReassembleRuleOptionPerfStats);
Flow* lwssn = (Flow*)pkt->flow;
TcpSession* tcpssn = (TcpSession*)lwssn->session;
IpsOption::EvalStatus SizeOption::eval(Cursor&, Packet* pkt)
{
- Profile profile(streamSizePerfStats);
+ DeepProfile profile(streamSizePerfStats);
if ( !pkt->flow || pkt->flow->pkt_type != PktType::TCP )
return NO_MATCH;
uint32_t flags = PKT_PDU_HEAD;
assert(trs.sos.seglist.next);
- Profile profile(s5TcpBuildPacketPerfStats);
+ DeepProfile profile(s5TcpBuildPacketPerfStats);
uint32_t to_seq = trs.sos.seglist.next->seq + total;
int TcpReassembler::_flush_to_seq(
TcpReassemblerState& trs, uint32_t bytes, Packet* p, uint32_t pkt_flags)
{
- Profile profile(s5TcpFlushPerfStats);
+ DeepProfile profile(s5TcpFlushPerfStats);
DetectionEngine::onload(trs.sos.session->flow);
Packet* pdu = DetectionEngine::set_next_packet();
// because we don't wait until it is acknowledged
int32_t TcpReassembler::flush_pdu_ips(TcpReassemblerState& trs, uint32_t* flags)
{
- Profile profile(s5TcpPAFPerfStats);
+ DeepProfile profile(s5TcpPAFPerfStats);
DetectionEngine::onload(trs.sos.session->flow);
uint32_t total = 0, avail;
int32_t TcpReassembler::flush_pdu_ackd(TcpReassemblerState& trs, uint32_t* flags)
{
- Profile profile(s5TcpPAFPerfStats);
+ DeepProfile profile(s5TcpPAFPerfStats);
DetectionEngine::onload(trs.sos.session->flow);
uint32_t total = 0;
int TcpReassembler::queue_packet_for_reassembly(
TcpReassemblerState& trs, TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpInsertPerfStats);
+ DeepProfile profile(s5TcpInsertPerfStats);
int rc = STREAM_INSERT_OK;
int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd)
{
- Profile profile(s5TcpDataPerfStats);
+ DeepProfile profile(s5TcpDataPerfStats);
const tcp::TCPHdr* tcph = tsd.get_tcph();
uint32_t seq = tsd.get_seg_seq();
update_ignored_session(tsd);
set_window_scale(*talker, *listener, tsd);
- check_for_session_hijack(tsd);
+ if ( SnortConfig::is_address_anomaly_check_enabled() )
+ check_for_session_hijack(tsd);
return true;
}
return ACTION_NOTHING;
else
{
- Profile profile(s5TcpStatePerfStats);
+ DeepProfile profile(s5TcpStatePerfStats);
if ( tsm->eval(tsd, *talker, *listener) )
{
#ifdef USE_TSC_CLOCK
#include "time/tsc_clock.h"
using SnortClock = TscClock;
+#define CLOCK_ZERO 0
+#define DURA_ZERO 0
+#define TO_TICKS(t) (t)
+#define TO_USECS(t) (t)
+#define TO_DURATION(v, t) (t)
#else
#include <chrono>
using hr_clock = std::chrono::high_resolution_clock;
using SnortClock = hr_clock;
inline long clock_scale() { return 1; }
+#define CLOCK_ZERO 0_ticks
+#define DURA_ZERO Clock::duration::zero()
+#define TO_TICKS(t) (t.count())
+#define TO_USECS(t) (std::chrono::duration_cast<std::chrono::microseconds>(t).count())
+#define TO_DURATION(v, t) (std::chrono::duration_cast<decltype(v)>(std::chrono::microseconds(t)))
#endif
using hr_duration = SnortClock::duration;
using time_point = typename Clock::time_point;
Stopwatch() :
- elapsed { duration::zero() }, running { false } { }
+ elapsed { DURA_ZERO }, running { false } { }
void start()
{
{ return running; }
void reset()
- { running = false; elapsed = duration::zero(); }
+ { running = false; elapsed = DURA_ZERO; }
void cancel()
{ running = false; }
duration elapsed;
bool running;
+
+#ifdef USE_TSC_CLOCK
+ time_point start_time = CLOCK_ZERO;
+#else
time_point start_time;
+#endif
};
#endif
struct TscClock
{
- // this has to be const so we use a nice round number and scale it later
- typedef std::ratio<1, 1000000> period;
-
- typedef uint64_t rep;
- typedef std::chrono::duration<rep, period> duration;
- typedef std::chrono::time_point<TscClock> time_point;
+ typedef uint64_t duration;
+ typedef uint64_t time_point;
static const bool is_steady = true;