mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/empty-lines'
* origin/topic/jsiwek/empty-lines: Add 'smtp_excessive_pending_cmds' weird Fix SMTP command string comparisons Improve handling of empty lines in several text protocol analyzers Add rate-limiting sampling mechanism for weird events Teach timestamp canonifier about timestamps before ~2001
This commit is contained in:
commit
bcf97f70ea
31 changed files with 1078 additions and 15 deletions
16
NEWS
16
NEWS
|
@ -409,6 +409,7 @@ Changed Functionality
|
||||||
- The string_to_pattern() built-in (and the now-deprecated merge_pattern()
|
- The string_to_pattern() built-in (and the now-deprecated merge_pattern()
|
||||||
built-in) is no longer restricted to only be called at initialization time.
|
built-in) is no longer restricted to only be called at initialization time.
|
||||||
|
|
||||||
|
|
||||||
- GeoIP Legacy Database support has been replaced with GeoIP2 MaxMind DB
|
- GeoIP Legacy Database support has been replaced with GeoIP2 MaxMind DB
|
||||||
format support.
|
format support.
|
||||||
|
|
||||||
|
@ -418,6 +419,21 @@ Changed Functionality
|
||||||
after January 2, 2019. It's also noted that all GeoIP Legacy databases
|
after January 2, 2019. It's also noted that all GeoIP Legacy databases
|
||||||
may be discontinued as they are superseded by GeoIP2.
|
may be discontinued as they are superseded by GeoIP2.
|
||||||
|
|
||||||
|
- "Weird" events are now generally suppressed/sampled by default according to
|
||||||
|
some tunable parameters:
|
||||||
|
|
||||||
|
- Weird::sampling_whitelist
|
||||||
|
- Weird::sampling_threshold
|
||||||
|
- Weird::sampling_rate
|
||||||
|
- Weird::sampling_duration
|
||||||
|
|
||||||
|
Those options can be changed if one needs the previous behavior of
|
||||||
|
a "net_weird", "flow_weird", or "conn_weird" event being raised for
|
||||||
|
every single event. Otherwise, there is a new weird_stats.log which
|
||||||
|
contains concise summaries of weird counts per type per time period
|
||||||
|
and the original weird.log may not differ much either, except in
|
||||||
|
the cases where a particular weird type exceeds the sampling threshold.
|
||||||
|
|
||||||
Removed Functionality
|
Removed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,8 @@ Miscellaneous
|
||||||
+----------------------------+---------------------------------------+---------------------------------+
|
+----------------------------+---------------------------------------+---------------------------------+
|
||||||
| weird.log | Unexpected network-level activity | :bro:type:`Weird::Info` |
|
| weird.log | Unexpected network-level activity | :bro:type:`Weird::Info` |
|
||||||
+----------------------------+---------------------------------------+---------------------------------+
|
+----------------------------+---------------------------------------+---------------------------------+
|
||||||
|
| weird-stats.log | Statistics about unexpected activity | :bro:type:`WeirdStats::Info` |
|
||||||
|
+----------------------------+---------------------------------------+---------------------------------+
|
||||||
|
|
||||||
Bro Diagnostics
|
Bro Diagnostics
|
||||||
---------------
|
---------------
|
||||||
|
|
|
@ -82,6 +82,13 @@ type addr_vec: vector of addr;
|
||||||
## directly and then remove this alias.
|
## directly and then remove this alias.
|
||||||
type table_string_of_string: table[string] of string;
|
type table_string_of_string: table[string] of string;
|
||||||
|
|
||||||
|
## A table of counts indexed by strings.
|
||||||
|
##
|
||||||
|
## .. todo:: We need this type definition only for declaring builtin functions
|
||||||
|
## via ``bifcl``. We should extend ``bifcl`` to understand composite types
|
||||||
|
## directly and then remove this alias.
|
||||||
|
type table_string_of_count: table[string] of count;
|
||||||
|
|
||||||
## A set of file analyzer tags.
|
## A set of file analyzer tags.
|
||||||
##
|
##
|
||||||
## .. todo:: We need this type definition only for declaring builtin functions
|
## .. todo:: We need this type definition only for declaring builtin functions
|
||||||
|
@ -626,6 +633,17 @@ type BrokerStats: record {
|
||||||
num_ids_outgoing: count;
|
num_ids_outgoing: count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
## Statistics about reporter messages and weirds.
|
||||||
|
##
|
||||||
|
## .. bro:see:: get_reporter_stats
|
||||||
|
type ReporterStats: record {
|
||||||
|
## Number of total weirds encountered, before any rate-limiting.
|
||||||
|
weirds: count;
|
||||||
|
## Number of times each individual weird is encountered, before any
|
||||||
|
## rate-limiting is applied.
|
||||||
|
weirds_by_type: table[string] of count;
|
||||||
|
};
|
||||||
|
|
||||||
## Deprecated.
|
## Deprecated.
|
||||||
##
|
##
|
||||||
## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere
|
## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere
|
||||||
|
@ -4826,6 +4844,35 @@ export {
|
||||||
type Cluster::Pool: record {};
|
type Cluster::Pool: record {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module Weird;
|
||||||
|
export {
|
||||||
|
## Prevents rate-limiting sampling of any weirds named in the table.
|
||||||
|
const sampling_whitelist: set[string] &redef;
|
||||||
|
|
||||||
|
## How many weirds of a given type to tolerate before sampling begins.
|
||||||
|
## i.e. this many consecutive weirds of a given type will be allowed to
|
||||||
|
## raise events for script-layer handling before being rate-limited.
|
||||||
|
const sampling_threshold = 25 &redef;
|
||||||
|
|
||||||
|
## The rate-limiting sampling rate. One out of every of this number of
|
||||||
|
## rate-limited weirds of a given type will be allowed to raise events
|
||||||
|
## for further script-layer handling.
|
||||||
|
const sampling_rate = 1000 &redef;
|
||||||
|
|
||||||
|
## How long a weird of a given type is allowed to keep state/counters in
|
||||||
|
## memory. For "net" weirds an expiration timer starts per weird name when
|
||||||
|
## first initializing its counter. For "flow" weirds an expiration timer
|
||||||
|
## starts once per src/dst IP pair for the first weird of any name. For
|
||||||
|
## "conn" weirds, counters and expiration timers are kept for the duration
|
||||||
|
## of the connection for each named weird and reset when necessary. e.g.
|
||||||
|
## if a "conn" weird by the name of "foo" is seen more than
|
||||||
|
## :bro:see:`Weird::sampling_threshold` times, then an expiration timer
|
||||||
|
## begins for "foo" and upon triggering will reset the counter for "foo"
|
||||||
|
## and unthrottle its rate-limiting until it once again exceeds the
|
||||||
|
## threshold.
|
||||||
|
const sampling_duration = 10min &redef;
|
||||||
|
}
|
||||||
|
|
||||||
module GLOBAL;
|
module GLOBAL;
|
||||||
|
|
||||||
## Seed for hashes computed internally for probabilistic data structures. Using
|
## Seed for hashes computed internally for probabilistic data structures. Using
|
||||||
|
|
|
@ -199,7 +199,7 @@ event http_request(c: connection, method: string, original_URI: string,
|
||||||
c$http$uri = unescaped_URI;
|
c$http$uri = unescaped_URI;
|
||||||
|
|
||||||
if ( method !in http_methods )
|
if ( method !in http_methods )
|
||||||
event conn_weird("unknown_HTTP_method", c, method);
|
Reporter::conn_weird("unknown_HTTP_method", c, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
event http_reply(c: connection, version: string, code: count, reason: string) &priority=5
|
event http_reply(c: connection, version: string, code: count, reason: string) &priority=5
|
||||||
|
|
|
@ -168,7 +168,7 @@ event sip_request(c: connection, method: string, original_URI: string, version:
|
||||||
c$sip$uri = original_URI;
|
c$sip$uri = original_URI;
|
||||||
|
|
||||||
if ( method !in sip_methods )
|
if ( method !in sip_methods )
|
||||||
event conn_weird("unknown_SIP_method", c, method);
|
Reporter::conn_weird("unknown_SIP_method", c, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
event sip_reply(c: connection, version: string, code: count, reason: string) &priority=5
|
event sip_reply(c: connection, version: string, code: count, reason: string) &priority=5
|
||||||
|
|
|
@ -309,7 +309,7 @@ event smb_pipe_request(c: connection, hdr: SMB1::Header, op_num: count)
|
||||||
if ( ! f?$uuid )
|
if ( ! f?$uuid )
|
||||||
{
|
{
|
||||||
# TODO: figure out why this is happening.
|
# TODO: figure out why this is happening.
|
||||||
event conn_weird("smb_pipe_request_missing_uuid", c, "");
|
Reporter::conn_weird("smb_pipe_request_missing_uuid", c, "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
local arg = fmt("%s: %s",
|
local arg = fmt("%s: %s",
|
||||||
|
|
|
@ -263,7 +263,7 @@ event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec)
|
||||||
{
|
{
|
||||||
c$ssl$server_name = names[0];
|
c$ssl$server_name = names[0];
|
||||||
if ( |names| > 1 )
|
if ( |names| > 1 )
|
||||||
event conn_weird("SSL_many_server_names", c, cat(names));
|
Reporter::conn_weird("SSL_many_server_names", c, cat(names));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
100
scripts/policy/misc/weird-stats.bro
Normal file
100
scripts/policy/misc/weird-stats.bro
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
##! Log weird statistics.
|
||||||
|
|
||||||
|
@load base/frameworks/sumstats
|
||||||
|
@load base/frameworks/cluster
|
||||||
|
|
||||||
|
module WeirdStats;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
|
## How often stats are reported.
|
||||||
|
const weird_stat_interval = 15min &redef;
|
||||||
|
|
||||||
|
type Info: record {
|
||||||
|
## Timestamp for the measurement.
|
||||||
|
ts: time &log;
|
||||||
|
## Name of the weird.
|
||||||
|
name: string &log;
|
||||||
|
## Number of times weird was seen since the last stats interval.
|
||||||
|
num_seen: count &log;
|
||||||
|
};
|
||||||
|
|
||||||
|
global log_weird_stats: event(rec: Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
global this_epoch_weirds: table[string] of double;
|
||||||
|
global last_epoch_weirds: table[string] of double;
|
||||||
|
|
||||||
|
function weird_epoch_results(ts: time, key: SumStats::Key, result: SumStats::Result)
|
||||||
|
{
|
||||||
|
this_epoch_weirds[key$str]=result["weirds.encountered"]$sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
function weird_epoch_finished(ts: time)
|
||||||
|
{
|
||||||
|
for ( n in this_epoch_weirds )
|
||||||
|
{
|
||||||
|
local last_count: double = 0.0;
|
||||||
|
|
||||||
|
if ( n in last_epoch_weirds )
|
||||||
|
last_count = last_epoch_weirds[n];
|
||||||
|
|
||||||
|
local num_seen: double = this_epoch_weirds[n] - last_count;
|
||||||
|
|
||||||
|
if ( num_seen > 0.0 )
|
||||||
|
Log::write(LOG, Info($ts = ts, $name = n,
|
||||||
|
$num_seen = double_to_count(num_seen)));
|
||||||
|
}
|
||||||
|
|
||||||
|
last_epoch_weirds = this_epoch_weirds;
|
||||||
|
this_epoch_weirds = table();
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init() &priority=5
|
||||||
|
{
|
||||||
|
Log::create_stream(WeirdStats::LOG,
|
||||||
|
[$columns = Info, $ev = log_weird_stats,
|
||||||
|
$path="weird_stats"]);
|
||||||
|
local r1 = SumStats::Reducer($stream = "weirds.encountered",
|
||||||
|
$apply = set(SumStats::SUM));
|
||||||
|
SumStats::create([$name = "weirds.statistics",
|
||||||
|
$epoch = weird_stat_interval, $reducers = set(r1),
|
||||||
|
$epoch_result = weird_epoch_results,
|
||||||
|
$epoch_finished = weird_epoch_finished]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module SumStats;
|
||||||
|
|
||||||
|
function observe_weird_stats()
|
||||||
|
{
|
||||||
|
local rs = get_reporter_stats();
|
||||||
|
|
||||||
|
for ( n in rs$weirds_by_type )
|
||||||
|
SumStats::observe("weirds.encountered", SumStats::Key($str = n),
|
||||||
|
SumStats::Observation($dbl=rs$weirds_by_type[n]+0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ( Cluster::is_enabled() )
|
||||||
|
|
||||||
|
# I'm not sure if this is a hack or not: the manager will generate this
|
||||||
|
# event at the end of its epoch so workers can handle it just in time to
|
||||||
|
# generate the necessary stats. Alternative may be workers generating the
|
||||||
|
# stats individually/proactively in their own finish_epoch, but that may be
|
||||||
|
# less synchronized?
|
||||||
|
event SumStats::cluster_ss_request(uid: string, ss_name: string, cleanup: bool) &priority=10
|
||||||
|
{
|
||||||
|
observe_weird_stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@else
|
||||||
|
|
||||||
|
event SumStats::finish_epoch(ss: SumStat) &priority=10
|
||||||
|
{
|
||||||
|
if ( ss$name != "weirds.statistics" )
|
||||||
|
return;
|
||||||
|
|
||||||
|
observe_weird_stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@endif
|
|
@ -54,6 +54,7 @@
|
||||||
@load misc/profiling.bro
|
@load misc/profiling.bro
|
||||||
@load misc/scan.bro
|
@load misc/scan.bro
|
||||||
@load misc/stats.bro
|
@load misc/stats.bro
|
||||||
|
@load misc/weird-stats.bro
|
||||||
@load misc/trim-trace-file.bro
|
@load misc/trim-trace-file.bro
|
||||||
@load protocols/conn/known-hosts.bro
|
@load protocols/conn/known-hosts.bro
|
||||||
@load protocols/conn/known-services.bro
|
@load protocols/conn/known-services.bro
|
||||||
|
|
25
src/Conn.cc
25
src/Conn.cc
|
@ -1071,3 +1071,28 @@ void Connection::CheckFlowLabel(bool is_orig, uint32 flow_label)
|
||||||
else
|
else
|
||||||
saw_first_resp_packet = 1;
|
saw_first_resp_packet = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Connection::PermitWeird(const char* name, uint64 threshold, uint64 rate,
|
||||||
|
double duration)
|
||||||
|
{
|
||||||
|
auto& state = weird_state[name];
|
||||||
|
++state.count;
|
||||||
|
|
||||||
|
if ( state.count < threshold )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( state.count == threshold )
|
||||||
|
state.sampling_start_time = network_time;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( network_time > state.sampling_start_time + duration )
|
||||||
|
{
|
||||||
|
state.sampling_start_time = 0;
|
||||||
|
state.count = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_above_threshold = state.count - threshold;
|
||||||
|
return num_above_threshold % rate == 0;
|
||||||
|
}
|
||||||
|
|
14
src/Conn.h
14
src/Conn.h
|
@ -5,6 +5,9 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "Dict.h"
|
#include "Dict.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
@ -275,6 +278,9 @@ public:
|
||||||
uint32 GetOrigFlowLabel() { return orig_flow_label; }
|
uint32 GetOrigFlowLabel() { return orig_flow_label; }
|
||||||
uint32 GetRespFlowLabel() { return resp_flow_label; }
|
uint32 GetRespFlowLabel() { return resp_flow_label; }
|
||||||
|
|
||||||
|
bool PermitWeird(const char* name, uint64 threshold, uint64 rate,
|
||||||
|
double duration);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Connection() { persistent = 0; }
|
Connection() { persistent = 0; }
|
||||||
|
@ -339,6 +345,14 @@ protected:
|
||||||
analyzer::pia::PIA* primary_PIA;
|
analyzer::pia::PIA* primary_PIA;
|
||||||
|
|
||||||
Bro::UID uid; // Globally unique connection ID.
|
Bro::UID uid; // Globally unique connection ID.
|
||||||
|
|
||||||
|
struct WeirdState {
|
||||||
|
WeirdState() { count = 0; sampling_start_time = 0; }
|
||||||
|
uint64 count = 0;
|
||||||
|
double sampling_start_time = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, WeirdState> weird_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConnectionTimer : public Timer {
|
class ConnectionTimer : public Timer {
|
||||||
|
|
|
@ -722,6 +722,7 @@ void init_builtin_funcs()
|
||||||
FileAnalysisStats = internal_type("FileAnalysisStats")->AsRecordType();
|
FileAnalysisStats = internal_type("FileAnalysisStats")->AsRecordType();
|
||||||
ThreadStats = internal_type("ThreadStats")->AsRecordType();
|
ThreadStats = internal_type("ThreadStats")->AsRecordType();
|
||||||
BrokerStats = internal_type("BrokerStats")->AsRecordType();
|
BrokerStats = internal_type("BrokerStats")->AsRecordType();
|
||||||
|
ReporterStats = internal_type("ReporterStats")->AsRecordType();
|
||||||
|
|
||||||
var_sizes = internal_type("var_sizes")->AsTableType();
|
var_sizes = internal_type("var_sizes")->AsTableType();
|
||||||
|
|
||||||
|
|
132
src/Reporter.cc
132
src/Reporter.cc
|
@ -10,6 +10,7 @@
|
||||||
#include "NetVar.h"
|
#include "NetVar.h"
|
||||||
#include "Net.h"
|
#include "Net.h"
|
||||||
#include "Conn.h"
|
#include "Conn.h"
|
||||||
|
#include "Timer.h"
|
||||||
#include "plugin/Plugin.h"
|
#include "plugin/Plugin.h"
|
||||||
#include "plugin/Manager.h"
|
#include "plugin/Manager.h"
|
||||||
|
|
||||||
|
@ -36,6 +37,11 @@ Reporter::Reporter()
|
||||||
warnings_to_stderr = true;
|
warnings_to_stderr = true;
|
||||||
errors_to_stderr = true;
|
errors_to_stderr = true;
|
||||||
|
|
||||||
|
weird_count = 0;
|
||||||
|
weird_sampling_rate = 0;
|
||||||
|
weird_sampling_duration = 0;
|
||||||
|
weird_sampling_threshold = 0;
|
||||||
|
|
||||||
openlog("bro", 0, LOG_LOCAL5);
|
openlog("bro", 0, LOG_LOCAL5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +55,24 @@ void Reporter::InitOptions()
|
||||||
info_to_stderr = internal_const_val("Reporter::info_to_stderr")->AsBool();
|
info_to_stderr = internal_const_val("Reporter::info_to_stderr")->AsBool();
|
||||||
warnings_to_stderr = internal_const_val("Reporter::warnings_to_stderr")->AsBool();
|
warnings_to_stderr = internal_const_val("Reporter::warnings_to_stderr")->AsBool();
|
||||||
errors_to_stderr = internal_const_val("Reporter::errors_to_stderr")->AsBool();
|
errors_to_stderr = internal_const_val("Reporter::errors_to_stderr")->AsBool();
|
||||||
|
weird_sampling_rate = internal_const_val("Weird::sampling_rate")->AsCount();
|
||||||
|
weird_sampling_threshold = internal_const_val("Weird::sampling_threshold")->AsCount();
|
||||||
|
weird_sampling_duration = internal_const_val("Weird::sampling_duration")->AsInterval();
|
||||||
|
auto wl_val = internal_const_val("Weird::sampling_whitelist")->AsTableVal();
|
||||||
|
auto wl_table = wl_val->AsTable();
|
||||||
|
|
||||||
|
HashKey* k;
|
||||||
|
IterCookie* c = wl_table->InitForIteration();
|
||||||
|
TableEntryVal* v;
|
||||||
|
|
||||||
|
while ( (v = wl_table->NextEntry(k, c)) )
|
||||||
|
{
|
||||||
|
auto index = wl_val->RecoverIndex(k);
|
||||||
|
string key = index->Index(0)->AsString()->CheckString();
|
||||||
|
weird_sampling_whitelist.emplace(move(key));
|
||||||
|
Unref(index);
|
||||||
|
delete k;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reporter::Info(const char* fmt, ...)
|
void Reporter::Info(const char* fmt, ...)
|
||||||
|
@ -221,23 +245,121 @@ void Reporter::WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const cha
|
||||||
delete vl;
|
delete vl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reporter::UpdateWeirdStats(const char* name)
|
||||||
|
{
|
||||||
|
++weird_count;
|
||||||
|
++weird_count_by_type[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetWeirdTimer : public Timer {
|
||||||
|
public:
|
||||||
|
NetWeirdTimer(double t, const char* name, double timeout)
|
||||||
|
: Timer(t + timeout, TIMER_NET_WEIRD_EXPIRE), weird_name(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Dispatch(double t, int is_expire) override
|
||||||
|
{ reporter->ResetNetWeird(weird_name); }
|
||||||
|
|
||||||
|
std::string weird_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FlowWeirdTimer : public Timer {
|
||||||
|
public:
|
||||||
|
using IPPair = std::pair<IPAddr, IPAddr>;
|
||||||
|
|
||||||
|
FlowWeirdTimer(double t, IPPair p, double timeout)
|
||||||
|
: Timer(t + timeout, TIMER_FLOW_WEIRD_EXPIRE), endpoints(p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Dispatch(double t, int is_expire) override
|
||||||
|
{ reporter->ResetFlowWeird(endpoints.first, endpoints.second); }
|
||||||
|
|
||||||
|
IPPair endpoints;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Reporter::ResetNetWeird(const std::string& name)
|
||||||
|
{
|
||||||
|
net_weird_state.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reporter::ResetFlowWeird(const IPAddr& orig, const IPAddr& resp)
|
||||||
|
{
|
||||||
|
flow_weird_state.erase(std::make_pair(orig, resp));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Reporter::PermitNetWeird(const char* name)
|
||||||
|
{
|
||||||
|
auto& count = net_weird_state[name];
|
||||||
|
++count;
|
||||||
|
|
||||||
|
if ( count == 1 )
|
||||||
|
timer_mgr->Add(new NetWeirdTimer(network_time, name,
|
||||||
|
weird_sampling_duration));
|
||||||
|
|
||||||
|
if ( count < weird_sampling_threshold )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto num_above_threshold = count - weird_sampling_threshold;
|
||||||
|
return num_above_threshold % weird_sampling_rate == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Reporter::PermitFlowWeird(const char* name,
|
||||||
|
const IPAddr& orig, const IPAddr& resp)
|
||||||
|
{
|
||||||
|
auto endpoints = std::make_pair(orig, resp);
|
||||||
|
auto& map = flow_weird_state[endpoints];
|
||||||
|
|
||||||
|
if ( map.empty() )
|
||||||
|
timer_mgr->Add(new FlowWeirdTimer(network_time, endpoints,
|
||||||
|
weird_sampling_duration));
|
||||||
|
|
||||||
|
auto& count = map[name];
|
||||||
|
++count;
|
||||||
|
|
||||||
|
if ( count < weird_sampling_threshold )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto num_above_threshold = count - weird_sampling_threshold;
|
||||||
|
return num_above_threshold % weird_sampling_rate == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Reporter::Weird(const char* name)
|
void Reporter::Weird(const char* name)
|
||||||
{
|
{
|
||||||
|
UpdateWeirdStats(name);
|
||||||
|
|
||||||
|
if ( ! WeirdOnSamplingWhiteList(name) )
|
||||||
|
{
|
||||||
|
if ( ! PermitNetWeird(name) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WeirdHelper(net_weird, 0, 0, "%s", name);
|
WeirdHelper(net_weird, 0, 0, "%s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reporter::Weird(Connection* conn, const char* name, const char* addl)
|
void Reporter::Weird(Connection* conn, const char* name, const char* addl)
|
||||||
{
|
{
|
||||||
WeirdHelper(conn_weird, conn->BuildConnVal(), addl, "%s", name);
|
UpdateWeirdStats(name);
|
||||||
}
|
|
||||||
|
|
||||||
void Reporter::Weird(Val* conn_val, const char* name, const char* addl)
|
if ( ! WeirdOnSamplingWhiteList(name) )
|
||||||
{
|
{
|
||||||
WeirdHelper(conn_weird, conn_val, addl, "%s", name);
|
if ( ! conn->PermitWeird(name, weird_sampling_threshold,
|
||||||
|
weird_sampling_rate, weird_sampling_duration) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeirdHelper(conn_weird, conn->BuildConnVal(), addl, "%s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name)
|
void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name)
|
||||||
{
|
{
|
||||||
|
UpdateWeirdStats(name);
|
||||||
|
|
||||||
|
if ( ! WeirdOnSamplingWhiteList(name) )
|
||||||
|
{
|
||||||
|
if ( ! PermitFlowWeird(name, orig, resp) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WeirdFlowHelper(orig, resp, "%s", name);
|
WeirdFlowHelper(orig, resp, "%s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "EventHandler.h"
|
#include "EventHandler.h"
|
||||||
|
@ -36,6 +40,11 @@ protected:
|
||||||
|
|
||||||
class Reporter {
|
class Reporter {
|
||||||
public:
|
public:
|
||||||
|
using IPPair = std::pair<IPAddr, IPAddr>;
|
||||||
|
using WeirdCountMap = std::unordered_map<std::string, uint64>;
|
||||||
|
using WeirdFlowMap = std::map<IPPair, WeirdCountMap>;
|
||||||
|
using WeirdSet = std::unordered_set<std::string>;
|
||||||
|
|
||||||
Reporter();
|
Reporter();
|
||||||
~Reporter();
|
~Reporter();
|
||||||
|
|
||||||
|
@ -76,7 +85,6 @@ public:
|
||||||
// that may lead to incorrectly processing a connnection.
|
// that may lead to incorrectly processing a connnection.
|
||||||
void Weird(const char* name); // Raises net_weird().
|
void Weird(const char* name); // Raises net_weird().
|
||||||
void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_weird().
|
void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_weird().
|
||||||
void Weird(Val* conn_val, const char* name, const char* addl = ""); // Raises conn_weird().
|
|
||||||
void Weird(const IPAddr& orig, const IPAddr& resp, const char* name); // Raises flow_weird().
|
void Weird(const IPAddr& orig, const IPAddr& resp, const char* name); // Raises flow_weird().
|
||||||
|
|
||||||
// Syslog a message. This methods does nothing if we're running
|
// Syslog a message. This methods does nothing if we're running
|
||||||
|
@ -120,6 +128,30 @@ public:
|
||||||
// Signals that we're done processing an error handler event.
|
// Signals that we're done processing an error handler event.
|
||||||
void EndErrorHandler() { --in_error_handler; }
|
void EndErrorHandler() { --in_error_handler; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset/cleanup state tracking for a "net" weird.
|
||||||
|
*/
|
||||||
|
void ResetNetWeird(const std::string& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset/cleanup state tracking for a "flow" weird.
|
||||||
|
*/
|
||||||
|
void ResetFlowWeird(const IPAddr& orig, const IPAddr& resp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the total number of weirds generated (counts weirds before
|
||||||
|
* any rate-limiting occurs).
|
||||||
|
*/
|
||||||
|
uint64 GetWeirdCount() const
|
||||||
|
{ return weird_count; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return number of weirds generated per weird type/name (counts weirds
|
||||||
|
* before any rate-limiting occurs).
|
||||||
|
*/
|
||||||
|
const WeirdCountMap& GetWeirdsByType() const
|
||||||
|
{ return weird_count_by_type; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
|
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
|
||||||
Connection* conn, val_list* addl, bool location, bool time,
|
Connection* conn, val_list* addl, bool location, bool time,
|
||||||
|
@ -129,6 +161,11 @@ private:
|
||||||
// contain format specifiers
|
// contain format specifiers
|
||||||
void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...) __attribute__((format(printf, 5, 6)));;
|
void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...) __attribute__((format(printf, 5, 6)));;
|
||||||
void WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...) __attribute__((format(printf, 4, 5)));;
|
void WeirdFlowHelper(const IPAddr& orig, const IPAddr& resp, const char* fmt_name, ...) __attribute__((format(printf, 4, 5)));;
|
||||||
|
void UpdateWeirdStats(const char* name);
|
||||||
|
inline bool WeirdOnSamplingWhiteList(const char* name)
|
||||||
|
{ return weird_sampling_whitelist.find(name) != weird_sampling_whitelist.end(); }
|
||||||
|
bool PermitNetWeird(const char* name);
|
||||||
|
bool PermitFlowWeird(const char* name, const IPAddr& o, const IPAddr& r);
|
||||||
|
|
||||||
int errors;
|
int errors;
|
||||||
bool via_events;
|
bool via_events;
|
||||||
|
@ -138,6 +175,18 @@ private:
|
||||||
bool errors_to_stderr;
|
bool errors_to_stderr;
|
||||||
|
|
||||||
std::list<std::pair<const Location*, const Location*> > locations;
|
std::list<std::pair<const Location*, const Location*> > locations;
|
||||||
|
|
||||||
|
uint64 weird_count;
|
||||||
|
WeirdCountMap weird_count_by_type;
|
||||||
|
|
||||||
|
WeirdCountMap net_weird_state;
|
||||||
|
WeirdFlowMap flow_weird_state;
|
||||||
|
|
||||||
|
WeirdSet weird_sampling_whitelist;
|
||||||
|
uint64 weird_sampling_threshold;
|
||||||
|
uint64 weird_sampling_rate;
|
||||||
|
double weird_sampling_duration;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Reporter* reporter;
|
extern Reporter* reporter;
|
||||||
|
|
|
@ -18,12 +18,14 @@ const char* TimerNames[] = {
|
||||||
"ConnectionStatusUpdateTimer",
|
"ConnectionStatusUpdateTimer",
|
||||||
"DNSExpireTimer",
|
"DNSExpireTimer",
|
||||||
"FileAnalysisInactivityTimer",
|
"FileAnalysisInactivityTimer",
|
||||||
|
"FlowWeirdTimer",
|
||||||
"FragTimer",
|
"FragTimer",
|
||||||
"IncrementalSendTimer",
|
"IncrementalSendTimer",
|
||||||
"IncrementalWriteTimer",
|
"IncrementalWriteTimer",
|
||||||
"InterconnTimer",
|
"InterconnTimer",
|
||||||
"IPTunnelInactivityTimer",
|
"IPTunnelInactivityTimer",
|
||||||
"NetbiosExpireTimer",
|
"NetbiosExpireTimer",
|
||||||
|
"NetWeirdTimer",
|
||||||
"NetworkTimer",
|
"NetworkTimer",
|
||||||
"NTPExpireTimer",
|
"NTPExpireTimer",
|
||||||
"ProfileTimer",
|
"ProfileTimer",
|
||||||
|
|
|
@ -23,12 +23,14 @@ enum TimerType {
|
||||||
TIMER_CONN_STATUS_UPDATE,
|
TIMER_CONN_STATUS_UPDATE,
|
||||||
TIMER_DNS_EXPIRE,
|
TIMER_DNS_EXPIRE,
|
||||||
TIMER_FILE_ANALYSIS_INACTIVITY,
|
TIMER_FILE_ANALYSIS_INACTIVITY,
|
||||||
|
TIMER_FLOW_WEIRD_EXPIRE,
|
||||||
TIMER_FRAG,
|
TIMER_FRAG,
|
||||||
TIMER_INCREMENTAL_SEND,
|
TIMER_INCREMENTAL_SEND,
|
||||||
TIMER_INCREMENTAL_WRITE,
|
TIMER_INCREMENTAL_WRITE,
|
||||||
TIMER_INTERCONN,
|
TIMER_INTERCONN,
|
||||||
TIMER_IP_TUNNEL_INACTIVITY,
|
TIMER_IP_TUNNEL_INACTIVITY,
|
||||||
TIMER_NB_EXPIRE,
|
TIMER_NB_EXPIRE,
|
||||||
|
TIMER_NET_WEIRD_EXPIRE,
|
||||||
TIMER_NETWORK,
|
TIMER_NETWORK,
|
||||||
TIMER_NTP_EXPIRE,
|
TIMER_NTP_EXPIRE,
|
||||||
TIMER_PROFILE,
|
TIMER_PROFILE,
|
||||||
|
|
|
@ -41,6 +41,9 @@ void Finger_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig
|
||||||
const char* line = (const char*) data;
|
const char* line = (const char*) data;
|
||||||
const char* end_of_line = line + length;
|
const char* end_of_line = line + length;
|
||||||
|
|
||||||
|
if ( length == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( is_orig )
|
if ( is_orig )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ void FTP_Analyzer::DeliverStream(int length, const u_char* data, bool orig)
|
||||||
const char* line = (const char*) data;
|
const char* line = (const char*) data;
|
||||||
const char* end_of_line = line + length;
|
const char* end_of_line = line + length;
|
||||||
|
|
||||||
|
if ( length == 0 )
|
||||||
|
// Could emit "ftp empty request/reply" weird, but maybe not worth it.
|
||||||
|
return;
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,9 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
|
||||||
if ( TCP() )
|
if ( TCP() )
|
||||||
s = is_orig ? TCP()->Orig() : TCP()->Resp();
|
s = is_orig ? TCP()->Orig() : TCP()->Resp();
|
||||||
|
|
||||||
|
if ( length == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( is_orig )
|
if ( is_orig )
|
||||||
{
|
{
|
||||||
if ( ! ident_request )
|
if ( ! ident_request )
|
||||||
|
|
|
@ -132,6 +132,9 @@ static string trim_whitespace(const char* in)
|
||||||
|
|
||||||
void POP3_Analyzer::ProcessRequest(int length, const char* line)
|
void POP3_Analyzer::ProcessRequest(int length, const char* line)
|
||||||
{
|
{
|
||||||
|
if ( length == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( waitingForAuthentication )
|
if ( waitingForAuthentication )
|
||||||
{
|
{
|
||||||
++authLines;
|
++authLines;
|
||||||
|
|
|
@ -269,7 +269,9 @@ void SMTP_Analyzer::ProcessLine(int length, const char* line, bool orig)
|
||||||
if ( smtp_request )
|
if ( smtp_request )
|
||||||
{
|
{
|
||||||
int data_len = end_of_line - line;
|
int data_len = end_of_line - line;
|
||||||
RequestEvent(cmd_len, cmd, data_len, line);
|
|
||||||
|
if ( cmd_len > 0 || data_len > 0 )
|
||||||
|
RequestEvent(cmd_len, cmd, data_len, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cmd_code != SMTP_CMD_END_OF_DATA )
|
if ( cmd_code != SMTP_CMD_END_OF_DATA )
|
||||||
|
@ -379,7 +381,17 @@ void SMTP_Analyzer::NewCmd(const int cmd_code)
|
||||||
if ( first_cmd < 0 )
|
if ( first_cmd < 0 )
|
||||||
first_cmd = cmd_code;
|
first_cmd = cmd_code;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
auto constexpr max_pending_cmd_q_size = 1000;
|
||||||
|
|
||||||
|
if ( pending_cmd_q.size() == max_pending_cmd_q_size )
|
||||||
|
{
|
||||||
|
Weird("smtp_excessive_pending_cmds");
|
||||||
|
pending_cmd_q.clear();
|
||||||
|
}
|
||||||
|
|
||||||
pending_cmd_q.push_back(cmd_code);
|
pending_cmd_q.push_back(cmd_code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
first_cmd = cmd_code;
|
first_cmd = cmd_code;
|
||||||
|
@ -805,12 +817,22 @@ void SMTP_Analyzer::UpdateState(const int cmd_code, const int reply_code, bool o
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool istrequal(const char* s, const char* cmd, int s_len)
|
||||||
|
{
|
||||||
|
auto cmd_len = strlen(cmd);
|
||||||
|
|
||||||
|
if ( cmd_len != s_len )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return strncasecmp(s, cmd, s_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void SMTP_Analyzer::ProcessExtension(int ext_len, const char* ext)
|
void SMTP_Analyzer::ProcessExtension(int ext_len, const char* ext)
|
||||||
{
|
{
|
||||||
if ( ! ext )
|
if ( ! ext )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( ! strncasecmp(ext, "PIPELINING", ext_len) )
|
if ( istrequal(ext, "PIPELINING", ext_len) )
|
||||||
pipelining = 1;
|
pipelining = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,11 +842,11 @@ int SMTP_Analyzer::ParseCmd(int cmd_len, const char* cmd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// special case because we cannot define our usual macros with "-"
|
// special case because we cannot define our usual macros with "-"
|
||||||
if ( strncmp(cmd, "X-ANONYMOUSTLS", cmd_len) == 0 )
|
if ( istrequal(cmd, "X-ANONYMOUSTLS", cmd_len) )
|
||||||
return SMTP_CMD_X_ANONYMOUSTLS;
|
return SMTP_CMD_X_ANONYMOUSTLS;
|
||||||
|
|
||||||
for ( int code = SMTP_CMD_EHLO; code < SMTP_CMD_LAST; ++code )
|
for ( int code = SMTP_CMD_EHLO; code < SMTP_CMD_LAST; ++code )
|
||||||
if ( ! strncasecmp(cmd, smtp_cmd_word[code - SMTP_CMD_EHLO], cmd_len) )
|
if ( istrequal(cmd, smtp_cmd_word[code - SMTP_CMD_EHLO], cmd_len) )
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -71,3 +71,44 @@ function Reporter::fatal%(msg: string%): bool
|
||||||
reporter->PopLocation();
|
reporter->PopLocation();
|
||||||
return new Val(1, TYPE_BOOL);
|
return new Val(1, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
## Generates a "net" weird.
|
||||||
|
##
|
||||||
|
## name: the name of the weird.
|
||||||
|
##
|
||||||
|
## Returns: Always true.
|
||||||
|
function Reporter::net_weird%(name: string%): bool
|
||||||
|
%{
|
||||||
|
reporter->Weird(name->CheckString());
|
||||||
|
return new Val(1, TYPE_BOOL);
|
||||||
|
%}
|
||||||
|
|
||||||
|
## Generates a "flow" weird.
|
||||||
|
##
|
||||||
|
## name: the name of the weird.
|
||||||
|
##
|
||||||
|
## orig: the originator host associated with the weird.
|
||||||
|
##
|
||||||
|
## resp: the responder host associated with the weird.
|
||||||
|
##
|
||||||
|
## Returns: Always true.
|
||||||
|
function Reporter::flow_weird%(name: string, orig: addr, resp: addr%): bool
|
||||||
|
%{
|
||||||
|
reporter->Weird(orig->AsAddr(), resp->AsAddr(), name->CheckString());
|
||||||
|
return new Val(1, TYPE_BOOL);
|
||||||
|
%}
|
||||||
|
|
||||||
|
## Generates a "conn" weird.
|
||||||
|
##
|
||||||
|
## name: the name of the weird.
|
||||||
|
##
|
||||||
|
## c: the connection associated with the weird.
|
||||||
|
##
|
||||||
|
## addl: additional information to accompany the weird.
|
||||||
|
##
|
||||||
|
## Returns: Always true.
|
||||||
|
function Reporter::conn_weird%(name: string, c: connection, addl: string &default=""%): bool
|
||||||
|
%{
|
||||||
|
reporter->Weird(c, name->CheckString(), addl->CheckString());
|
||||||
|
return new Val(1, TYPE_BOOL);
|
||||||
|
%}
|
||||||
|
|
|
@ -16,6 +16,7 @@ RecordType* ThreadStats;
|
||||||
RecordType* TimerStats;
|
RecordType* TimerStats;
|
||||||
RecordType* FileAnalysisStats;
|
RecordType* FileAnalysisStats;
|
||||||
RecordType* BrokerStats;
|
RecordType* BrokerStats;
|
||||||
|
RecordType* ReporterStats;
|
||||||
%%}
|
%%}
|
||||||
|
|
||||||
## Returns packet capture statistics. Statistics include the number of
|
## Returns packet capture statistics. Statistics include the number of
|
||||||
|
@ -35,6 +36,7 @@ RecordType* BrokerStats;
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_net_stats%(%): NetStats
|
function get_net_stats%(%): NetStats
|
||||||
%{
|
%{
|
||||||
uint64 recv = 0;
|
uint64 recv = 0;
|
||||||
|
@ -83,6 +85,7 @@ function get_net_stats%(%): NetStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_conn_stats%(%): ConnStats
|
function get_conn_stats%(%): ConnStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(ConnStats);
|
RecordVal* r = new RecordVal(ConnStats);
|
||||||
|
@ -133,6 +136,7 @@ function get_conn_stats%(%): ConnStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_proc_stats%(%): ProcStats
|
function get_proc_stats%(%): ProcStats
|
||||||
%{
|
%{
|
||||||
struct rusage ru;
|
struct rusage ru;
|
||||||
|
@ -189,6 +193,7 @@ function get_proc_stats%(%): ProcStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_event_stats%(%): EventStats
|
function get_event_stats%(%): EventStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(EventStats);
|
RecordVal* r = new RecordVal(EventStats);
|
||||||
|
@ -215,6 +220,7 @@ function get_event_stats%(%): EventStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_reassembler_stats%(%): ReassemblerStats
|
function get_reassembler_stats%(%): ReassemblerStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(ReassemblerStats);
|
RecordVal* r = new RecordVal(ReassemblerStats);
|
||||||
|
@ -243,6 +249,7 @@ function get_reassembler_stats%(%): ReassemblerStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_dns_stats%(%): DNSStats
|
function get_dns_stats%(%): DNSStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(DNSStats);
|
RecordVal* r = new RecordVal(DNSStats);
|
||||||
|
@ -276,6 +283,7 @@ function get_dns_stats%(%): DNSStats
|
||||||
## get_reassembler_stats
|
## get_reassembler_stats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_timer_stats%(%): TimerStats
|
function get_timer_stats%(%): TimerStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(TimerStats);
|
RecordVal* r = new RecordVal(TimerStats);
|
||||||
|
@ -303,6 +311,7 @@ function get_timer_stats%(%): TimerStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_file_analysis_stats%(%): FileAnalysisStats
|
function get_file_analysis_stats%(%): FileAnalysisStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(FileAnalysisStats);
|
RecordVal* r = new RecordVal(FileAnalysisStats);
|
||||||
|
@ -330,6 +339,7 @@ function get_file_analysis_stats%(%): FileAnalysisStats
|
||||||
## get_reassembler_stats
|
## get_reassembler_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_thread_stats%(%): ThreadStats
|
function get_thread_stats%(%): ThreadStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(ThreadStats);
|
RecordVal* r = new RecordVal(ThreadStats);
|
||||||
|
@ -355,6 +365,7 @@ function get_thread_stats%(%): ThreadStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_gap_stats%(%): GapStats
|
function get_gap_stats%(%): GapStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(GapStats);
|
RecordVal* r = new RecordVal(GapStats);
|
||||||
|
@ -386,6 +397,7 @@ function get_gap_stats%(%): GapStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_matcher_stats%(%): MatcherStats
|
function get_matcher_stats%(%): MatcherStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(MatcherStats);
|
RecordVal* r = new RecordVal(MatcherStats);
|
||||||
|
@ -423,6 +435,7 @@ function get_matcher_stats%(%): MatcherStats
|
||||||
## get_thread_stats
|
## get_thread_stats
|
||||||
## get_timer_stats
|
## get_timer_stats
|
||||||
## get_broker_stats
|
## get_broker_stats
|
||||||
|
## get_reporter_stats
|
||||||
function get_broker_stats%(%): BrokerStats
|
function get_broker_stats%(%): BrokerStats
|
||||||
%{
|
%{
|
||||||
RecordVal* r = new RecordVal(BrokerStats);
|
RecordVal* r = new RecordVal(BrokerStats);
|
||||||
|
@ -441,3 +454,39 @@ function get_broker_stats%(%): BrokerStats
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
## Returns statistics about reporter messages and weirds.
|
||||||
|
##
|
||||||
|
## Returns: A record with reporter statistics.
|
||||||
|
##
|
||||||
|
## .. bro:see:: get_conn_stats
|
||||||
|
## get_dns_stats
|
||||||
|
## get_event_stats
|
||||||
|
## get_file_analysis_stats
|
||||||
|
## get_gap_stats
|
||||||
|
## get_matcher_stats
|
||||||
|
## get_net_stats
|
||||||
|
## get_proc_stats
|
||||||
|
## get_reassembler_stats
|
||||||
|
## get_thread_stats
|
||||||
|
## get_timer_stats
|
||||||
|
## get_broker_stats
|
||||||
|
function get_reporter_stats%(%): ReporterStats
|
||||||
|
%{
|
||||||
|
RecordVal* r = new RecordVal(ReporterStats);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
TableVal* weirds_by_type = new TableVal(internal_type("table_string_of_count")->AsTableType());
|
||||||
|
|
||||||
|
for ( auto& kv : reporter->GetWeirdsByType() )
|
||||||
|
{
|
||||||
|
Val* weird = new StringVal(kv.first);
|
||||||
|
weirds_by_type->Assign(weird, new Val(kv.second, TYPE_COUNT));
|
||||||
|
Unref(weird);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->Assign(n++, new Val(reporter->GetWeirdCount(), TYPE_COUNT));
|
||||||
|
r->Assign(n++, weirds_by_type);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
%}
|
||||||
|
|
351
testing/btest/Baseline/core.reporter-weird-sampling/output
Normal file
351
testing/btest/Baseline/core.reporter-weird-sampling/output
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
||||||
|
net_weird, my_net_weird
|
||||||
|
flow_weird, my_flow_weird
|
||||||
|
conn_weird, my_conn_weird
|
||||||
|
net_weird, whitelisted_net_weird
|
||||||
|
flow_weird, whitelisted_flow_weird
|
||||||
|
conn_weird, whitelisted_conn_weird
|
|
@ -55,4 +55,5 @@ traceroute
|
||||||
tunnel
|
tunnel
|
||||||
unified2
|
unified2
|
||||||
weird
|
weird
|
||||||
|
weird_stats
|
||||||
x509
|
x509
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path weird_stats
|
||||||
|
#open 2018-07-26-23-11-27
|
||||||
|
#fields ts name num_seen
|
||||||
|
#types time string count
|
||||||
|
1532646687.827249 weird3 1
|
||||||
|
1532646687.827249 weird2 1000
|
||||||
|
1532646687.827249 weird1 2000
|
||||||
|
1532646692.877464 weird1 2
|
||||||
|
#close 2018-07-26-23-11-34
|
|
@ -0,0 +1,12 @@
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path weird_stats
|
||||||
|
#open 2018-07-27-00-20-35
|
||||||
|
#fields ts name num_seen
|
||||||
|
#types time string count
|
||||||
|
1532650834.978616 my_weird 1000
|
||||||
|
1532650840.011592 my_weird 2000
|
||||||
|
1532650845.043367 my_weird 10
|
||||||
|
#close 2018-07-27-00-20-47
|
55
testing/btest/core/reporter-weird-sampling.bro
Normal file
55
testing/btest/core/reporter-weird-sampling.bro
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/http/bro.org.pcap %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
redef Weird::sampling_duration = 5sec;
|
||||||
|
redef Weird::sampling_threshold = 10;
|
||||||
|
redef Weird::sampling_rate = 10;
|
||||||
|
redef Weird::sampling_whitelist = set("whitelisted_net_weird",
|
||||||
|
"whitelisted_flow_weird",
|
||||||
|
"whitelisted_conn_weird");
|
||||||
|
|
||||||
|
event conn_weird(name: string, c: connection, addl: string)
|
||||||
|
{
|
||||||
|
print "conn_weird", name;
|
||||||
|
}
|
||||||
|
|
||||||
|
event flow_weird(name: string, src: addr, dst: addr)
|
||||||
|
{
|
||||||
|
print "flow_weird", name;
|
||||||
|
}
|
||||||
|
|
||||||
|
event net_weird(name: string)
|
||||||
|
{
|
||||||
|
print "net_weird", name;
|
||||||
|
}
|
||||||
|
|
||||||
|
event gen_weirds(c: connection)
|
||||||
|
{
|
||||||
|
local num = 30;
|
||||||
|
|
||||||
|
while ( num != 0 )
|
||||||
|
{
|
||||||
|
Reporter::net_weird("my_net_weird");
|
||||||
|
Reporter::flow_weird("my_flow_weird", c$id$orig_h, c$id$resp_h);
|
||||||
|
Reporter::conn_weird("my_conn_weird", c);
|
||||||
|
|
||||||
|
Reporter::net_weird("whitelisted_net_weird");
|
||||||
|
Reporter::flow_weird("whitelisted_flow_weird", c$id$orig_h, c$id$resp_h);
|
||||||
|
Reporter::conn_weird("whitelisted_conn_weird", c);
|
||||||
|
--num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global did_one_connection = F;
|
||||||
|
|
||||||
|
event new_connection(c: connection)
|
||||||
|
{
|
||||||
|
if ( did_one_connection )
|
||||||
|
return;
|
||||||
|
|
||||||
|
did_one_connection = T;
|
||||||
|
event gen_weirds(c); # should permit 10 + 2 of each "my" weird
|
||||||
|
schedule 2sec { gen_weirds(c) }; # should permit 3 of each "my" weird
|
||||||
|
schedule 7sec { gen_weirds(c) }; # should permit 10 + 2 of each "my" weird
|
||||||
|
# Total of 27 "my" weirds of each type and 90 of each "whitelisted" type
|
||||||
|
}
|
93
testing/btest/scripts/policy/misc/weird-stats-cluster.bro
Normal file
93
testing/btest/scripts/policy/misc/weird-stats-cluster.bro
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# @TEST-SERIALIZE: comm
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-run manager-1 BROPATH=$BROPATH:.. CLUSTER_NODE=manager-1 bro %INPUT
|
||||||
|
# @TEST-EXEC: btest-bg-run worker-1 BROPATH=$BROPATH:.. CLUSTER_NODE=worker-1 bro %INPUT
|
||||||
|
# @TEST-EXEC: btest-bg-run worker-2 BROPATH=$BROPATH:.. CLUSTER_NODE=worker-2 bro %INPUT
|
||||||
|
# @TEST-EXEC: btest-bg-wait 20
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff manager-1/weird_stats.log
|
||||||
|
|
||||||
|
@TEST-START-FILE cluster-layout.bro
|
||||||
|
redef Cluster::nodes = {
|
||||||
|
["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=37757/tcp],
|
||||||
|
["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37760/tcp, $manager="manager-1", $interface="eth0"],
|
||||||
|
["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=37761/tcp, $manager="manager-1", $interface="eth1"],
|
||||||
|
};
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
@load misc/weird-stats
|
||||||
|
|
||||||
|
redef Cluster::retry_interval = 1sec;
|
||||||
|
redef Broker::default_listen_retry = 1sec;
|
||||||
|
redef Broker::default_connect_retry = 1sec;
|
||||||
|
|
||||||
|
redef Log::enable_local_logging = T;
|
||||||
|
redef Log::default_rotation_interval = 0secs;
|
||||||
|
redef WeirdStats::weird_stat_interval = 5secs;
|
||||||
|
|
||||||
|
event terminate_me()
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
event ready_again()
|
||||||
|
{
|
||||||
|
Reporter::net_weird("weird1");
|
||||||
|
|
||||||
|
if ( Cluster::node == "worker-2" )
|
||||||
|
{
|
||||||
|
schedule 5secs { terminate_me() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event ready_for_data()
|
||||||
|
{
|
||||||
|
local n = 0;
|
||||||
|
|
||||||
|
if ( Cluster::node == "worker-1" )
|
||||||
|
{
|
||||||
|
while ( n < 1000 )
|
||||||
|
{
|
||||||
|
Reporter::net_weird("weird1");
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reporter::net_weird("weird3");
|
||||||
|
}
|
||||||
|
else if ( Cluster::node == "worker-2" )
|
||||||
|
{
|
||||||
|
while ( n < 1000 )
|
||||||
|
{
|
||||||
|
Reporter::net_weird("weird1");
|
||||||
|
Reporter::net_weird("weird2");
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
schedule 5secs { ready_again() };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@if ( Cluster::local_node_type() == Cluster::MANAGER )
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
Broker::auto_publish(Cluster::worker_topic, ready_for_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
global peer_count = 0;
|
||||||
|
|
||||||
|
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
||||||
|
{
|
||||||
|
++peer_count;
|
||||||
|
|
||||||
|
if ( peer_count == 2 )
|
||||||
|
event ready_for_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
@endif
|
32
testing/btest/scripts/policy/misc/weird-stats.bro
Normal file
32
testing/btest/scripts/policy/misc/weird-stats.bro
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# @TEST-EXEC: btest-bg-run bro bro %INPUT
|
||||||
|
# @TEST-EXEC: btest-bg-wait 20
|
||||||
|
# @TEST-EXEC: btest-diff bro/weird_stats.log
|
||||||
|
|
||||||
|
@load misc/weird-stats.bro
|
||||||
|
|
||||||
|
redef exit_only_after_terminate = T;
|
||||||
|
redef WeirdStats::weird_stat_interval = 5sec;
|
||||||
|
|
||||||
|
event die()
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
event gen_weirds(n: count, done: bool &default = F)
|
||||||
|
{
|
||||||
|
while ( n != 0 )
|
||||||
|
{
|
||||||
|
Reporter::net_weird("my_weird");
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( done )
|
||||||
|
schedule 5sec { die() };
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
event gen_weirds(1000);
|
||||||
|
schedule 7.5sec { gen_weirds(2000) } ;
|
||||||
|
schedule 12.5sec { gen_weirds(10, T) } ;
|
||||||
|
}
|
|
@ -9,5 +9,5 @@ else
|
||||||
sed="sed -E"
|
sed="sed -E"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$sed 's/(0\.000000)|([0-9]{10}\.[0-9]{2,8})/XXXXXXXXXX.XXXXXX/g' | \
|
$sed 's/(0\.000000)|([0-9]{9,10}\.[0-9]{2,8})/XXXXXXXXXX.XXXXXX/g' | \
|
||||||
$sed 's/^ *#(open|close).(19|20)..-..-..-..-..-..$/#\1 XXXX-XX-XX-XX-XX-XX/g'
|
$sed 's/^ *#(open|close).(19|20)..-..-..-..-..-..$/#\1 XXXX-XX-XX-XX-XX-XX/g'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue