#include "time/packet_time.h"
#include "utils/util_cstring.h"
-#ifdef UNIT_TEST
-#include "catch/catch.hpp"
-#endif
-
static int already_fatal = 0;
static unsigned parse_errors = 0;
va_end(ap);
}
-ThrottledErrorLogger::ThrottledErrorLogger(uint32_t dur) :
- throttle_duration { dur }
-{ reset(); }
-
-bool ThrottledErrorLogger::log(const char* format, ...)
-{
- if ( !snort_conf )
- return false;
-
- if ( throttle() )
- return false;
-
- va_list ap;
-
- va_start(ap, format);
- int index = vsnprintf(buf, STD_BUF, format, ap);
- va_end(ap);
-
- if ( index && ( count > 1 ) )
- snprintf(&buf[index - 1], STD_BUF - index,
- " (suppressed " STDu64 " times in the last %d seconds).\n",
- count, delta);
-
- ErrorMessage("%s", buf);
- return true;
-}
-
-void ThrottledErrorLogger::reset()
-{ count = 0; }
-
-bool ThrottledErrorLogger::throttle()
-{
- time_t cur = packet_time();
- bool result = false;
-
- if ( count++ )
- {
- delta = cur - last;
- result = (decltype(throttle_duration))delta < throttle_duration;
-
- if ( !result )
- count = 0;
- }
-
- last = cur;
-
- return result;
-}
-
/*
* Function: FatalError(const char *, ...)
*
assert(false);
}
-#ifdef UNIT_TEST
-
-static void set_packet_time(time_t x)
-{
- struct timeval t { x, 0 };
- packet_time_update(&t);
-}
-
-static bool check_message(const char* buffer, const char* msg)
-{
- if ( strncmp(buffer, msg, strnlen(msg, STD_BUF)) != 0 )
- {
- INFO( buffer );
- return false;
- }
-
- return true;
-}
-
-TEST_CASE( "throttled error logger", "[ThrottledErrorLogger]" )
-{
- uint32_t dur = 5;
- ThrottledErrorLogger logger(dur);
-
- set_packet_time(0);
-
- SECTION( "1st message" )
- {
- const char msg[] = "first message";
- REQUIRE( logger.log("%s\n", msg) );
-
- CHECK( check_message(logger.last_message(), msg) );
- }
-
- SECTION( "2nd message within 1 second" )
- {
- const char msg[] = "second message";
- logger.log(" ");
-
- REQUIRE_FALSE( logger.log("%s\n", msg) );
- }
-
- SECTION( "0 duration" )
- {
- logger.throttle_duration = 0;
- const char msg[] = "zero duration";
-
- logger.log(" "); // trigger throttling
- REQUIRE( logger.log("%s\n", msg) );
-
- CHECK( check_message(logger.last_message(), msg) );
- }
-
- SECTION( "message @ duration" )
- {
- const char msg[] = "at duration";
- logger.log(" "); // trigger throttling
-
- set_packet_time(dur - 1);
- CHECK_FALSE( logger.log("%s\n", msg) );
- }
-
- SECTION( "message after duration" )
- {
- const char msg[] = "after duration";
- logger.log(" "); // trigger throttling
-
- set_packet_time(dur);
- REQUIRE( logger.log("%s\n", msg) );
-
- CHECK( check_message(logger.last_message(), msg) );
- }
-
- SECTION( "reversed packet time" )
- {
- const char msg[] = "reversed packet time";
-
- set_packet_time(10);
- logger.log(" ");
-
- set_packet_time(4);
- REQUIRE( logger.log("%s\n", msg) );
-
- CHECK( check_message(logger.last_message(), msg) );
- }
-}
-
-#endif
SO_PUBLIC void WarningMessage(const char*, ...) __attribute__((format (printf, 1, 2)));
SO_PUBLIC void ErrorMessage(const char*, ...) __attribute__((format (printf, 1, 2)));
-// FIXIT-L should we be using STL timekeeping types for this?
-class ThrottledErrorLogger
-{
-public:
- ThrottledErrorLogger(uint32_t);
-
- bool log(const char*, ...) __attribute__((format (printf, 2, 3)));
- void reset();
-
- uint32_t throttle_duration;
- uint32_t duration_to_log;
-
- const char* last_message() const
- { return buf; }
-
-private:
- bool throttle();
-
- time_t last;
- int delta;
- uint64_t count;
-
- char buf[STD_BUF + 1];
-};
-
// FIXIT-M do not call FatalError() during runtime
SO_PUBLIC NORETURN void FatalError(const char*, ...) __attribute__((format (printf, 1, 2)));
#include "log/messages.h"
#include "log/unified2.h"
#include "main/snort_debug.h"
+#include "utils/util_cstring.h"
static AppInfoTable app_info_table;
static AppInfoTable app_info_service_table;
else if (!config->referred_appId_disabled)
{
char referred_app_list[4096];
- int referred_app_index = snprintf(referred_app_list, 4096, "%d ", atoi(
- conf_val));
+ int referred_app_index = safe_snprintf(referred_app_list, 4096, "%d ",
+ atoi(conf_val));
set_app_info_flags(atoi(conf_val), APPINFO_FLAG_REFERRED);
while ((token = strtok_r(nullptr, CONF_SEPARATORS, &context)) != nullptr)
{
AppId id = atoi(token);
- referred_app_index += snprintf(referred_app_list + referred_app_index,
- 4096 - referred_app_index, "%d ", id);
+ referred_app_index += safe_snprintf(referred_app_list + referred_app_index,
+ sizeof(referred_app_list) - referred_app_index, "%d ", id);
set_app_info_flags(id, APPINFO_FLAG_REFERRED);
}
DebugFormat(DEBUG_APPID,
-add_library(appid_test_depends_on_lib ../appid_stats_counter.cc ../../../sfip/sf_ip.cc)
+add_library(appid_test_depends_on_lib ../appid_stats_counter.cc ../../../sfip/sf_ip.cc ../../../utils/util_cstring.cc)
add_cpputest(appid_http_event_test appid_test_depends_on_lib)
add_cpputest(appid_api_test appid_test_depends_on_lib)
appid_http_event_test_LDADD = \
../appid_stats_counter.o \
../../../sfip/sf_ip.o \
+../../../utils/util_cstring.o \
@CPPUTEST_LDFLAGS@
appid_api_test_CPPFLAGS = -I$(top_srcdir)/src/network_inspectors/appid @AM_CPPFLAGS@ @CPPUTEST_CPPFLAGS@
appid_api_test_LDADD = \
../appid_stats_counter.o \
../../../sfip/sf_ip.o \
+../../../utils/util_cstring.o \
@CPPUTEST_LDFLAGS@
app_info_table_test_CPPFLAGS = -I$(top_srcdir)/src/network_inspectors/appid @AM_CPPFLAGS@ @CPPUTEST_CPPFLAGS@
app_info_table_test_LDADD = \
../appid_stats_counter.o \
+../../../utils/util_cstring.o \
@CPPUTEST_LDFLAGS@
appid_detector_test_CPPFLAGS = -I$(top_srcdir)/src/network_inspectors/appid @AM_CPPFLAGS@ @CPPUTEST_CPPFLAGS@
appid_detector_test_LDADD = \
../appid_stats_counter.o \
../../../sfip/sf_ip.o \
+../../../utils/util_cstring.o \
@CPPUTEST_LDFLAGS@
#include "packet_io/active.h"
#include "packet_io/sfdaq.h"
#include "profiler/profiler.h"
+#include "utils/util_cstring.h"
#include "norm_module.h"
if ( Norm_IsEnabled(nc, NORM_TCP_OPT) )
{
- char buf[1024] = "";
+ char buf[1024];
char* p = buf;
int opt;
- size_t min;
-
- p += snprintf(p, buf+sizeof(buf)-p, "%s", "(allow ");
- min = strlen(buf);
+ int buf_size = sizeof(buf);
+ int len = safe_snprintf(p, buf_size, "%s", "(allow ");
+ p += len;
+ buf_size -= len;
+ bool opt_printed = false;
// TBD translate options to keywords allowed by parser
for ( opt = 2; opt < 256; opt++ )
{
- const char* fmt = (strlen(buf) > min) ? ",%d" : "%d";
if ( Norm_TcpIsOptional(nc, opt) )
- p += snprintf(p, buf+sizeof(buf)-p, fmt, opt);
- }
- if ( strlen(buf) > min )
- {
- snprintf(p, buf+sizeof(buf)-p, "%c", ')');
- buf[sizeof(buf)-1] = '\0';
+ {
+ const char* fmt = opt_printed ? ",%d" : "%d";
+ len = safe_snprintf(p, buf_size, fmt, opt);
+ if (len >0)
+ opt_printed = true;
+ p += len;
+ buf_size -= len;
+ }
}
+ snprintf(p, buf_size, "%c", ')');
LogMessage("%12s: %s %s\n", "tcp.opt", ON, buf);
}
else
else
type = 'r';
- buf.len = snprintf((char*)buf.data, sizeof(buf.data),
+ buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
"Priority Count: %d\n"
"Connection Count: %d\n"
"IP Count: %d\n"
char a1[INET6_ADDRSTRLEN];
ip1->ntop(a1, sizeof(a1));
- buf.len = snprintf((char*)buf.data, sizeof(buf.data),
+ buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
"Scanned IP: %s\n"
"Port Count: %d\n"
- "Ports: ",
+ "Ports:",
a1,
proto->open_ports_cnt);
for ( int i = 0; i < proto->open_ports_cnt; i++ )
{
- buf.len += snprintf(
- (char*)buf.data, sizeof(buf.data) - buf.len, "%hu ", proto->open_ports[i]);
+ buf.len += safe_snprintf(
+ (char*)buf.data + buf.len, sizeof(buf.data) - buf.len, " %hu", proto->open_ports[i]);
}
+ buf.len += safe_snprintf((char*)buf.data + buf.len, sizeof(buf.data) - buf.len, "\n");
}
static void make_open_port_info(Packet* p, uint16_t port)
const char* addr = p->ptrs.ip_api.get_src()->ntoa();
- buf.len = snprintf((char*)buf.data, sizeof(buf.data),
+ buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
"Scanned IP: %s\n"
"Open Port: %hu\n",
addr, port);
#include "detection/detection_engine.h"
#include "events/event_queue.h"
#include "log/messages.h"
+#include "utils/util_cstring.h"
#include "gtp.h"
#include "gtp_inspect.h"
while ((i < inputSize)&&(totalBytes > 0))
{
- length = snprintf(buf_ptr, totalBytes, "%.2x ", (uint8_t)input[i]);
+ length = safe_snprintf(buf_ptr, totalBytes, "%.2x ", (uint8_t)input[i]);
buf_ptr += length;
totalBytes -= length;
if (totalBytes < 0)
dest[dsize-1]=0; /* guarantee a null termination */
+ if (appendLen >= (dsize - currLen))
+ appendLen = dsize - currLen - 1;
+ else if (appendLen < 0)
+ appendLen = 0;
+
return appendLen;
}
+// return actual number of bytes written to buffer s
+int safe_snprintf(char* s, size_t n, const char* format, ... )
+{
+ va_list ap;
+
+ va_start(ap, format);
+ int len = vsnprintf(s, n, format, ap);
+ va_end(ap);
+
+ if (len >= (int)n)
+ len = n - 1;
+ else if (len < 0)
+ len = 0;
+
+ return len;
+}
\ No newline at end of file
#define SNORT_STRNCPY_SUCCESS 0
#define SNORT_STRNCPY_TRUNCATION 1
#define SNORT_STRNCPY_ERROR -1
-
#define SNORT_STRNLEN_ERROR -1
+SO_PUBLIC int safe_snprintf(char*, size_t, const char*, ... )
+ __attribute__((format (printf, 3, 4)));
// these functions are deprecated; use C++ strings instead
SO_PUBLIC int SnortSnprintf(char*, size_t, const char*, ...)
__attribute__((format (printf, 3, 4)));