PegCount* FileIdModule::get_counts() const
{ return (PegCount*)&file_counts; }
-void FileIdModule::sum_stats()
+void FileIdModule::sum_stats(bool accumulate_now_stats)
{
file_stats_sum();
- Module::sum_stats();
+ Module::sum_stats(accumulate_now_stats);
}
bool FileIdModule::set(const char*, Value& v, SnortConfig*)
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
- void sum_stats() override;
+ void sum_stats(bool) override;
void load_config(FileConfig*& dst);
#define SSNFLAG_COUNTED_INITIALIZE 0x00000100
#define SSNFLAG_COUNTED_ESTABLISH 0x00000200
#define SSNFLAG_COUNTED_CLOSING 0x00000400
+#define SSNFLAG_COUNTED_CLOSED 0x00000800
#define SSNFLAG_TIMEDOUT 0x00001000
#define SSNFLAG_PRUNED 0x00002000
PegCount timeouts; \
PegCount prunes
+#define SESSION_STAT_TYPES \
+ CountType sessions = CountType::SUM; \
+ CountType max = CountType::MAX; \
+ CountType created = CountType::SUM; \
+ CountType released = CountType::SUM; \
+ CountType timeouts = CountType::SUM; \
+ CountType prunes = CountType::SUM
+
+// FIXIT-M The calculation for max sessions is incorrect since the sessions
+// value is reset to zero after writing it out to the now file.
#define SESSION_STATS_ADD(stats) \
{ \
stats.sessions++; \
const char* help;
};
+enum CountType
+{
+ SUM, // Tracks cumulative total number of items seen.
+ NOW, // Gives snapshot of current number of items.
+ MAX, // Tracks maximum value seen.
+};
+
SO_PUBLIC extern const struct PegInfo simple_pegs[];
#define array_size(a) (sizeof(a)/sizeof(a[0]))
return true;
}
-void Module::sum_stats()
+void Module::sum_stats_helper(bool accumulate_now_stats, const CountType* const count_types)
{
if ( num_counts < 0 )
reset_stats();
if ( global_stats() )
{
for ( int i = 0; i < num_counts; i++ )
- counts[i] = p[i];
+ set_peg_count(i, p[i]);
}
else
{
for ( int i = 0; i < num_counts; i++ )
{
- counts[i] += p[i];
- p[i] = 0;
+ if(count_types)
+ {
+ switch (count_types[i])
+ {
+ case CountType::SUM:
+ add_peg_count(i, p[i]);
+ p[i] = 0;
+ break;
+
+ case CountType::NOW:
+ if(accumulate_now_stats)
+ add_peg_count(i, p[i]);
+ break;
+
+ case CountType::MAX:
+ set_max_peg_count(i, p[i]);
+ break;
+ }
+ }
+ else
+ {
+ add_peg_count(i, p[i]);
+ p[i] = 0;
+ }
}
}
}
+void Module::sum_stats(bool)
+{
+ sum_stats_helper(false, nullptr);
+}
+
void Module::show_interval_stats(IndexVec& peg_idxs, FILE* fh)
{
if ( num_counts > 0 )
void Module::reset_stats()
{
- num_counts = 0;
- const PegInfo* pegs = get_pegs();
+ if( num_counts <= 0 )
+ {
+ num_counts = 0;
+ const PegInfo* pegs = get_pegs();
- if ( !pegs )
- return;
+ if ( !pegs )
+ return;
- while ( pegs[num_counts].name )
- ++num_counts;
+ while ( pegs[num_counts].name )
+ ++num_counts;
- counts.resize(num_counts);
+ counts.resize(num_counts);
+ }
for ( int i = 0; i < num_counts; i++ )
counts[i] = 0;
#include <string>
#include <vector>
+#include <assert.h>
#include "framework/counts.h"
#include "framework/parameter.h"
virtual bool global_stats() const
{ return false; }
- virtual void sum_stats();
+ virtual void sum_stats(bool accumulate_now_stats);
virtual void show_interval_stats(IndexVec&, FILE*);
virtual void show_stats();
virtual void reset_stats();
Module(const char* name, const char* help, const Parameter*,
bool is_list = false, Trace* = nullptr);
+ void sum_stats_helper(bool accumulate_now_stats,
+ const CountType* const count_types);
+
private:
friend class ModuleManager;
void init(const char*, const char* = nullptr);
std::vector<PegCount> counts;
- int num_counts;
+ int num_counts = -1;
const char* name;
const char* help;
int table_level = 0;
Trace* trace;
+
+ void set_peg_count(int index, PegCount value)
+ {
+ assert(index < num_counts);
+ counts[index] = value;
+ }
+
+ void set_max_peg_count(int index, PegCount value)
+ {
+ assert(index < num_counts);
+ if(value > counts[index])
+ counts[index] = value;
+ }
+
+ void add_peg_count(int index, PegCount value)
+ {
+ assert(index < num_counts);
+ counts[index] += value;
+ }
};
#endif
PegCount* HostCacheModule::get_counts() const
{ return (PegCount*)host_cache.get_counts(); }
-void HostCacheModule::sum_stats()
+void HostCacheModule::sum_stats(bool accumulate_now_stats)
{
host_cache.lock();
- Module::sum_stats();
+ Module::sum_stats(accumulate_now_stats);
host_cache.unlock();
}
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
- void sum_stats() override;
+ void sum_stats(bool) override;
private:
static const Parameter host_cache_params[];
bool global_stats() const override
{ return true; }
- void sum_stats() override
+ void sum_stats(bool) override
{ } // accumulate externally
private:
for ( auto p : s_modules )
{
std::lock_guard<std::mutex> lock(stats_mutex);
- p->mod->sum_stats();
+ p->mod->sum_stats(true);
}
std::lock_guard<std::mutex> lock(stats_mutex);
pc_sum();
for ( auto const& m : config->modules )
if (!summary)
- m->sum_stats();
+ m->sum_stats(false);
}
#ifdef UNIT_TEST
PegCount* get_counts() const override { return counts; }
- void sum_stats() override {}
+ void sum_stats(bool) override {}
- void real_sum_stats() { Module::sum_stats(); }
+ void real_sum_stats() { Module::sum_stats(false); }
private:
PegCount* counts;
struct TrafficStats
{
- uint64_t packets_a_to_b;
- uint64_t bytes_a_to_b;
- uint64_t packets_b_to_a;
- uint64_t bytes_b_to_a;
+ PegCount packets_a_to_b;
+ PegCount bytes_a_to_b;
+ PegCount packets_b_to_a;
+ PegCount bytes_b_to_a;
};
struct FlowStateValue
uint8_t* PacketManager::encode_get_dst_mac()
{ return dst_mac; }
-uint64_t PacketManager::get_rebuilt_packet_count()
+PegCount PacketManager::get_rebuilt_packet_count()
{ return total_rebuilt_pkts; }
void PacketManager::encode_set_pkt(Packet* p)
return true;
}
-void StreamModule::sum_stats()
+void StreamModule::sum_stats(bool)
{ base_sum(); }
void StreamModule::show_stats()
ProfileStats* get_profile() const override;
const StreamModuleConfig* get_data();
- void sum_stats() override;
+ void sum_stats(bool) override;
void show_stats() override;
void reset_stats() override;
PegCount* StreamIcmpModule::get_counts() const
{ return (PegCount*)&icmpStats; }
+
+void StreamIcmpModule::sum_stats(bool accumulate_now_stats)
+{
+ assert(sizeof(IcmpStats)/sizeof(PegCount) == sizeof(IcmpStatTypes)/sizeof(CountType));
+
+ static const IcmpStatTypes icmp_stat_types;
+ static const CountType* const count_types = (const CountType* const)&icmp_stat_types;
+
+ sum_stats_helper(accumulate_now_stats, count_types);
+}
+
SESSION_STATS;
};
+struct IcmpStatTypes
+{
+ SESSION_STAT_TYPES;
+
+ IcmpStatTypes() {}
+};
+
//-------------------------------------------------------------------------
// stream_icmp module
//-------------------------------------------------------------------------
ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
+ void sum_stats(bool) override;
StreamIcmpConfig* get_data();
PegCount* StreamIpModule::get_counts() const
{ return (PegCount*)&ip_stats; }
+void StreamIpModule::sum_stats(bool accumulate_now_stats)
+{
+ assert(sizeof(IpStats)/sizeof(PegCount) == sizeof(IpStatTypes)/sizeof(CountType));
+
+ static const IpStatTypes ip_stat_types;
+ static const CountType* const count_types = (const CountType* const)&ip_stat_types;
+
+ sum_stats_helper(accumulate_now_stats, count_types);
+}
+
{
SESSION_STATS;
PegCount total; // total_ipfragmented_packets
- PegCount current; // iCurrentFrags
+ PegCount current_frags; // iCurrentFrags
PegCount max_frags; // iMaxFrags
PegCount reassembles; // total_ipreassembled_packets / iFragFlushes
PegCount discards;
PegCount fragmented_bytes; // total_ipfragmented_bytes
};
+struct IpStatTypes
+{
+ SESSION_STAT_TYPES;
+ CountType total = CountType::SUM;
+ CountType current_frags = CountType::NOW;
+
+ // FIXIT-M max_frags appears to be unused.
+ CountType max_frags = CountType::SUM;
+
+ CountType reassembles = CountType::SUM;
+ CountType discards = CountType::SUM;
+ CountType frag_timeouts = CountType::SUM;
+ CountType overlaps = CountType::SUM;
+ CountType anomalies = CountType::SUM;
+ CountType alerts = CountType::SUM;
+ CountType drops = CountType::SUM;
+ CountType trackers_created = CountType::SUM;
+ CountType trackers_released = CountType::SUM;
+ CountType trackers_cleared = CountType::SUM;
+ CountType trackers_completed = CountType::SUM;
+ CountType nodes_created = CountType::SUM;
+ CountType nodes_released = CountType::SUM;
+ CountType mem_in_use = CountType::NOW;
+ CountType reassembled_bytes = CountType::SUM;
+ CountType fragmented_bytes = CountType::SUM;
+
+ IpStatTypes() {}
+};
+
extern const PegInfo ip_pegs[];
extern THREAD_LOCAL struct IpStats ip_stats;
extern THREAD_LOCAL ProfileStats ip_perf_stats;
ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
+ void sum_stats(bool) override;
StreamIpConfig* get_data();
unsigned get_gid() const override
void IpSession::clear()
{
+ if(tracker.engine)
+ {
+ // Only decrement if the tracker was not already cleaned up.
+ assert(ip_stats.current_frags);
+ ip_stats.current_frags--;
+ }
+
IpSessionCleanup(flow, &tracker);
IpHAManager::process_deletion(flow);
- ip_stats.current--;
}
bool IpSession::setup(Packet*)
memset(&tracker, 0, sizeof(tracker));
SESSION_STATS_ADD(ip_stats);
ip_stats.trackers_created++;
- ip_stats.current++;
+ ip_stats.current_frags++;
#ifdef ENABLE_EXPECTED_IP
if ( Stream::expected_flow(flow, p) )
#ifndef STREAM_TCP_H
#define STREAM_TCP_H
-class Flow;
class Inspector;
class TcpStreamConfig;
-class Session;
-// misc stuff
-Session* get_tcp_session(Flow*);
TcpStreamConfig* get_tcp_cfg(Inspector*);
-void tcp_sinit();
-void tcp_sterm();
-void tcp_sum();
-void tcp_stats();
-void tcp_reset_stats();
-void tcp_show(TcpStreamConfig*);
-
#endif
{ "rebuilt_bytes", "total rebuilt bytes" },
{ "overlaps", "overlapping segments queued" },
{ "gaps", "missing data between PDUs" },
- { "max_segs", "number of times the maximum queued segment limit was reached" },
- { "max_bytes", "number of times the maximum queued byte limit was reached" },
+ { "exceeded_max_segs", "number of times the maximum queued segment limit was reached" },
+ { "exceeded_max_bytes", "number of times the maximum queued byte limit was reached" },
{ "internal_events", "135:X events generated" },
{ "client_cleanups", "number of times data from server was flushed when session released" },
{ "server_cleanups", "number of times data from client was flushed when session released" },
PegCount* StreamTcpModule::get_counts() const
{ return (PegCount*)&tcpStats; }
+void StreamTcpModule::sum_stats(bool accumulate_now_stats)
+{
+ assert(sizeof(TcpStats)/sizeof(PegCount) == sizeof(TcpStatTypes)/sizeof(CountType));
+
+ static const TcpStatTypes tcp_stat_types;
+ static const CountType* const count_types = (const CountType* const)&tcp_stat_types;
+
+ sum_stats_helper(accumulate_now_stats, count_types);
+}
+
PegCount rebuilt_bytes; //total_rebuilt_bytes
PegCount overlaps;
PegCount gaps;
- PegCount max_segs;
- PegCount max_bytes;
+ PegCount exceeded_max_segs;
+ PegCount exceeded_max_bytes;
PegCount internalEvents;
PegCount s5tcp1;
PegCount s5tcp2;
PegCount sessions_closing;
};
+struct TcpStatTypes
+{
+ SESSION_STAT_TYPES;
+ CountType resyns = CountType::SUM;
+ CountType discards = CountType::SUM;
+ CountType events = CountType::SUM;
+ CountType sessions_ignored = CountType::SUM;
+ CountType no_pickups = CountType::SUM;
+ CountType sessions_on_syn = CountType::SUM;
+ CountType sessions_on_syn_ack = CountType::SUM;
+ CountType sessions_on_3way = CountType::SUM;
+ CountType sessions_on_data = CountType::SUM;
+ CountType segs_queued = CountType::SUM;
+ CountType segs_released = CountType::SUM;
+ CountType segs_split = CountType::SUM;
+ CountType segs_used = CountType::SUM;
+ CountType rebuilt_packets = CountType::SUM;
+ CountType rebuilt_buffers = CountType::SUM;
+ CountType rebuilt_bytes = CountType::SUM;
+ CountType overlaps = CountType::SUM;
+ CountType gaps = CountType::SUM;
+ CountType exceeded_max_segs = CountType::SUM;
+ CountType exceeded_max_bytes = CountType::SUM;
+ CountType internalEvents = CountType::SUM;
+ CountType s5tcp1 = CountType::SUM;
+ CountType s5tcp2 = CountType::SUM;
+ CountType mem_in_use = CountType::NOW;
+ CountType sessions_initializing = CountType::NOW;
+ CountType sessions_established = CountType::NOW;
+ CountType sessions_closing = CountType::NOW;
+
+ TcpStatTypes() {}
+};
+
extern THREAD_LOCAL struct TcpStats tcpStats;
inline void inc_tcp_discards()
ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
+ void sum_stats(bool) override;
private:
TcpStreamConfig* config;
if ( ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
&& !( session_flags & SSNFLAG_COUNTED_CLOSING ) )
{
- //assert(tcpStats.sessions_initializing);
- if ( tcpStats.sessions_initializing ) // FIXIT-L eliminate / fix underflow
- tcpStats.sessions_initializing--;
+ assert(tcpStats.sessions_initializing);
+ tcpStats.sessions_initializing--;
}
}
break;
if ( session_flags & SSNFLAG_COUNTED_ESTABLISH )
{
- //assert(tcpStats.sessions_established);
+ assert(tcpStats.sessions_established);
tcpStats.sessions_established--;
if (perfmon_config && (perfmon_config->perf_flags & PERF_FLOWIP))
}
else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
{
- //assert(tcpStats.sessions_initializing);
- if ( tcpStats.sessions_initializing ) // FIXIT-L eliminate / fix underflow
- tcpStats.sessions_initializing--;
+ assert(tcpStats.sessions_initializing);
+ tcpStats.sessions_initializing--;
}
}
break;
case TcpStreamTracker::TCP_CLOSED:
- if ( session_flags & SSNFLAG_COUNTED_CLOSING )
- {
- //assert(tcpStats.sessions_closing);
- tcpStats.sessions_closing--;
- }
- else if ( session_flags & SSNFLAG_COUNTED_ESTABLISH )
+ if ( !( session_flags & SSNFLAG_COUNTED_CLOSED ) )
{
- //assert(tcpStats.sessions_established);
- if ( tcpStats.sessions_established ) // FIXIT-L eliminate / fix underflow
+ session_flags |= SSNFLAG_COUNTED_CLOSED;
+
+ if ( session_flags & SSNFLAG_COUNTED_CLOSING )
+ {
+ assert(tcpStats.sessions_closing);
+ tcpStats.sessions_closing--;
+ }
+ else if ( session_flags & SSNFLAG_COUNTED_ESTABLISH )
+ {
+ assert(tcpStats.sessions_established);
tcpStats.sessions_established--;
- if ( perfmon_config && ( perfmon_config->perf_flags & PERF_FLOWIP ) )
- perf_flow_ip->update_state(&flow->client_ip,
- &flow->server_ip, SFS_STATE_TCP_CLOSED);
- }
- else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
- {
- //assert(tcpStats.sessions_initializing);
- if ( tcpStats.sessions_initializing ) // FIXIT-L eliminate / fix underflow
+ if ( perfmon_config && ( perfmon_config->perf_flags & PERF_FLOWIP ) )
+ perf_flow_ip->update_state(&flow->client_ip,
+ &flow->server_ip, SFS_STATE_TCP_CLOSED);
+ }
+ else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
+ {
+ assert(tcpStats.sessions_initializing);
tcpStats.sessions_initializing--;
+ }
}
break;
if ( config->max_queued_bytes
&& ( listener->reassembler->get_seg_bytes_total() > config->max_queued_bytes ) )
{
- tcpStats.max_bytes++;
+ tcpStats.exceeded_max_bytes++;
// FIXIT-H add one alert per flow per above
return true;
}
if ( config->max_queued_segs
&& ( listener->reassembler->get_seg_count() + 1 > config->max_queued_segs ) )
{
- tcpStats.max_segs++;
+ tcpStats.exceeded_max_segs++;
// FIXIT-H add one alert per flow per above
return true;
}