void dump(const ConfigData&) override;
private:
- JsonStream json;
+ snort::JsonStream json;
};
class JsonTopConfigOutput : public ConfigOutput
void dump(const ConfigData&) override;
private:
- JsonStream json;
+ snort::JsonStream json;
};
#endif // JSON_CONFIG_OUTPUT_H
boyer_moore_search.h
literal_search.h
scratch_allocator.h
+ json_stream.h
)
add_library (helpers OBJECT
#include <cassert>
#include <iomanip>
+using namespace snort;
+
void JsonStream::open(const char* key)
{
split();
out << val;
}
+void JsonStream::put(const char* key, const char* val)
+{
+ if (val and val[0] == '\0')
+ return;
+
+ split();
+
+ if ( key )
+ out << std::quoted(key) << ": ";
+
+ if (val)
+ out << std::quoted(val);
+ else
+ out << "null";
+}
+
void JsonStream::put(const char* key, const std::string& val)
{
if ( val.empty() )
// Simple output stream for outputting JSON data.
#include <iostream>
+#include "main/snort_types.h"
-class JsonStream
+namespace snort
+{
+class SO_PUBLIC JsonStream
{
public:
JsonStream(std::ostream& o) : out(o) { }
void put(const char* key); // null
void put(const char* key, long val);
+ void put(const char* key, const char* val);
void put(const char* key, const std::string& val);
void put(const char* key, double val, int precision);
unsigned level = 0;
unsigned level_array = 0;
};
-
+}
#endif
#include "../json_stream.h"
+using namespace snort;
+
TEST_CASE("basic", "[json_stream]")
{
std::ostringstream ss;
SECTION("int")
{
- js.put("i", 0);
+ js.put("i", (long) 0);
const char* x = R"-("i": 0)-";
CHECK(ss.str() == x);
}
#include "appid_api.h"
+#include "detection/detection_engine.h"
#include "framework/inspector.h"
#include "managers/inspector_manager.h"
#include "utils/util.h"
return odp_ctxt.get_app_info_mgr().get_app_name(app_id);
}
+const char* AppIdApi::get_application_name(AppId app_id, const Flow& flow)
+{
+ const char* app_name = nullptr;
+ AppIdSession* asd = get_appid_session(flow);
+ if (asd)
+ {
+ // Skip sessions using old odp context after odp reload
+ AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+ if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &(asd->get_odp_ctxt())))
+ return nullptr;
+
+ if (app_id == APP_ID_UNKNOWN)
+ return "unknown";
+ app_name = asd->get_odp_ctxt().get_app_info_mgr().get_app_name(app_id);
+ }
+
+ return app_name;
+}
+
const char* AppIdApi::get_application_name(const Flow& flow, bool from_client)
{
const char* app_name = nullptr;
asd->set_ss_application_ids(client_id, payload_id, change_bits);
asd->set_tls_host(change_bits);
- asd->publish_appid_event(change_bits, flow);
+ Packet* p = DetectionEngine::get_current_packet();
+ assert(p);
+ asd->publish_appid_event(change_bits, *p);
}
else
{
AppIdSession* get_appid_session(const Flow& flow);
const char* get_application_name(AppId app_id, OdpContext& odp_ctxt);
+ const char* get_application_name(AppId app_id, const Flow& flow);
const char* get_application_name(const Flow& flow, bool from_client);
AppId get_application_id(const char* appName, const AppIdContext& ctxt);
uint32_t produce_ha_state(const Flow& flow, uint8_t* buf);
asd->set_ss_application_ids(asd->pick_service_app_id(), asd->pick_ss_client_app_id(),
asd->pick_ss_payload_app_id(), asd->pick_ss_misc_app_id(),
asd->pick_ss_referred_payload_app_id(), change_bits);
- asd->publish_appid_event(change_bits, p->flow);
+ asd->publish_appid_event(change_bits, *p);
asd->set_session_flags(APPID_SESSION_FUTURE_FLOW_IDED);
if (appidDebug->is_active())
asd.pick_ss_referred_payload_app_id(), change_bits);
asd.set_tls_host(change_bits);
- asd.publish_appid_event(change_bits, p->flow);
+ asd.publish_appid_event(change_bits, *p);
}
#include <cassert>
+#include "detection/detection_engine.h"
#include "managers/inspector_manager.h"
#include "app_info_table.h"
#include "appid_debug.h"
else
asd->set_application_ids_service(APP_ID_HTTP2, change_bits);
- asd->publish_appid_event(change_bits, flow, http_event->get_is_http2(),
+ Packet* p = DetectionEngine::get_current_packet();
+ assert(p);
+ asd->publish_appid_event(change_bits, *p, http_event->get_is_http2(),
asd->get_api().get_hsessions_size() - 1);
}
using namespace snort;
unsigned AppIdSession::inspector_id = 0;
-THREAD_LOCAL uint32_t AppIdSession::appid_flow_data_id = 0;
std::mutex AppIdSession::inferred_svcs_lock;
uint16_t AppIdSession::inferred_svcs_ver = 0;
odp_ctxt(odp_ctxt), tp_appid_ctxt(inspector.get_ctxt().get_tp_appid_ctxt())
{
service_ip.clear();
- session_id = ++appid_flow_data_id;
initiator_port = port;
appid_stats.total_sessions++;
}
}
-void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, Flow* flow,
+void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packet& p,
bool is_http2, uint32_t http2_stream_index)
{
if (!api.stored_in_stash and change_bits.any())
{
- assert(flow and flow->stash);
- flow->stash->store(STASH_APPID_DATA, &api, false);
+ assert(p.flow and p.flow->stash);
+ p.flow->stash->store(STASH_APPID_DATA, &api, false);
api.stored_in_stash = true;
}
if (change_bits.none())
return;
- AppidEvent app_event(change_bits, is_http2, http2_stream_index, api);
- DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, flow);
+ AppidEvent app_event(change_bits, is_http2, http2_stream_index, api, p);
+ DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, p.flow);
if (appidDebug->is_active())
{
std::string str;
size_t size_of() override
{ return sizeof(*this); }
- uint32_t session_id = 0;
snort::Flow* flow = nullptr;
AppIdConfig& config;
std::unordered_map<unsigned, AppIdFlowData*> flow_data;
AppidChangeBits& change_bits);
void set_tp_payload_app_id(snort::Packet& p, AppidSessionDirection dir, AppId app_id,
AppidChangeBits& change_bits);
- void publish_appid_event(AppidChangeBits&, snort::Flow*, bool is_http2 = false,
+ void publish_appid_event(AppidChangeBits&, const snort::Packet&, bool is_http2 = false,
uint32_t http2_stream_index = 0);
inline void set_tp_app_id(AppId app_id)
void reinit_session_data(AppidChangeBits& change_bits);
void delete_session_data(bool free_api = true);
- static THREAD_LOCAL uint32_t appid_flow_data_id;
bool tp_app_id_deferred = false;
bool tp_payload_app_id_deferred = false;
using namespace snort;
+THREAD_LOCAL uint32_t AppIdSessionApi::appid_flow_data_id = 0;
+
+AppIdSessionApi::AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID), asd(asd), initiator_ip(ip)
+{
+ session_id = std::to_string(get_instance_id()) + "." + std::to_string(++appid_flow_data_id);
+}
+
AppId AppIdSessionApi::get_service_app_id() const
{
return application_ids[APP_PROTOID_SERVICE];
return hsessions.size();
}
+ const std::string& get_session_id() const
+ {
+ return session_id;
+ }
+
protected:
- AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) :
- StashGenericObject(STASH_GENERIC_OBJECT_APPID), asd(asd), initiator_ip(ip) {}
+ AppIdSessionApi(const AppIdSession* asd, const SfIp& ip);
private:
const AppIdSession* asd = nullptr;
snort::SfIp initiator_ip;
ServiceAppDescriptor service;
char* tls_host = nullptr;
+ std::string session_id;
// Following two fields are used only for non-http sessions. For HTTP traffic,
// these fields are maintained inside AppIdHttpSession.
ClientAppDescriptor client;
PayloadAppDescriptor payload;
+ static THREAD_LOCAL uint32_t appid_flow_data_id;
+
void set_ss_application_ids(AppId service, AppId client, AppId payload, AppId misc,
AppId referred, AppidChangeBits& change_bits);
void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits);
void SipEventHandler::handle(DataEvent& event, Flow* flow)
{
- SipEvent& sip_event = (SipEvent&)event;
- AppIdSession* asd = nullptr;
+ if (!flow)
+ return;
- if ( flow )
- asd = appid_api.get_appid_session(*flow);
+ SipEvent& sip_event = (SipEvent&)event;
+ AppIdSession* asd = appid_api.get_appid_session(*flow);
+ const Packet* p = sip_event.get_packet();
+ assert(p);
if ( !asd )
{
- const Packet* p = sip_event.get_packet();
IpProtocol protocol = p->is_tcp() ? IpProtocol::TCP : IpProtocol::UDP;
AppidSessionDirection direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
AppidChangeBits change_bits;
client_handler(sip_event, *asd, change_bits);
service_handler(sip_event, *asd, change_bits);
- asd->publish_appid_event(change_bits, flow);
+ asd->publish_appid_event(change_bits, *p);
}
void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd,
static AppId client_id = APP_ID_NONE;
static DetectorHTTPPattern mpattern;
+namespace snort
+{
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+}
+
void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
AppIdDiscovery::AppIdDiscovery() { }
AppIdDiscovery::~AppIdDiscovery() { }
// Verify detector user data and that we are in packet context
assert(pLuaData.ptr);
- lua_pushlstring(L, (char*)&pLuaData->asd->session_id,
- sizeof(pLuaData->asd->session_id));
+ lua_pushstring(L, pLuaData->asd->get_api().get_session_id().c_str());
return 1;
}
{
if (memcmp(data, PATTERN1, sizeof(PATTERN1)-1) == 0)
{
- printf("maybe first directconnect to hub detected\n");
serviceData->state = CONN_STATE_1;
goto inprocess;
}
if (memcmp(data, PATTERN2, sizeof(PATTERN2)-1) == 0)
{
- printf("maybe first dc connect between peers detected\n");
serviceData->state = CONN_STATE_2;
goto inprocess;
}
break;
case CONN_STATE_1:
- printf ("ValidateDirectConnectTcp(): state 1 size %d\n", size);
if (size >= 11)
{
if (memcmp(data, PATTERN3, sizeof(PATTERN3)-1) == 0
|| memcmp(data, PATTERN5, sizeof(PATTERN5)-1) == 0
|| memcmp(data, PATTERN6, sizeof(PATTERN6)-1) == 0)
{
- printf("found directconnect HSUP ADBAS E in second packet\n");
goto success;
}
}
void Module::show_stats(){}
void Module::sum_stats(bool ){}
void Module::reset_stats() {}
+
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
SslPatternMatchers::~SslPatternMatchers() { }
class Inspector* InspectorManager::get_inspector(const char*, bool, const SnortConfig*)
{ return &dummy_appid_inspector; }
+Packet::Packet(bool) { }
+Packet::~Packet() { }
+
+Packet* DetectionEngine::get_current_packet()
+{
+ static Packet p;
+ return &p;
+}
+
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
class DummyInspector : public snort::Inspector
mock().actualCall("publish");
}
-void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, Flow* flow, bool, uint32_t)
+void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packet& p, bool, uint32_t)
{
- AppidEvent app_event(change_bits, false, 0, this->get_api());
- DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, flow);
+ AppidEvent app_event(change_bits, false, 0, this->get_api(), p);
+ DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, p.flow);
}
bool SslPatternMatchers::scan_hostname(const uint8_t* server_name, size_t, AppId& client_id, AppId& payload_id)
FlowData::FlowData(unsigned, Inspector*) { }
FlowData::~FlowData() = default;
+AppIdSessionApi::AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID), asd(asd), initiator_ip(ip) {}
}
void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
{
Inspector* InspectorManager::get_inspector(
char const*, bool, const snort::SnortConfig*) { return nullptr; }
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
void ApplicationDescriptor::set_id(
}
} // namespace ip
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
} // namespace snort
// Stubs for publish
return nullptr;
}
-void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, Flow* flow, bool, uint32_t)
+void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packet& p, bool, uint32_t)
{
- AppidEvent app_event(change_bits, false, 0, this->get_api());
- DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, flow);
+ AppidEvent app_event(change_bits, false, 0, this->get_api(), p);
+ DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, p.flow);
}
void AppIdHttpSession::set_tun_dest(){}
AppIdApi appid_api;
Inspector* InspectorManager::get_inspector(
char const*, bool, const snort::SnortConfig*) { return nullptr; }
+
+Packet::Packet(bool) { }
+Packet::~Packet() { }
+
+Packet* DetectionEngine::get_current_packet()
+{
+ static Packet p;
+ return &p;
+}
+
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
const char* content_type = nullptr;
return mock_session;
}
-void AppIdSession::publish_appid_event(AppidChangeBits&, Flow*, bool, uint32_t) { }
+void AppIdSession::publish_appid_event(AppidChangeBits&, const Packet&, bool, uint32_t) { }
TEST_GROUP(appid_http_event)
{
#include <CppUTest/TestHarness.h>
using namespace snort;
+namespace snort
+{
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+}
+
void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
const char* AppInfoManager::get_app_name(AppId)
{
static AppIdConfig config;
static OdpContext odpctxt(config, nullptr);
+namespace snort
+{
+ unsigned get_instance_id()
+ {
+ return 0;
+ }
+}
+
void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
{
return p;
}
time_t packet_time() { return std::time(0); }
+
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+ StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
// Stubs for AppInfoManager
{
public:
AppidEvent(const AppidChangeBits& ac, bool is_http2, uint32_t http2_stream_index,
- const snort::AppIdSessionApi& api) :
- ac_bits(ac), is_http2(is_http2), http2_stream_index(http2_stream_index), api(api) {}
+ const snort::AppIdSessionApi& api, const snort::Packet& p) :
+ ac_bits(ac), is_http2(is_http2), http2_stream_index(http2_stream_index), api(api), p(p) {}
const AppidChangeBits& get_change_bitset() const
{ return ac_bits; }
const snort::AppIdSessionApi& get_appid_session_api() const
{ return api; }
+ const snort::Packet* get_packet() override
+ { return &p; }
+
private:
const AppidChangeBits& ac_bits;
bool is_http2;
uint32_t http2_stream_index;
const snort::AppIdSessionApi& api;
+ const snort::Packet& p;
};
#endif
#undef SNORT_VERSION_STRING
#undef SNORT_VERSION_STRLEN
-/****************************************************************************
- *
- * Function: DisplayBanner()
- *
- * Purpose: Show valuable proggie info
- *
- * Arguments: None.
- *
- * Returns: 0 all the time
- *
- ****************************************************************************/
int DisplayBanner()
{
const char* ljv = LUAJIT_VERSION;
return 0;
}
-/****************************************************************************
- *
- * Function: ts_print(const struct, char *)
- *
- * Purpose: Generate a time stamp and stuff it in a buffer. This one has
- * millisecond precision. Oh yeah, I ripped this code off from
- * TCPdump, props to those guys.
- *
- * Arguments: timeval => clock struct coming out of libpcap
- * timebuf => buffer to stuff timestamp into
- *
- * Returns: void function
- *
- ****************************************************************************/
-void ts_print(const struct timeval* tvp, char* timebuf)
-{
- struct timeval tv;
- struct timezone tz;
-
- /* if null was passed, we use current time */
- if (!tvp)
- {
- /* manual page (for linux) says tz is never used, so.. */
- memset((char*)&tz, 0, sizeof(tz));
- gettimeofday(&tv, &tz);
- tvp = &tv;
- }
-
- const SnortConfig* sc = SnortConfig::get_conf();
- int localzone = sc->thiszone;
-
- /*
- ** If we're doing UTC, then make sure that the timezone is correct.
- */
- if (sc->output_use_utc())
- localzone = 0;
-
- int s = (tvp->tv_sec + localzone) % SECONDS_PER_DAY;
- time_t Time = (tvp->tv_sec + localzone) - s;
-
- struct tm ttm;
- struct tm* lt = gmtime_r(&Time, &ttm);
-
- if ( !lt )
- {
- (void)SnortSnprintf(timebuf, TIMEBUF_SIZE, "%lu", tvp->tv_sec);
-
- }
- else if (sc->output_include_year())
- {
- int year = (lt->tm_year >= 100) ? (lt->tm_year - 100) : lt->tm_year;
-
- (void)SnortSnprintf(timebuf, TIMEBUF_SIZE,
- "%02d/%02d/%02d-%02d:%02d:%02d.%06u",
- year, lt->tm_mon + 1, lt->tm_mday,
- s / 3600, (s % 3600) / 60, s % 60,
- (unsigned)tvp->tv_usec);
- }
- else
- {
- (void)SnortSnprintf(timebuf, TIMEBUF_SIZE,
- "%02d/%02d-%02d:%02d:%02d.%06u", lt->tm_mon + 1,
- lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60,
- (unsigned)tvp->tv_usec);
- }
-}
-
-/****************************************************************************
- *
- * Function: gmt2local(time_t)
- *
- * Purpose: Figures out how to adjust the current clock reading based on the
- * timezone you're in. Ripped off from TCPdump.
- *
- * Arguments: time_t => offset from GMT
- *
- * Returns: offset seconds from GMT
- *
- ****************************************************************************/
+// get offset seconds from GMT
int gmt2local(time_t t)
{
if (t == 0)
unlink(pid_lockfilename.c_str());
}
-/****************************************************************************
- *
- * Function: ClosePidFile(char *)
- *
- * Purpose: Releases lock on a PID file
- *
- * Arguments: None
- *
- * Returns: void function
- *
- ****************************************************************************/
void ClosePidFile()
{
if (pid_file)
}
}
-/****************************************************************************
- *
- * Function: SetUidGid()
- *
- * Purpose: Sets safe UserID and GroupID if needed
- *
- * Arguments: none
- *
- * Returns: void function
- *
- ****************************************************************************/
+// set safe UserID and GroupID, if needed
bool SetUidGid(int user_id, int group_id)
{
// Were any changes requested?
return true;
}
-/****************************************************************************
- *
- * Function: InitGroups()
- *
- * Purpose: Sets the groups of the process based on the UserID with the
- * GroupID added
- *
- * Arguments: none
- *
- * Returns: void function
- *
- ****************************************************************************/
+// set the groups of the process based on the UserID with the GroupID added
void InitGroups(int user_id, int group_id)
{
if ((user_id != -1) && (getuid() == 0))
}
}
-/****************************************************************************
- *
- * Function: read_infile(const char* key, const char* file)
- *
- * Purpose: Reads the BPF filters in from a file. Ripped from tcpdump.
- *
- * Arguments: fname => the name of the file containing the BPF filters
- *
- * Returns: the processed BPF string
- *
- ****************************************************************************/
+// read the BPF filters in from a file, return the processed BPF string
std::string read_infile(const char* key, const char* fname)
{
int fd = open(fname, O_RDONLY);
return buf;
}
-/**
- * Chroot and adjust the log_dir reference
- */
+// Chroot and adjust the log_dir reference
bool EnterChroot(std::string& root_dir, std::string& log_dir)
{
if (log_dir.empty())
return p;
}
+void ts_print(const struct timeval* tvp, char* timebuf, bool yyyymmdd)
+{
+ struct timeval tv;
+ struct timezone tz;
+
+ // if null was passed, use current time
+ if (!tvp)
+ {
+ // manual page (for linux) says tz is never used, so..
+ memset((char*)&tz, 0, sizeof(tz));
+ gettimeofday(&tv, &tz);
+ tvp = &tv;
+ }
+
+ const SnortConfig* sc = SnortConfig::get_conf();
+ int localzone = sc->thiszone;
+
+ // If we're doing UTC, then make sure that the timezone is correct.
+ if (sc->output_use_utc())
+ localzone = 0;
+
+ int s = (tvp->tv_sec + localzone) % SECONDS_PER_DAY;
+ time_t Time = (tvp->tv_sec + localzone) - s;
+
+ struct tm ttm;
+ struct tm* lt = gmtime_r(&Time, &ttm);
+
+ if ( !lt )
+ {
+ (void)SnortSnprintf(timebuf, TIMEBUF_SIZE, "%lu", tvp->tv_sec);
+
+ }
+ else if (sc->output_include_year())
+ {
+ int year = (lt->tm_year >= 100) ? (lt->tm_year - 100) : lt->tm_year;
+
+ (void)SnortSnprintf(timebuf, TIMEBUF_SIZE,
+ "%02d/%02d/%02d-%02d:%02d:%02d.%06u",
+ year, lt->tm_mon + 1, lt->tm_mday,
+ s / 3600, (s % 3600) / 60, s % 60,
+ (unsigned)tvp->tv_usec);
+ }
+ else if (yyyymmdd)
+ {
+ (void)SnortSnprintf(timebuf, TIMEBUF_SIZE,
+ "%04d-%02d-%02d %02d:%02d:%02d.%06u",
+ lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday,
+ s / 3600, (s % 3600) / 60, s % 60,
+ (unsigned)tvp->tv_usec);
+ }
+ else
+ {
+ (void)SnortSnprintf(timebuf, TIMEBUF_SIZE,
+ "%02d/%02d-%02d:%02d:%02d.%06u", lt->tm_mon + 1,
+ lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60,
+ (unsigned)tvp->tv_usec);
+ }
+}
}
#ifdef UNIT_TEST
#include "main/snort_types.h"
-#define TIMEBUF_SIZE 26
+#define TIMEBUF_SIZE 27
#define SECONDS_PER_DAY 86400 /* number of seconds in a day */
#define SECONDS_PER_HOUR 3600 /* number of seconds in a hour */
void StoreSnortInfoStrings();
int DisplayBanner();
int gmt2local(time_t);
-void ts_print(const struct timeval*, char*);
std::string read_infile(const char* key, const char* fname);
void CleanupProtoNames();
void CreatePidFile(pid_t);
SO_PUBLIC const char* get_error(int errnum);
SO_PUBLIC char* snort_strdup(const char*);
SO_PUBLIC char* snort_strndup(const char*, size_t);
+SO_PUBLIC void ts_print(const struct timeval*, char*, bool yyyymmdd = false);
}
#endif