#include "parameter.h"
#include "utils/stats.h"
-static const Parameter null_params[] =
+
+static const Parameter defaults[] =
{
+ { "trace", Parameter::PT_INT, nullptr, nullptr,
+ "mask for enabling debug traces in module" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
{
name = s;
help = h;
- params = null_params;
+ params = &defaults[(sizeof(defaults) / sizeof(Parameter)) - 1];
+ default_params = params;
list = false;
num_counts = -1;
}
Module::Module(const char* s, const char* h)
{ init(s, h); }
-Module::Module(const char* s, const char* h, const Parameter* p, bool is_list)
+Module::Module(const char* s, const char* h, const Parameter* p, bool is_list, Trace* t)
{
init(s, h);
- params = p;
list = is_list;
+ trace = t;
+ params = p;
+
+ // FIXIT-L: This will not be valid after adding more default options
+ if ( t )
+ default_params = defaults;
+}
+
+bool Module::set(const char*, Value& v, SnortConfig*)
+{
+ if ( v.is("trace") )
+ {
+ if ( trace )
+ *trace = v.get_long();
+ }
+ else
+ return false;
+ return true;
}
void Module::sum_stats()
#include <string>
#include <vector>
+#include "main/snort_debug.h"
#include "main/snort_types.h"
#include "framework/value.h"
#include "framework/parameter.h"
#include "framework/counts.h"
+#include "main/snort_debug.h"
#include "utils/stats.h"
using LuaCFunction = int(*)(struct lua_State*);
virtual bool end(const char*, int, SnortConfig*)
{ return true; }
- virtual bool set(const char*, Value&, SnortConfig*)
- { return false; }
+ virtual bool set(const char*, Value&, SnortConfig*);
// ips events:
virtual unsigned get_gid() const
const Parameter* get_parameters() const
{ return params; }
+ const Parameter* get_default_parameters() const
+ { return default_params; }
+
virtual const Command* get_commands() const
{ return nullptr; }
protected:
Module(const char* name, const char* help);
- Module(const char* name, const char* help, const Parameter*, bool is_list = false);
+ Module(const char* name, const char* help, const Parameter*,
+ bool is_list = false, Trace* = nullptr);
private:
friend class ModuleManager;
const char* help;
const Parameter* params;
+ const Parameter* default_params = nullptr;
bool list;
std::vector<PegCount> counts;
int num_counts;
+ Trace* trace;
};
#endif
return deflt ? deflt : "";
}
+const Parameter* Parameter::find(const Parameter* p, const Parameter* d, const char* s)
+{
+ auto ret = find(p, s);
+
+ if ( !ret )
+ ret = find(d, s);
+
+ return ret;
+}
+
const Parameter* Parameter::find(const Parameter* p, const char* s)
{
+ if ( !p )
+ return nullptr;
+
while ( p->name )
{
if ( !strcmp(p->name, s) || p->is_wild_card() )
double get_number() const;
const char* get_string() const;
+ static const Parameter* find(const Parameter*, const Parameter*, const char*);
static const Parameter* find(const Parameter*, const char*);
// 0-based; -1 if not found; list is | delimited
#include "snort_types.h"
#include "snort_config.h"
+#include "utils/safec.h"
bool Debug::init = false;
uint64_t Debug::mask = 0;
va_end(ap);
}
+
+bool trace_enabled(Trace mask, Trace flags)
+{ return mask & flags; }
+
+bool trace_enabled(Trace mask)
+{ return mask; }
+
+template <int (output)(const char*, FILE*)>
+static inline void trace_vprintf(const char* name, Trace mask, const char* file, int line,
+ Trace flags, const char* fmt, va_list ap)
+{
+ if ( !trace_enabled(mask, flags) )
+ return;
+
+ char buf[STD_BUF];
+ int buf_len = sizeof(buf);
+ char* buf_ptr = buf;
+
+ int size = snprintf(buf, buf_len, "%s: ", name);
+ if ( size > 0 && size < buf_len )
+ {
+ buf_ptr += size;
+ buf_len -= size;
+ }
+
+ if ( file )
+ {
+ size = snprintf(buf_ptr, buf_len, "%s:%d: ", file, line);
+ if ( size > 0 && size < buf_len )
+ {
+ buf_ptr += size;
+ buf_len -= size;
+ }
+ }
+
+ vsnprintf(buf_ptr, buf_len, fmt, ap);
+
+ if ( snort_conf and SnortConfig::log_syslog() )
+ syslog(LOG_DAEMON | LOG_DEBUG, "%s", buf);
+ else
+ output(buf, stdout);
+}
+
+void trace_vprintf(const char* name, Trace mask, const char* file, int line,
+ Trace flags, const char* fmt, va_list ap)
+{
+ trace_vprintf<fputs>(name, mask, file, line, flags, fmt, ap);
+}
+
+#ifdef UNIT_TEST
+#include <catch/catch.hpp>
+
+//stringify the expansion of the macro
+#define sx(code) sm(code)
+
+//stringify the macro
+#define sm(code) #code
+
+#define TRACE_SECTION_1 0x0000000000000001
+#define TRACE_SECTION_2 0x0000000000000002
+#define TRACE_SECTION_3 0x0000000000000004
+#define TRACE_SECTION_4 0x0000000000000008
+
+struct TestCase
+{
+ const char* test;
+ const char* expected;
+};
+
+static char testing_dump[STD_BUF];
+static int test_fputs(const char* str, FILE*)
+{
+ memcpy_s(testing_dump, STD_BUF, str, STD_BUF);
+
+ return 0;
+}
+
+TEST_CASE("macros", "[trace]")
+{
+ const Trace my_flags = TRACE_SECTION_1 | TRACE_SECTION_2 | TRACE_SECTION_3;
+
+ TestCase cases[] =
+ {
+ {
+ sx(trace_log(testing, "my message")),
+ "trace_print<trace_vprintf>(\"testing\", testing_trace, nullptr, 0, \"my message\")"
+ },
+ {
+ sx(trace_log(testing, my_flags, "my message")),
+ "trace_print<trace_vprintf>(\"testing\", testing_trace, nullptr, 0, my_flags, \"my message\")"
+ },
+ {
+ sx(trace_logf(testing, "%s %s", "my", "message")),
+ "trace_printf<trace_vprintf>(\"testing\", testing_trace, nullptr, 0, \"%s %s\", \"my\", \"message\")"
+ },
+ {
+ sx(trace_logf(testing, my_flags, "%s %s", "my", "message")),
+ "trace_printf<trace_vprintf>(\"testing\", testing_trace, nullptr, 0, my_flags, \"%s %s\", \"my\", \"message\")"
+ },
+ {
+ sx(trace_debug(testing, "my message")), "trace_print<trace_vprintf>(\"testing\", testing_trace, " sx(__FILE__) ", " sx(__LINE__) ", \"my message\")"
+ },
+ {
+ sx(trace_debug(testing, my_flags, "my message")), "trace_print<trace_vprintf>(\"testing\", testing_trace, " sx(__FILE__) ", " sx(__LINE__) ", my_flags, \"my message\")"
+ },
+ {
+ sx(trace_debugf(testing, "%s %s", "my", "message")), "trace_printf<trace_vprintf>(\"testing\", testing_trace, " sx(__FILE__) ", " sx(__LINE__) ", \"%s %s\", \"my\", \"message\")"
+ },
+ {
+ sx(trace_debugf(testing, my_flags, "%s %s", "my", "message")), "trace_printf<trace_vprintf>(\"testing\", testing_trace, " sx(__FILE__) ", " sx(__LINE__) ", my_flags, \"%s %s\", \"my\", \"message\")"
+ }
+ };
+
+ CHECK( !strcmp(cases[0].expected, cases[0].test) );
+ CHECK( !strcmp(cases[1].expected, cases[1].test) );
+ CHECK( !strcmp(cases[2].expected, cases[2].test) );
+ CHECK( !strcmp(cases[3].expected, cases[3].test) );
+ CHECK( !strcmp(cases[4].expected, cases[4].test) );
+ CHECK( !strcmp(cases[5].expected, cases[5].test) );
+ CHECK( !strcmp(cases[6].expected, cases[6].test) );
+ CHECK( !strcmp(cases[7].expected, cases[7].test) );
+}
+
+#undef trace_print
+#undef trace_printf
+
+//These templates expand to replace the default expansion of trace_vprintf.
+//This custom expansion replaces output (expands to fputs in snort_debug.h macros)
+//with test_fputs for capturing what would be passed to the console.
+#define trace_print trace_print<trace_vprintf<test_fputs>>
+#define trace_printf trace_printf<trace_vprintf<test_fputs>>
+
+TEST_CASE("trace_log", "[trace]")
+{
+ Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
+
+ testing_dump[0] = '\0';
+ trace_log(testing, "my message");
+ CHECK( !strcmp(testing_dump, "testing: my message") );
+
+ testing_dump[0] = '\0';
+ trace_log(testing, TRACE_SECTION_1, "my masked message");
+ CHECK( testing_dump[0] == '\0' );
+
+ testing_dump[0] = '\0';
+ trace_log(testing, TRACE_SECTION_2, "my other masked message");
+ CHECK( !strcmp(testing_dump, "testing: my other masked message") );
+}
+
+TEST_CASE("trace_logf", "[trace]")
+{
+ Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
+
+ testing_dump[0] = '\0';
+ trace_logf(testing, "%s %s", "my", "message");
+ CHECK( !strcmp(testing_dump, "testing: my message") );
+
+ testing_dump[0] = '\0';
+ trace_logf(testing, TRACE_SECTION_1, "%s %s %s", "my", "masked", "message");
+ CHECK( testing_dump[0] == '\0' );
+
+ testing_dump[0] = '\0';
+ trace_logf(testing, TRACE_SECTION_2, "%s %s %s %s", "my", "other", "masked", "message");
+ CHECK( !strcmp(testing_dump, "testing: my other masked message") );
+}
+
+TEST_CASE("trace_debug", "[trace]")
+{
+ Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
+
+ testing_dump[0] = '\0';
+ trace_debug(testing, "my message"); CHECK( !strcmp(testing_dump, "testing: " __FILE__ ":" sx(__LINE__) ": my message") );
+
+ testing_dump[0] = '\0';
+ trace_debug(testing, TRACE_SECTION_1, "my masked message");
+ CHECK( testing_dump[0] == '\0' );
+
+ testing_dump[0] = '\0';
+ trace_debug(testing, TRACE_SECTION_2, "my other masked message"); CHECK( !strcmp(testing_dump, "testing: " __FILE__ ":" sx(__LINE__) ": my other masked message") );
+}
+
+TEST_CASE("trace_debugf", "[trace]")
+{
+ Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
+
+ testing_dump[0] = '\0';
+ trace_debugf(testing, "%s %s", "my", "message"); CHECK( !strcmp(testing_dump, "testing: " __FILE__ ":" sx(__LINE__) ": my message") );
+
+ testing_dump[0] = '\0';
+ trace_debugf(testing, TRACE_SECTION_1, "%s %s %s", "my", "masked", "message");
+ CHECK( testing_dump[0] == '\0' );
+
+ testing_dump[0] = '\0';
+ trace_debugf(testing, TRACE_SECTION_2, "%s %s %s %s", "my", "other", "masked", "message"); CHECK( !strcmp(testing_dump, "testing: " __FILE__ ":" sx(__LINE__) ": my other masked message") );
+}
+
+TEST_CASE("safety", "[trace]")
+{
+ Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
+
+ char* message = new char[STD_BUF + 1];
+
+ for( int i = 0; i < STD_BUF; i++ )
+ message[i] = 'A';
+ message[STD_BUF] = '\0';
+
+ testing_dump[0] = '\0';
+ trace_log(testing, message);
+ CHECK( strlen(testing_dump) == STD_BUF - 1 );
+
+ delete message;
+}
+
+#endif
#include "config.h"
#endif
+#include <cstdarg>
+#include <cstdio>
#include <stdint.h>
#include <ctype.h>
#define DEBUG_DCE_UDP 0x1000000000000000LL
+typedef uint64_t Trace;
+
+bool trace_enabled(Trace mask);
+bool trace_enabled(Trace mask, Trace flags);
+
+#define TRACE_NAME(name) name##_trace
+
#ifdef DEBUG_MSGS
+void trace_vprintf(const char* name, Trace mask, const char* file, int line,
+ Trace flags, const char* fmt, va_list);
+
+template <void (trace_vprintf)(const char*, Trace, const char*, int, Trace, const char*, va_list)>
+static inline void trace_printf(const char* name, Trace mask, const char* file, int line,
+ Trace flags, const char* fmt, ...) __attribute__((format (printf, 6, 7)));
+
+template <void (trace_vprintf)(const char*, Trace, const char*, int, Trace, const char*, va_list) = trace_vprintf>
+static inline void trace_printf(const char* name, Trace mask, const char* file, int line,
+ Trace flags, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ trace_vprintf(name, mask, file, line, flags, fmt, ap);
+
+ va_end(ap);
+}
+
+template <void (trace_vprintf)(const char*, Trace, const char*, int, Trace, const char*, va_list)>
+static inline void trace_printf(const char* name, Trace mask, const char* file,
+ int line, const char* fmt, ...) __attribute__((format (printf, 5, 6)));
+
+template <void (trace_vprintf)(const char*, Trace, const char*, int, Trace, const char*, va_list) = trace_vprintf>
+static inline void trace_printf(const char* name, Trace mask, const char* file,
+ int line, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ trace_vprintf(name, mask, file, line, UINT64_MAX, fmt, ap);
+
+ va_end(ap);
+}
+
+template <void (trace_vprintf)(const char*, Trace, const char*, int, Trace, const char*, va_list) = trace_vprintf>
+static inline void trace_print(const char* name, Trace mask, const char* file,
+ int line, const char* msg)
+{
+ trace_printf<trace_vprintf>(name, mask, file, line, UINT64_MAX, "%s", msg);
+}
+
+template <void (trace_vprintf)(const char*, Trace, const char*, int, Trace, const char*, va_list) = trace_vprintf>
+static inline void trace_print(const char* name, Trace mask, const char* file,
+ int line, Trace flags, const char* msg)
+{
+ trace_printf<trace_vprintf>(name, mask, file, line, flags, "%s", msg);
+}
+
+#define trace_print trace_print<trace_vprintf>
+#define trace_printf trace_printf<trace_vprintf>
+
+#define trace_log(tracer, ...) \
+ trace_print(#tracer, tracer##_trace, nullptr, 0, __VA_ARGS__)
+
+#define trace_logf(tracer, ...) \
+ trace_printf(#tracer, tracer##_trace, nullptr, 0, __VA_ARGS__)
+
+#define trace_debug(tracer, ...) \
+ trace_print(#tracer, tracer##_trace, __FILE__, __LINE__, __VA_ARGS__)
+
+#define trace_debugf(tracer, ...) \
+ trace_printf(#tracer, tracer##_trace, __FILE__, __LINE__, __VA_ARGS__)
+
class SO_PUBLIC Debug
{
public:
#define DEBUG_WRAP(code) code
#else
+#define trace_log(tracer, ...)
+#define trace_logf(tracer, ...)
+#define trace_debug(tracer, ...)
+#define trace_debugf(tracer, ...)
+
#define DebugFormat(dbg, fmt, ...)
#define DebugFormatNoFileLine(dbg, fmt, ...)
#define DebugMessage(dbg, msg)
dump_field_lua(fqn, p, true);
}
}
- while ( p->name )
+ while ( p && p->name )
dump_field(key, pfx, p++, list);
}
string s = fqn;
const Parameter* p = get_params(s, mod->get_parameters());
+ if ( !p )
+ p = get_params(s, mod->get_default_parameters());
+
if ( !p )
{
// FIXIT-L handle things like x = { 1 } where x is a table not a
std::string sfqn = s;
p = get_params(sfqn, m->get_parameters(), idx);
+ if ( !p )
+ p = get_params(sfqn, m->get_default_parameters(), idx);
+
if ( !p )
{
ParseError("can't find %s", s);
cout << endl << "Type: " << mod_type(p->api) << endl;
- if ( const Parameter* params = m->get_parameters() )
+ const Parameter* params = m->get_parameters();
+ const Parameter* def_params = m->get_default_parameters();
+
+ if ( ( params and params->type < Parameter::PT_MAX ) ||
+ ( def_params and params->type < Parameter::PT_MAX ) )
{
- if ( params->type < Parameter::PT_MAX )
- {
- cout << endl << "Configuration: " << endl << endl;
- show_configs(name, true);
- }
+ cout << endl << "Configuration: " << endl << endl;
+ show_configs(name, true);
}
if ( m->get_commands() )
{
dump_field(s, pfx, m->params);
}
+
+ s = m->name;
+
+ if ( m->default_params )
+ dump_table(s, pfx, m->default_params);
+
if ( !pfx )
cout << endl;
key = k.c_str();
Module* m = get_snort_module();
- const Parameter* p = m->get_parameters();
- p = Parameter::find(p, key);
+ const Parameter* p = Parameter::find(m->get_parameters(), key);
if ( !p )
ParseError("unknown option %s %s", key, val);
{
ft->frag_flags |= FRAG_GOT_FIRST;
- DebugMessage(DEBUG_FRAG, "Got first frag\n");
+ trace_log(stream_ip, "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)
{
- DebugMessage(DEBUG_FRAG, "Got last frag again!\n");
+ trace_log(stream_ip, "Got last frag again!\n");
switch (ft->frag_policy)
{
case FRAG_POLICY_BSD:
{
ft->calculated_size = endOfThisFrag;
- DebugFormat(DEBUG_FRAG, "Got last frag, Bytes: %u, "
+ trace_logf(stream_ip, "Got last frag, Bytes: %u, "
"Calculated size: %u\n",
ft->frag_bytes,
ft->calculated_size);
ft->frag_flags |= FRAG_NO_BSD_VULN;
}
- DebugFormat(DEBUG_FRAG, "Frag Status: %s:%s\n",
+ trace_logf(stream_ip, "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)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"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)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"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);
//drop this and all following fragments
if (ft && !(ft->frag_flags & FRAG_DROP_FRAGMENTS))
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"Frag: Will drop all fragments on this packet\n");
ft->frag_flags |= FRAG_DROP_FRAGMENTS;
}
*/
static inline int FragIsComplete(FragTracker* ft)
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[$] Checking completion criteria\n");
/*
if ((ft->frag_flags & FRAG_GOT_FIRST) &&
(ft->frag_flags & FRAG_GOT_LAST))
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
" Got First and Last frags\n");
/*
*/
if (ft->frag_bytes == ft->calculated_size)
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
" [!] frag_bytes = calculated_size!\n");
ip_stats.trackers_completed++;
if (ft->frag_bytes > ft->calculated_size)
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
" [!] frag_bytes > calculated_size!\n");
ip_stats.trackers_completed++;
return 1;
}
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
" Calc size (%u) != frag bytes (%u)\n",
ft->calculated_size, ft->frag_bytes);
return 0;
}
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
" Missing First or Last frags (frag_flags: 0x%X)\n",
ft->frag_flags);
/* 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;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"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;
+ trace_log(stream_ip,
+ "[^^] Walking fraglist:\n");
DebugMessage(DEBUG_FRAG,
"[^^] Walking fraglist:\n");
}
*/
for (frag = ft->fraglist; frag; frag = frag->next)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
" frag: %p\n"
" frag->data: %p\n"
" frag->offset: %d\n"
/*
* process the packet through the detection engine
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"Processing rebuilt packet:\n");
ip_stats.reassembles++;
* Note, that this won't print out the IP Options or any other
* data that is established when the packet is decoded.
*/
- if ( Debug::enabled(DEBUG_FRAG) )
+ if ( stream_ip.enabled(1) )
LogIPPkt(dpkt);
#endif
SnortEventqPop();
encap_frag_cnt--;
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"Done with rebuilt packet, marking rebuilt...\n");
ft->frag_flags = ft->frag_flags | FRAG_REBUILT;
*/
static inline void delete_node(FragTracker* ft, Fragment* node)
{
- DebugFormat(DEBUG_FRAG, "Deleting list node %p (p %p n %p)\n",
+ trace_logf(stream_ip, "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 = NULL; /* ptr to the Fragment element to drop */
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"delete_tracker %d nodes to dump\n", ft->fraglist_count);
/*
#ifdef DEBUG_MSGS
if ( p->is_ip4() )
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[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:
- DebugFormat(DEBUG_FRAG, "WARNING: Insert into Fraglist failed, "
+ trace_logf(stream_ip, "WARNING: Insert into Fraglist failed, "
"(offset: %hu).\n", frag_offset);
return;
#ifdef DEBUG_MSGS
if ( p->is_ip4() )
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[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:
- DebugFormat(DEBUG_FRAG, "WARNING: Insert into Fraglist failed due to timeout, "
+ trace_logf(stream_ip, "WARNING: Insert into Fraglist failed due to timeout, "
"(offset: %hu).\n", frag_offset);
return;
case FRAG_INSERT_OVERLAP_LIMIT:
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"WARNING: Excessive IP fragment overlap, "
"(More: %d, offset: %d, offsetSize: %hu).\n",
(p->ptrs.decode_flags & DECODE_MF),
*/
if (FragIsComplete(ft))
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[*] Fragment is complete, rebuilding!\n");
/*
/*
* bonk/boink/jolt/etc attack...
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Short frag (Bonk, etc) attack!\n");
EventAnomShortFrag(fe);
if (ft->frag_flags & FRAG_GOT_LAST)
{
/* oversize frag attack */
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Oversize frag pkt!\n");
EventAnomOversize(fe);
/*
* zero size frag...
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Zero size frag!\n");
EventAnomZeroFrag(fe);
/*
* oversize pkt...
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Oversize frag!\n");
EventAnomBadsizeLg(fe);
ft->frag_pkts++;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"Walking frag list (%d nodes), new frag %d@%d\n",
ft->fraglist_count, fragLength, frag_offset);
i++;
right = idx;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"%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)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"Dealing with previous (left) frag %d@%d\n",
left->size, left->offset);
/*
* teardrop attack...
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Teardrop attack!\n");
EventAttackTeardrop(fe);
frag_offset += (int16_t)overlap;
slide = (int16_t)overlap;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"left overlap, new frag moves: %d bytes, "
"slide: %d\n", overlap, slide);
/*
* zero size frag
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"zero size frag\n");
EventAnomZeroFrag(fe);
return FRAG_INSERT_ANOMALY;
}
- DebugFormat(DEBUG_FRAG, "left overlap, "
+ trace_logf(stream_ip, "left overlap, "
"truncating new pkt (slide: %d)\n", slide);
break;
}
left_overlap_last:
- DebugFormat(DEBUG_FRAG, "[!!] left overlap, "
+ trace_logf(stream_ip, "[!!] left overlap, "
"truncating old pkt (offset: %d overlap: %d)\n",
left->offset, overlap);
{
dump_me = left;
- DebugFormat(DEBUG_FRAG, "retrans, "
+ trace_logf(stream_ip, "retrans, "
"dumping old frag (offset: %d overlap: %d)\n",
dump_me->offset, overlap);
*/
if (frag_end < frag_offset)
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"frag_end < frag_offset!");
EventAnomBadsizeSm(fe);
}
else
{
- DebugMessage(DEBUG_FRAG, "No left overlap!\n");
+ trace_log(stream_ip, "No left overlap!\n");
}
}
if ((uint16_t)fragLength > pkt_snaplen)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"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);
*/
while (right && (right->offset < frag_end) && !done)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"Next (right)fragment %d@%d\n",
right->size, right->offset);
/*
* teardrop attack...
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Teardrop attack!\n");
EventAttackTeardrop(fe);
ip_stats.overlaps++;
ft->overlap_count++;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"Right-side overlap %d bytes\n", overlap);
/*
right->size -= (int16_t)overlap;
ft->frag_bytes -= (int16_t)overlap;
}
- DebugFormat(DEBUG_FRAG, "[!!] right overlap, "
+ trace_logf(stream_ip, "[!!] right overlap, "
"truncating old frag (offset: %d, "
"overlap: %d)\n", right->offset, overlap);
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"Exiting right overlap loop...\n");
if (right->size <= 0)
{
dump_me = right;
- DebugFormat(DEBUG_FRAG, "retrans, "
+ trace_logf(stream_ip, "retrans, "
"dumping old frag (offset: %d overlap: %d)\n",
dump_me->offset, overlap);
case FRAG_POLICY_SOLARIS:
case FRAG_POLICY_BSD_RIGHT:
trunc = (int16_t)overlap;
- DebugFormat(DEBUG_FRAG, "[!!] right overlap, "
+ trace_logf(stream_ip, "[!!] right overlap, "
"truncating new frag (offset: %d "
"overlap: %d)\n",
right->offset, overlap);
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"Exiting right overlap loop...\n");
break;
}
dump_me = right;
ft->frag_bytes -= right->size;
- DebugFormat(DEBUG_FRAG, "retrans, "
+ trace_logf(stream_ip, "retrans, "
"dumping old frag (offset: %d overlap: %d)\n",
dump_me->offset, overlap);
trunc = (int16_t)overlap;
}
- DebugFormat(DEBUG_FRAG, "right overlap, "
+ trace_logf(stream_ip, "right overlap, "
"rejecting new overlap data (overlap: %d, "
"trunc: %d)\n", overlap, trunc);
/*
* zero size frag
*/
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"zero size frag (len: %d overlap: %d)\n",
fragLength, overlap);
dump_me = right;
ft->frag_bytes -= right->size;
- DebugFormat(DEBUG_FRAG, "retrans, "
+ trace_logf(stream_ip, "retrans, "
"dumping old frag (offset: %d overlap: %d)\n",
dump_me->offset, overlap);
(ft->overlap_count >= fe->max_overlaps))
{
// overlap limit exceeded. Raise event on all subsequent fragments
- DebugMessage(DEBUG_FRAG, "Reached overlap limit.\n");
+ trace_log(stream_ip, "Reached overlap limit.\n");
EventExcessiveOverlap(fe);
}
else
{
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"Fully truncated right overlap\n");
}
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"insert(): returning normally\n");
return ret;
/* Just to double check */
if (fragLength > pkt_snaplen)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"Overly large 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...
*/
- DebugMessage(DEBUG_FRAG,
+ trace_log(stream_ip,
"[..] Short frag (Bonk, etc) attack!\n");
EventAnomShortFrag(&engine);
/*
* zero size frag
*/
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"zero size frag after left & right trimming "
"(len: %d slide: %d trunc: %d)\n",
len, slide, trunc);
newfrag = ft->fraglist;
while (newfrag)
{
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"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;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[+] 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);
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[*] 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;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[#] accumulated bytes on FragTracker %u, count"
" %d\n", ft->frag_bytes, ft->fraglist_count);
*/
add_node(ft, left, newfrag);
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[*] 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;
- DebugFormat(DEBUG_FRAG,
+ trace_logf(stream_ip,
"[#] accumulated bytes on FragTracker %u, count"
" %d\n", ft->frag_bytes, ft->fraglist_count);
// stream_ip module
//-------------------------------------------------------------------------
+Trace TRACE_NAME(stream_ip);
+
static const RuleMap stream_ip_rules[] =
{
{ DEFRAG_IPOPTIONS, DEFRAG_IPOPTIONS_STR },
};
StreamIpModule::StreamIpModule() :
- Module(MOD_NAME, MOD_HELP, s_params)
-{
- config = nullptr;
-}
+ Module(MOD_NAME, MOD_HELP, s_params, false, &TRACE_NAME(stream_ip))
+{ config = nullptr; }
StreamIpModule::~StreamIpModule()
{
return temp;
}
-bool StreamIpModule::set(const char*, Value& v, SnortConfig*)
+bool StreamIpModule::set(const char* f, Value& v, SnortConfig* c)
{
if ( v.is("max_frags") )
config->frag_engine.max_frags = v.get_long();
config->frag_engine.frag_timeout = v.get_long();
}
else
- return false;
+ return Module::set(f, v, c);
return true;
}
#ifndef IP_MODULE_H
#define IP_MODULE_H
+#include "main/snort_debug.h"
#include "main/snort_types.h"
#include "main/thread.h"
#include "flow/session.h"
extern THREAD_LOCAL ProfileStats fragPerfStats;
extern THREAD_LOCAL ProfileStats fragInsertPerfStats;
extern THREAD_LOCAL ProfileStats fragRebuildPerfStats;
+extern Trace TRACE_NAME(stream_ip);
//-------------------------------------------------------------------------
// stream_ip module