mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 15:18:20 +00:00
Cleaned up stats collection.
- Removed the gap_report event. It wasn't used anymore and functionally no more capable that scheduling events and using the get_gap_summary bif. - Added functionality to Dictionaries to count cumulative numbers of inserts performed. This is further used to measure the total number of connections of various types. Previously only the number of active connections was available. - The Reassembler base class now tracks active reassembly size for all subclasses (File/TCP/Frag & unknown). - Improvements to the stats.log. Mostly, more information.
This commit is contained in:
parent
374e61ee20
commit
2b0a28686a
14 changed files with 189 additions and 117 deletions
|
@ -462,34 +462,51 @@ type NetStats: record {
|
||||||
## .. note:: All process-level values refer to Bro's main process only, not to
|
## .. note:: All process-level values refer to Bro's main process only, not to
|
||||||
## the child process it spawns for doing communication.
|
## the child process it spawns for doing communication.
|
||||||
type bro_resources: record {
|
type bro_resources: record {
|
||||||
version: string; ##< Bro version string.
|
version: string; ##< Bro version string.
|
||||||
debug: bool; ##< True if compiled with --enable-debug.
|
debug: bool; ##< True if compiled with --enable-debug.
|
||||||
start_time: time; ##< Start time of process.
|
start_time: time; ##< Start time of process.
|
||||||
real_time: interval; ##< Elapsed real time since Bro started running.
|
real_time: interval; ##< Elapsed real time since Bro started running.
|
||||||
user_time: interval; ##< User CPU seconds.
|
user_time: interval; ##< User CPU seconds.
|
||||||
system_time: interval; ##< System CPU seconds.
|
system_time: interval; ##< System CPU seconds.
|
||||||
mem: count; ##< Maximum memory consumed, in KB.
|
mem: count; ##< Maximum memory consumed, in KB.
|
||||||
minor_faults: count; ##< Page faults not requiring actual I/O.
|
minor_faults: count; ##< Page faults not requiring actual I/O.
|
||||||
major_faults: count; ##< Page faults requiring actual I/O.
|
major_faults: count; ##< Page faults requiring actual I/O.
|
||||||
num_swap: count; ##< Times swapped out.
|
num_swap: count; ##< Times swapped out.
|
||||||
blocking_input: count; ##< Blocking input operations.
|
blocking_input: count; ##< Blocking input operations.
|
||||||
blocking_output: count; ##< Blocking output operations.
|
blocking_output: count; ##< Blocking output operations.
|
||||||
num_context: count; ##< Number of involuntary context switches.
|
num_context: count; ##< Number of involuntary context switches.
|
||||||
|
|
||||||
|
num_packets: count; ##< Total number of packets processed to date.
|
||||||
|
num_fragments: count; ##< Current number of fragments pending reassembly.
|
||||||
|
max_fragments: count; ##< Maximum number of concurrently buffered fragments so far.
|
||||||
|
|
||||||
|
num_tcp_conns: count; ##< Current number of TCP connections in memory.
|
||||||
|
max_tcp_conns: count; ##< Maximum number of concurrent TCP connections so far.
|
||||||
|
cumulative_tcp_conns: count; ##<
|
||||||
|
|
||||||
num_TCP_conns: count; ##< Current number of TCP connections in memory.
|
num_udp_conns: count; ##< Current number of UDP flows in memory.
|
||||||
num_UDP_conns: count; ##< Current number of UDP flows in memory.
|
max_udp_conns: count; ##< Maximum number of concurrent UDP connections so far.
|
||||||
num_ICMP_conns: count; ##< Current number of ICMP flows in memory.
|
cumulative_udp_conns: count; ##<
|
||||||
num_fragments: count; ##< Current number of fragments pending reassembly.
|
|
||||||
num_packets: count; ##< Total number of packets processed to date.
|
|
||||||
num_timers: count; ##< Current number of pending timers.
|
|
||||||
num_events_queued: count; ##< Total number of events queued so far.
|
|
||||||
num_events_dispatched: count; ##< Total number of events dispatched so far.
|
|
||||||
|
|
||||||
max_TCP_conns: count; ##< Maximum number of concurrent TCP connections so far.
|
num_icmp_conns: count; ##< Current number of ICMP flows in memory.
|
||||||
max_UDP_conns: count; ##< Maximum number of concurrent UDP connections so far.
|
max_icmp_conns: count; ##< Maximum number of concurrent ICMP connections so far.
|
||||||
max_ICMP_conns: count; ##< Maximum number of concurrent ICMP connections so far.
|
cumulative_icmp_conns: count; ##<
|
||||||
max_fragments: count; ##< Maximum number of concurrently buffered fragments so far.
|
|
||||||
max_timers: count; ##< Maximum number of concurrent timers pending so far.
|
num_timers: count; ##< Current number of pending timers.
|
||||||
|
max_timers: count; ##< Maximum number of concurrent timers pending so far.
|
||||||
|
|
||||||
|
num_events_queued: count; ##< Total number of events queued so far.
|
||||||
|
num_events_dispatched: count; ##< Total number of events dispatched so far.
|
||||||
|
|
||||||
|
total_conns: count; ##<
|
||||||
|
current_conns: count; ##<
|
||||||
|
current_conns_extern: count; ##<
|
||||||
|
sess_current_conns: count; ##<
|
||||||
|
|
||||||
|
reassem_file_size: count; ##< Size of File reassembly tracking.
|
||||||
|
reassem_frag_size: count; ##< Size of Fragment reassembly tracking.
|
||||||
|
reassem_tcp_size: count; ##< Size of TCP reassembly tracking.
|
||||||
|
reassem_unknown_size: count; ##< Size of reassembly tracking for unknown purposes.
|
||||||
};
|
};
|
||||||
|
|
||||||
## Summary statistics of all regular expression matchers.
|
## Summary statistics of all regular expression matchers.
|
||||||
|
@ -507,7 +524,7 @@ type matcher_stats: record {
|
||||||
|
|
||||||
## Statistics about number of gaps in TCP connections.
|
## Statistics about number of gaps in TCP connections.
|
||||||
##
|
##
|
||||||
## .. bro:see:: gap_report get_gap_summary
|
## .. bro:see:: get_gap_summary
|
||||||
type gap_info: record {
|
type gap_info: record {
|
||||||
ack_events: count; ##< How many ack events *could* have had gaps.
|
ack_events: count; ##< How many ack events *could* have had gaps.
|
||||||
ack_bytes: count; ##< How many bytes those covered.
|
ack_bytes: count; ##< How many bytes those covered.
|
||||||
|
@ -3416,23 +3433,17 @@ global pkt_profile_file: file &redef;
|
||||||
## .. bro:see:: load_sample
|
## .. bro:see:: load_sample
|
||||||
global load_sample_freq = 20 &redef;
|
global load_sample_freq = 20 &redef;
|
||||||
|
|
||||||
## Rate at which to generate :bro:see:`gap_report` events assessing to what
|
|
||||||
## degree the measurement process appears to exhibit loss.
|
|
||||||
##
|
|
||||||
## .. bro:see:: gap_report
|
|
||||||
const gap_report_freq = 1.0 sec &redef;
|
|
||||||
|
|
||||||
## Whether to attempt to automatically detect SYN/FIN/RST-filtered trace
|
## Whether to attempt to automatically detect SYN/FIN/RST-filtered trace
|
||||||
## and not report missing segments for such connections.
|
## and not report missing segments for such connections.
|
||||||
## If this is enabled, then missing data at the end of connections may not
|
## If this is enabled, then missing data at the end of connections may not
|
||||||
## be reported via :bro:see:`content_gap`.
|
## be reported via :bro:see:`content_gap`.
|
||||||
const detect_filtered_trace = F &redef;
|
const detect_filtered_trace = F &redef;
|
||||||
|
|
||||||
## Whether we want :bro:see:`content_gap` and :bro:see:`gap_report` for partial
|
## Whether we want :bro:see:`content_gap` and :bro:see:`get_gap_summary` for partial
|
||||||
## connections. A connection is partial if it is missing a full handshake. Note
|
## connections. A connection is partial if it is missing a full handshake. Note
|
||||||
## that gap reports for partial connections might not be reliable.
|
## that gap reports for partial connections might not be reliable.
|
||||||
##
|
##
|
||||||
## .. bro:see:: content_gap gap_report partial_connection
|
## .. bro:see:: content_gap get_gap_summary partial_connection
|
||||||
const report_gaps_for_partial = F &redef;
|
const report_gaps_for_partial = F &redef;
|
||||||
|
|
||||||
## Flag to prevent Bro from exiting automatically when input is exhausted.
|
## Flag to prevent Bro from exiting automatically when input is exhausted.
|
||||||
|
|
|
@ -10,7 +10,7 @@ export {
|
||||||
redef enum Log::ID += { LOG };
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
## How often stats are reported.
|
## How often stats are reported.
|
||||||
const stats_report_interval = 1min &redef;
|
const stats_report_interval = 5min &redef;
|
||||||
|
|
||||||
type Info: record {
|
type Info: record {
|
||||||
## Timestamp for the measurement.
|
## Timestamp for the measurement.
|
||||||
|
@ -27,6 +27,22 @@ export {
|
||||||
## interval.
|
## interval.
|
||||||
events_queued: count &log;
|
events_queued: count &log;
|
||||||
|
|
||||||
|
## TCP connections seen since last stats interval.
|
||||||
|
tcp_conns: count &log;
|
||||||
|
## UDP connections seen since last stats interval.
|
||||||
|
udp_conns: count &log;
|
||||||
|
## ICMP connections seen since last stats interval.
|
||||||
|
icmp_conns: count &log;
|
||||||
|
|
||||||
|
## Current size of TCP data in reassembly.
|
||||||
|
reassem_tcp_size: count &log;
|
||||||
|
## Current size of File data in reassembly.
|
||||||
|
reassem_file_size: count &log;
|
||||||
|
## Current size of packet fragment data in reassembly.
|
||||||
|
reassem_frag_size: count &log;
|
||||||
|
## Current size of unkown data in reassembly (this is only PIA buffer right now).
|
||||||
|
reassem_unknown_size: count &log;
|
||||||
|
|
||||||
## Lag between the wall clock and packet timestamps if reading
|
## Lag between the wall clock and packet timestamps if reading
|
||||||
## live traffic.
|
## live traffic.
|
||||||
lag: interval &log &optional;
|
lag: interval &log &optional;
|
||||||
|
@ -64,16 +80,27 @@ event check_stats(last_ts: time, last_ns: NetStats, last_res: bro_resources)
|
||||||
# shutting down.
|
# shutting down.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
local info: Info = [$ts=now, $peer=peer_description, $mem=res$mem/1000000,
|
local info: Info = [$ts=now,
|
||||||
|
$peer=peer_description,
|
||||||
|
$mem=res$mem/1000000,
|
||||||
$pkts_proc=res$num_packets - last_res$num_packets,
|
$pkts_proc=res$num_packets - last_res$num_packets,
|
||||||
$events_proc=res$num_events_dispatched - last_res$num_events_dispatched,
|
$events_proc=res$num_events_dispatched - last_res$num_events_dispatched,
|
||||||
$events_queued=res$num_events_queued - last_res$num_events_queued];
|
$events_queued=res$num_events_queued - last_res$num_events_queued,
|
||||||
|
$tcp_conns=res$cumulative_tcp_conns - last_res$cumulative_tcp_conns,
|
||||||
|
$udp_conns=res$cumulative_udp_conns - last_res$cumulative_udp_conns,
|
||||||
|
$icmp_conns=res$cumulative_icmp_conns - last_res$cumulative_icmp_conns,
|
||||||
|
$reassem_tcp_size=res$reassem_tcp_size,
|
||||||
|
$reassem_file_size=res$reassem_file_size,
|
||||||
|
$reassem_frag_size=res$reassem_frag_size,
|
||||||
|
$reassem_unknown_size=res$reassem_unknown_size
|
||||||
|
];
|
||||||
|
|
||||||
|
# Someone's going to have to explain what this is and add a field to the Info record.
|
||||||
|
# info$util = 100.0*((res$user_time + res$system_time) - (last_res$user_time + last_res$system_time))/(now-last_ts);
|
||||||
|
|
||||||
if ( reading_live_traffic() )
|
if ( reading_live_traffic() )
|
||||||
{
|
{
|
||||||
info$lag = now - network_time();
|
info$lag = now - network_time();
|
||||||
# Someone's going to have to explain what this is and add a field to the Info record.
|
|
||||||
# info$util = 100.0*((res$user_time + res$system_time) - (last_res$user_time + last_res$system_time))/(now-last_ts);
|
|
||||||
info$pkts_recv = ns$pkts_recvd - last_ns$pkts_recvd;
|
info$pkts_recv = ns$pkts_recvd - last_ns$pkts_recvd;
|
||||||
info$pkts_dropped = ns$pkts_dropped - last_ns$pkts_dropped;
|
info$pkts_dropped = ns$pkts_dropped - last_ns$pkts_dropped;
|
||||||
info$pkts_link = ns$pkts_link - last_ns$pkts_link;
|
info$pkts_link = ns$pkts_link - last_ns$pkts_link;
|
||||||
|
|
|
@ -66,6 +66,7 @@ Dictionary::Dictionary(dict_order ordering, int initial_size)
|
||||||
delete_func = 0;
|
delete_func = 0;
|
||||||
tbl_next_ind = 0;
|
tbl_next_ind = 0;
|
||||||
|
|
||||||
|
cumulative_entries = 0;
|
||||||
num_buckets2 = num_entries2 = max_num_entries2 = thresh_entries2 = 0;
|
num_buckets2 = num_entries2 = max_num_entries2 = thresh_entries2 = 0;
|
||||||
den_thresh2 = 0;
|
den_thresh2 = 0;
|
||||||
}
|
}
|
||||||
|
@ -444,6 +445,7 @@ void* Dictionary::Insert(DictEntry* new_entry, int copy_key)
|
||||||
// on lists than prepending.
|
// on lists than prepending.
|
||||||
chain->append(new_entry);
|
chain->append(new_entry);
|
||||||
|
|
||||||
|
++cumulative_entries;
|
||||||
if ( *max_num_entries_ptr < ++*num_entries_ptr )
|
if ( *max_num_entries_ptr < ++*num_entries_ptr )
|
||||||
*max_num_entries_ptr = *num_entries_ptr;
|
*max_num_entries_ptr = *num_entries_ptr;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,12 @@ public:
|
||||||
max_num_entries + max_num_entries2 : max_num_entries;
|
max_num_entries + max_num_entries2 : max_num_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total number of entries ever.
|
||||||
|
uint64 NumCumulativeInserts() const
|
||||||
|
{
|
||||||
|
return cumulative_entries;
|
||||||
|
}
|
||||||
|
|
||||||
// True if the dictionary is ordered, false otherwise.
|
// True if the dictionary is ordered, false otherwise.
|
||||||
int IsOrdered() const { return order != 0; }
|
int IsOrdered() const { return order != 0; }
|
||||||
|
|
||||||
|
@ -166,6 +172,7 @@ private:
|
||||||
int num_buckets;
|
int num_buckets;
|
||||||
int num_entries;
|
int num_entries;
|
||||||
int max_num_entries;
|
int max_num_entries;
|
||||||
|
uint64 cumulative_entries;
|
||||||
double den_thresh;
|
double den_thresh;
|
||||||
int thresh_entries;
|
int thresh_entries;
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
EventMgr mgr;
|
EventMgr mgr;
|
||||||
|
|
||||||
int num_events_queued = 0;
|
uint64 num_events_queued = 0;
|
||||||
int num_events_dispatched = 0;
|
uint64 num_events_dispatched = 0;
|
||||||
|
|
||||||
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
||||||
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
||||||
|
|
|
@ -72,8 +72,8 @@ protected:
|
||||||
Event* next_event;
|
Event* next_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int num_events_queued;
|
extern uint64 num_events_queued;
|
||||||
extern int num_events_dispatched;
|
extern uint64 num_events_dispatched;
|
||||||
|
|
||||||
class EventMgr : public BroObj {
|
class EventMgr : public BroObj {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -28,7 +28,7 @@ void FragTimer::Dispatch(double t, int /* is_expire */)
|
||||||
FragReassembler::FragReassembler(NetSessions* arg_s,
|
FragReassembler::FragReassembler(NetSessions* arg_s,
|
||||||
const IP_Hdr* ip, const u_char* pkt,
|
const IP_Hdr* ip, const u_char* pkt,
|
||||||
HashKey* k, double t)
|
HashKey* k, double t)
|
||||||
: Reassembler(0)
|
: Reassembler(0, REASSEM_FRAG)
|
||||||
{
|
{
|
||||||
s = arg_s;
|
s = arg_s;
|
||||||
key = k;
|
key = k;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "bro-config.h"
|
#include "bro-config.h"
|
||||||
|
|
||||||
|
@ -10,7 +11,8 @@
|
||||||
static const bool DEBUG_reassem = false;
|
static const bool DEBUG_reassem = false;
|
||||||
|
|
||||||
DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
|
DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
|
||||||
DataBlock* arg_prev, DataBlock* arg_next)
|
DataBlock* arg_prev, DataBlock* arg_next,
|
||||||
|
ReassemblerType reassem_type)
|
||||||
{
|
{
|
||||||
seq = arg_seq;
|
seq = arg_seq;
|
||||||
upper = seq + size;
|
upper = seq + size;
|
||||||
|
@ -26,17 +28,24 @@ DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
|
||||||
if ( next )
|
if ( next )
|
||||||
next->prev = this;
|
next->prev = this;
|
||||||
|
|
||||||
|
if ( Reassembler::sizes.size() == 0 )
|
||||||
|
Reassembler::sizes.resize(REASSEM_TERM, 0);
|
||||||
|
|
||||||
|
rtype = reassem_type;
|
||||||
|
Reassembler::sizes[rtype] += pad_size(size) + padded_sizeof(DataBlock);
|
||||||
Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock);
|
Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 Reassembler::total_size = 0;
|
uint64 Reassembler::total_size = 0;
|
||||||
|
std::vector<uint64> Reassembler::sizes;
|
||||||
|
|
||||||
Reassembler::Reassembler(uint64 init_seq)
|
Reassembler::Reassembler(uint64 init_seq, ReassemblerType reassem_type)
|
||||||
{
|
{
|
||||||
blocks = last_block = 0;
|
blocks = last_block = 0;
|
||||||
old_blocks = last_old_block = 0;
|
old_blocks = last_old_block = 0;
|
||||||
total_old_blocks = max_old_blocks = 0;
|
total_old_blocks = max_old_blocks = 0;
|
||||||
trim_seq = last_reassem_seq = init_seq;
|
trim_seq = last_reassem_seq = init_seq;
|
||||||
|
rtype = reassem_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
Reassembler::~Reassembler()
|
Reassembler::~Reassembler()
|
||||||
|
@ -110,7 +119,7 @@ void Reassembler::NewBlock(double t, uint64 seq, uint64 len, const u_char* data)
|
||||||
|
|
||||||
if ( ! blocks )
|
if ( ! blocks )
|
||||||
blocks = last_block = start_block =
|
blocks = last_block = start_block =
|
||||||
new DataBlock(data, len, seq, 0, 0);
|
new DataBlock(data, len, seq, 0, 0, rtype);
|
||||||
else
|
else
|
||||||
start_block = AddAndCheck(blocks, seq, upper_seq, data);
|
start_block = AddAndCheck(blocks, seq, upper_seq, data);
|
||||||
|
|
||||||
|
@ -275,7 +284,7 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
||||||
if ( last_block && seq == last_block->upper )
|
if ( last_block && seq == last_block->upper )
|
||||||
{
|
{
|
||||||
last_block = new DataBlock(data, upper - seq, seq,
|
last_block = new DataBlock(data, upper - seq, seq,
|
||||||
last_block, 0);
|
last_block, 0, rtype);
|
||||||
return last_block;
|
return last_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +297,7 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
||||||
{
|
{
|
||||||
// b is the last block, and it comes completely before
|
// b is the last block, and it comes completely before
|
||||||
// the new block.
|
// the new block.
|
||||||
last_block = new DataBlock(data, upper - seq, seq, b, 0);
|
last_block = new DataBlock(data, upper - seq, seq, b, 0, rtype);
|
||||||
return last_block;
|
return last_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +306,7 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
||||||
if ( upper <= b->seq )
|
if ( upper <= b->seq )
|
||||||
{
|
{
|
||||||
// The new block comes completely before b.
|
// The new block comes completely before b.
|
||||||
new_b = new DataBlock(data, upper - seq, seq, b->prev, b);
|
new_b = new DataBlock(data, upper - seq, seq, b->prev, b, rtype);
|
||||||
if ( b == blocks )
|
if ( b == blocks )
|
||||||
blocks = new_b;
|
blocks = new_b;
|
||||||
return new_b;
|
return new_b;
|
||||||
|
@ -308,7 +317,7 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
||||||
{
|
{
|
||||||
// The new block has a prefix that comes before b.
|
// The new block has a prefix that comes before b.
|
||||||
uint64 prefix_len = b->seq - seq;
|
uint64 prefix_len = b->seq - seq;
|
||||||
new_b = new DataBlock(data, prefix_len, seq, b->prev, b);
|
new_b = new DataBlock(data, prefix_len, seq, b->prev, b, rtype);
|
||||||
if ( b == blocks )
|
if ( b == blocks )
|
||||||
blocks = new_b;
|
blocks = new_b;
|
||||||
|
|
||||||
|
@ -342,6 +351,17 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
||||||
return new_b;
|
return new_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64 Reassembler::MemoryAllocation(ReassemblerType rtype)
|
||||||
|
{
|
||||||
|
if (Reassembler::sizes.size() == 0 )
|
||||||
|
Reassembler::sizes.resize(REASSEM_TERM, 0);
|
||||||
|
|
||||||
|
if ( rtype < REASSEM_TERM )
|
||||||
|
return Reassembler::sizes[rtype];
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool Reassembler::Serialize(SerialInfo* info) const
|
bool Reassembler::Serialize(SerialInfo* info) const
|
||||||
{
|
{
|
||||||
return SerialObj::Serialize(info);
|
return SerialObj::Serialize(info);
|
||||||
|
|
|
@ -6,10 +6,23 @@
|
||||||
#include "Obj.h"
|
#include "Obj.h"
|
||||||
#include "IPAddr.h"
|
#include "IPAddr.h"
|
||||||
|
|
||||||
|
// Whenever subclassing the Reassembler class
|
||||||
|
// you should add to this for known subclasses.
|
||||||
|
enum ReassemblerType {
|
||||||
|
REASSEM_UNKNOWN,
|
||||||
|
REASSEM_TCP,
|
||||||
|
REASSEM_FRAG,
|
||||||
|
REASSEM_FILE,
|
||||||
|
|
||||||
|
// Terminal value. Add new above.
|
||||||
|
REASSEM_TERM,
|
||||||
|
};
|
||||||
|
|
||||||
class DataBlock {
|
class DataBlock {
|
||||||
public:
|
public:
|
||||||
DataBlock(const u_char* data, uint64 size, uint64 seq,
|
DataBlock(const u_char* data, uint64 size, uint64 seq,
|
||||||
DataBlock* prev, DataBlock* next);
|
DataBlock* prev, DataBlock* next,
|
||||||
|
ReassemblerType reassem_type = REASSEM_UNKNOWN);
|
||||||
|
|
||||||
~DataBlock();
|
~DataBlock();
|
||||||
|
|
||||||
|
@ -19,13 +32,12 @@ public:
|
||||||
DataBlock* prev; // previous block with lower seq #
|
DataBlock* prev; // previous block with lower seq #
|
||||||
uint64 seq, upper;
|
uint64 seq, upper;
|
||||||
u_char* block;
|
u_char* block;
|
||||||
|
ReassemblerType rtype;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Reassembler : public BroObj {
|
class Reassembler : public BroObj {
|
||||||
public:
|
public:
|
||||||
Reassembler(uint64 init_seq);
|
Reassembler(uint64 init_seq, ReassemblerType reassem_type = REASSEM_UNKNOWN);
|
||||||
virtual ~Reassembler();
|
virtual ~Reassembler();
|
||||||
|
|
||||||
void NewBlock(double t, uint64 seq, uint64 len, const u_char* data);
|
void NewBlock(double t, uint64 seq, uint64 len, const u_char* data);
|
||||||
|
@ -51,6 +63,9 @@ public:
|
||||||
// Sum over all data buffered in some reassembler.
|
// Sum over all data buffered in some reassembler.
|
||||||
static uint64 TotalMemoryAllocation() { return total_size; }
|
static uint64 TotalMemoryAllocation() { return total_size; }
|
||||||
|
|
||||||
|
// Data buffered by type of reassembler.
|
||||||
|
static uint64 MemoryAllocation(ReassemblerType rtype);
|
||||||
|
|
||||||
void SetMaxOldBlocks(uint32 count) { max_old_blocks = count; }
|
void SetMaxOldBlocks(uint32 count) { max_old_blocks = count; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -82,12 +97,15 @@ protected:
|
||||||
uint32 max_old_blocks;
|
uint32 max_old_blocks;
|
||||||
uint32 total_old_blocks;
|
uint32 total_old_blocks;
|
||||||
|
|
||||||
|
ReassemblerType rtype;
|
||||||
static uint64 total_size;
|
static uint64 total_size;
|
||||||
|
static std::vector<uint64> sizes;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline DataBlock::~DataBlock()
|
inline DataBlock::~DataBlock()
|
||||||
{
|
{
|
||||||
Reassembler::total_size -= pad_size(upper - seq) + padded_sizeof(DataBlock);
|
Reassembler::total_size -= pad_size(upper - seq) + padded_sizeof(DataBlock);
|
||||||
|
Reassembler::sizes[rtype] -= pad_size(upper - seq) + padded_sizeof(DataBlock);
|
||||||
delete [] block;
|
delete [] block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1156,8 +1156,11 @@ void NetSessions::Drain()
|
||||||
void NetSessions::GetStats(SessionStats& s) const
|
void NetSessions::GetStats(SessionStats& s) const
|
||||||
{
|
{
|
||||||
s.num_TCP_conns = tcp_conns.Length();
|
s.num_TCP_conns = tcp_conns.Length();
|
||||||
|
s.cumulative_TCP_conns = tcp_conns.NumCumulativeInserts();
|
||||||
s.num_UDP_conns = udp_conns.Length();
|
s.num_UDP_conns = udp_conns.Length();
|
||||||
|
s.cumulative_UDP_conns = udp_conns.NumCumulativeInserts();
|
||||||
s.num_ICMP_conns = icmp_conns.Length();
|
s.num_ICMP_conns = icmp_conns.Length();
|
||||||
|
s.cumulative_ICMP_conns = icmp_conns.NumCumulativeInserts();
|
||||||
s.num_fragments = fragments.Length();
|
s.num_fragments = fragments.Length();
|
||||||
s.num_packets = num_packets_processed;
|
s.num_packets = num_packets_processed;
|
||||||
s.num_timers = timer_mgr->Size();
|
s.num_timers = timer_mgr->Size();
|
||||||
|
|
|
@ -32,19 +32,24 @@ namespace analyzer { namespace arp { class ARP_Analyzer; } }
|
||||||
|
|
||||||
struct SessionStats {
|
struct SessionStats {
|
||||||
int num_TCP_conns;
|
int num_TCP_conns;
|
||||||
int num_UDP_conns;
|
|
||||||
int num_ICMP_conns;
|
|
||||||
int num_fragments;
|
|
||||||
int num_packets;
|
|
||||||
int num_timers;
|
|
||||||
int num_events_queued;
|
|
||||||
int num_events_dispatched;
|
|
||||||
|
|
||||||
int max_TCP_conns;
|
int max_TCP_conns;
|
||||||
|
uint64 cumulative_TCP_conns;
|
||||||
|
|
||||||
|
int num_UDP_conns;
|
||||||
int max_UDP_conns;
|
int max_UDP_conns;
|
||||||
|
uint64 cumulative_UDP_conns;
|
||||||
|
|
||||||
|
int num_ICMP_conns;
|
||||||
int max_ICMP_conns;
|
int max_ICMP_conns;
|
||||||
|
uint64 cumulative_ICMP_conns;
|
||||||
|
|
||||||
|
int num_fragments;
|
||||||
int max_fragments;
|
int max_fragments;
|
||||||
|
uint64 num_packets;
|
||||||
|
int num_timers;
|
||||||
int max_timers;
|
int max_timers;
|
||||||
|
uint64 num_events_queued;
|
||||||
|
uint64 num_events_dispatched;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Drains and deletes a timer manager if it hasn't seen any advances
|
// Drains and deletes a timer manager if it hasn't seen any advances
|
||||||
|
@ -242,7 +247,7 @@ protected:
|
||||||
OSFingerprint* SYN_OS_Fingerprinter;
|
OSFingerprint* SYN_OS_Fingerprinter;
|
||||||
int build_backdoor_analyzer;
|
int build_backdoor_analyzer;
|
||||||
int dump_this_packet; // if true, current packet should be recorded
|
int dump_this_packet; // if true, current packet should be recorded
|
||||||
int num_packets_processed;
|
uint64 num_packets_processed;
|
||||||
PacketProfiler* pkt_profiler;
|
PacketProfiler* pkt_profiler;
|
||||||
|
|
||||||
// We may use independent timer managers for different sets of related
|
// We may use independent timer managers for different sets of related
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
#include "analyzer/protocol/tcp/TCP.h"
|
#include "analyzer/protocol/tcp/TCP.h"
|
||||||
#include "TCP_Endpoint.h"
|
#include "TCP_Endpoint.h"
|
||||||
|
|
||||||
// Only needed for gap_report events.
|
|
||||||
#include "Event.h"
|
|
||||||
|
|
||||||
#include "events.bif.h"
|
#include "events.bif.h"
|
||||||
|
|
||||||
using namespace analyzer::tcp;
|
using namespace analyzer::tcp;
|
||||||
|
@ -18,17 +15,11 @@ const bool DEBUG_tcp_contents = false;
|
||||||
const bool DEBUG_tcp_connection_close = false;
|
const bool DEBUG_tcp_connection_close = false;
|
||||||
const bool DEBUG_tcp_match_undelivered = false;
|
const bool DEBUG_tcp_match_undelivered = false;
|
||||||
|
|
||||||
static double last_gap_report = 0.0;
|
|
||||||
static uint64 last_ack_events = 0;
|
|
||||||
static uint64 last_ack_bytes = 0;
|
|
||||||
static uint64 last_gap_events = 0;
|
|
||||||
static uint64 last_gap_bytes = 0;
|
|
||||||
|
|
||||||
TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer,
|
TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer,
|
||||||
TCP_Analyzer* arg_tcp_analyzer,
|
TCP_Analyzer* arg_tcp_analyzer,
|
||||||
TCP_Reassembler::Type arg_type,
|
TCP_Reassembler::Type arg_type,
|
||||||
TCP_Endpoint* arg_endp)
|
TCP_Endpoint* arg_endp)
|
||||||
: Reassembler(1)
|
: Reassembler(1, REASSEM_TCP)
|
||||||
{
|
{
|
||||||
dst_analyzer = arg_dst_analyzer;
|
dst_analyzer = arg_dst_analyzer;
|
||||||
tcp_analyzer = arg_tcp_analyzer;
|
tcp_analyzer = arg_tcp_analyzer;
|
||||||
|
@ -45,7 +36,7 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer,
|
||||||
if ( tcp_max_old_segments )
|
if ( tcp_max_old_segments )
|
||||||
SetMaxOldBlocks(tcp_max_old_segments);
|
SetMaxOldBlocks(tcp_max_old_segments);
|
||||||
|
|
||||||
if ( tcp_contents )
|
if ( ::tcp_contents )
|
||||||
{
|
{
|
||||||
// Val dst_port_val(ntohs(Conn()->RespPort()), TYPE_PORT);
|
// Val dst_port_val(ntohs(Conn()->RespPort()), TYPE_PORT);
|
||||||
PortVal dst_port_val(ntohs(tcp_analyzer->Conn()->RespPort()),
|
PortVal dst_port_val(ntohs(tcp_analyzer->Conn()->RespPort()),
|
||||||
|
@ -387,7 +378,6 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block)
|
||||||
{ // New stuff.
|
{ // New stuff.
|
||||||
uint64 len = b->Size();
|
uint64 len = b->Size();
|
||||||
uint64 seq = last_reassem_seq;
|
uint64 seq = last_reassem_seq;
|
||||||
|
|
||||||
last_reassem_seq += len;
|
last_reassem_seq += len;
|
||||||
|
|
||||||
if ( record_contents_file )
|
if ( record_contents_file )
|
||||||
|
@ -548,35 +538,6 @@ void TCP_Reassembler::AckReceived(uint64 seq)
|
||||||
tot_gap_bytes += num_missing;
|
tot_gap_bytes += num_missing;
|
||||||
tcp_analyzer->Event(ack_above_hole);
|
tcp_analyzer->Event(ack_above_hole);
|
||||||
}
|
}
|
||||||
|
|
||||||
double dt = network_time - last_gap_report;
|
|
||||||
|
|
||||||
if ( gap_report && gap_report_freq > 0.0 &&
|
|
||||||
dt >= gap_report_freq )
|
|
||||||
{
|
|
||||||
uint64 devents = tot_ack_events - last_ack_events;
|
|
||||||
uint64 dbytes = tot_ack_bytes - last_ack_bytes;
|
|
||||||
uint64 dgaps = tot_gap_events - last_gap_events;
|
|
||||||
uint64 dgap_bytes = tot_gap_bytes - last_gap_bytes;
|
|
||||||
|
|
||||||
RecordVal* r = new RecordVal(gap_info);
|
|
||||||
r->Assign(0, new Val(devents, TYPE_COUNT));
|
|
||||||
r->Assign(1, new Val(dbytes, TYPE_COUNT));
|
|
||||||
r->Assign(2, new Val(dgaps, TYPE_COUNT));
|
|
||||||
r->Assign(3, new Val(dgap_bytes, TYPE_COUNT));
|
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
|
||||||
vl->append(new IntervalVal(dt, Seconds));
|
|
||||||
vl->append(r);
|
|
||||||
|
|
||||||
mgr.QueueEvent(gap_report, vl);
|
|
||||||
|
|
||||||
last_gap_report = network_time;
|
|
||||||
last_ack_events = tot_ack_events;
|
|
||||||
last_ack_bytes = tot_ack_bytes;
|
|
||||||
last_gap_events = tot_gap_events;
|
|
||||||
last_gap_bytes = tot_gap_bytes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check EOF here because t_reassem->LastReassemSeq() may have
|
// Check EOF here because t_reassem->LastReassemSeq() may have
|
||||||
|
|
38
src/bro.bif
38
src/bro.bif
|
@ -1763,20 +1763,38 @@ function resource_usage%(%): bro_resources
|
||||||
#define ADD_STAT(x) \
|
#define ADD_STAT(x) \
|
||||||
res->Assign(n++, new Val(unsigned(sessions ? x : 0), TYPE_COUNT));
|
res->Assign(n++, new Val(unsigned(sessions ? x : 0), TYPE_COUNT));
|
||||||
|
|
||||||
ADD_STAT(s.num_TCP_conns);
|
|
||||||
ADD_STAT(s.num_UDP_conns);
|
|
||||||
ADD_STAT(s.num_ICMP_conns);
|
|
||||||
ADD_STAT(s.num_fragments);
|
|
||||||
ADD_STAT(s.num_packets);
|
ADD_STAT(s.num_packets);
|
||||||
ADD_STAT(s.num_timers);
|
ADD_STAT(s.num_fragments);
|
||||||
ADD_STAT(s.num_events_queued);
|
|
||||||
ADD_STAT(s.num_events_dispatched);
|
|
||||||
ADD_STAT(s.max_TCP_conns);
|
|
||||||
ADD_STAT(s.max_UDP_conns);
|
|
||||||
ADD_STAT(s.max_ICMP_conns);
|
|
||||||
ADD_STAT(s.max_fragments);
|
ADD_STAT(s.max_fragments);
|
||||||
|
|
||||||
|
ADD_STAT(s.num_TCP_conns);
|
||||||
|
ADD_STAT(s.max_TCP_conns);
|
||||||
|
ADD_STAT(s.cumulative_TCP_conns);
|
||||||
|
|
||||||
|
ADD_STAT(s.num_UDP_conns);
|
||||||
|
ADD_STAT(s.max_UDP_conns);
|
||||||
|
ADD_STAT(s.cumulative_UDP_conns);
|
||||||
|
|
||||||
|
ADD_STAT(s.num_ICMP_conns);
|
||||||
|
ADD_STAT(s.max_ICMP_conns);
|
||||||
|
ADD_STAT(s.cumulative_ICMP_conns);
|
||||||
|
|
||||||
|
ADD_STAT(s.num_timers);
|
||||||
ADD_STAT(s.max_timers);
|
ADD_STAT(s.max_timers);
|
||||||
|
|
||||||
|
ADD_STAT(s.mem);
|
||||||
|
ADD_STAT(s.num_events_dispatched);
|
||||||
|
|
||||||
|
ADD_STAT(Connection::TotalConnections());
|
||||||
|
ADD_STAT(Connection::CurrentConnections());
|
||||||
|
ADD_STAT(Connection::CurrentExternalConnections());
|
||||||
|
ADD_STAT(sessions->CurrentConnections());
|
||||||
|
|
||||||
|
ADD_STAT(Reassembler::MemoryAllocation(REASSEM_FILE));
|
||||||
|
ADD_STAT(Reassembler::MemoryAllocation(REASSEM_FRAG));
|
||||||
|
ADD_STAT(Reassembler::MemoryAllocation(REASSEM_TCP));
|
||||||
|
ADD_STAT(Reassembler::MemoryAllocation(REASSEM_UNKNOWN));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace file_analysis {
|
||||||
class File;
|
class File;
|
||||||
|
|
||||||
FileReassembler::FileReassembler(File *f, uint64 starting_offset)
|
FileReassembler::FileReassembler(File *f, uint64 starting_offset)
|
||||||
: Reassembler(starting_offset), the_file(f), flushing(false)
|
: Reassembler(starting_offset, REASSEM_FILE), the_file(f), flushing(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue