mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 19:18:19 +00:00

* origin/topic/johanna/conn-threshold: Wrap threshold stuff up - fix two small bugs and update baselines. update GridFTP analyzer to use connection thresholding instead of polling Add high level api for thresholding that holds lists of thresholds and raises an event for each threshold exactly once. Allow setting packet and byte thresholds for connections. BIT-1377 #merged
183 lines
3.8 KiB
C++
183 lines
3.8 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
//
|
|
// See ConnSize.h for more extensive comments.
|
|
|
|
|
|
#include "ConnSize.h"
|
|
#include "analyzer/protocol/tcp/TCP.h"
|
|
|
|
#include "events.bif.h"
|
|
|
|
using namespace analyzer::conn_size;
|
|
|
|
ConnSize_Analyzer::ConnSize_Analyzer(Connection* c)
|
|
: Analyzer("CONNSIZE", c),
|
|
orig_bytes(), resp_bytes(), orig_pkts(), resp_pkts()
|
|
{
|
|
}
|
|
|
|
|
|
ConnSize_Analyzer::~ConnSize_Analyzer()
|
|
{
|
|
}
|
|
|
|
void ConnSize_Analyzer::Init()
|
|
{
|
|
Analyzer::Init();
|
|
|
|
orig_bytes = 0;
|
|
orig_pkts = 0;
|
|
resp_bytes = 0;
|
|
resp_pkts = 0;
|
|
|
|
orig_bytes_thresh = 0;
|
|
orig_pkts_thresh = 0;
|
|
resp_bytes_thresh = 0;
|
|
resp_pkts_thresh = 0;
|
|
}
|
|
|
|
void ConnSize_Analyzer::Done()
|
|
{
|
|
Analyzer::Done();
|
|
}
|
|
|
|
void ConnSize_Analyzer::ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool is_orig)
|
|
{
|
|
if ( ! f )
|
|
return;
|
|
|
|
val_list* vl = new val_list;
|
|
vl->append(BuildConnVal());
|
|
vl->append(new Val(threshold, TYPE_COUNT));
|
|
vl->append(new Val(is_orig, TYPE_BOOL));
|
|
ConnectionEvent(f, vl);
|
|
}
|
|
|
|
void ConnSize_Analyzer::CheckSizes(bool is_orig)
|
|
{
|
|
if ( is_orig )
|
|
{
|
|
if ( orig_bytes_thresh && orig_bytes >= orig_bytes_thresh )
|
|
{
|
|
ThresholdEvent(conn_bytes_threshold_crossed, orig_bytes_thresh, is_orig);
|
|
orig_bytes_thresh = 0;
|
|
}
|
|
|
|
if ( orig_pkts_thresh && orig_pkts >= orig_pkts_thresh )
|
|
{
|
|
ThresholdEvent(conn_packets_threshold_crossed, orig_pkts_thresh, is_orig);
|
|
orig_pkts_thresh = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( resp_bytes_thresh && resp_bytes >= resp_bytes_thresh )
|
|
{
|
|
ThresholdEvent(conn_bytes_threshold_crossed, resp_bytes_thresh, is_orig);
|
|
resp_bytes_thresh = 0;
|
|
}
|
|
|
|
if ( resp_pkts_thresh && resp_pkts >= resp_pkts_thresh )
|
|
{
|
|
ThresholdEvent(conn_packets_threshold_crossed, resp_pkts_thresh, is_orig);
|
|
resp_pkts_thresh = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen)
|
|
{
|
|
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
|
|
|
|
if ( is_orig )
|
|
{
|
|
orig_bytes += ip->TotalLen();
|
|
orig_pkts ++;
|
|
}
|
|
else
|
|
{
|
|
resp_bytes += ip->TotalLen();
|
|
resp_pkts ++;
|
|
}
|
|
|
|
CheckSizes(is_orig);
|
|
}
|
|
|
|
void ConnSize_Analyzer::SetThreshold(uint64 threshold, bool bytes, bool orig)
|
|
{
|
|
if ( bytes )
|
|
{
|
|
if ( orig )
|
|
orig_bytes_thresh = threshold;
|
|
else
|
|
resp_bytes_thresh = threshold;
|
|
}
|
|
else
|
|
{
|
|
if ( orig )
|
|
orig_pkts_thresh = threshold;
|
|
else
|
|
resp_pkts_thresh = threshold;
|
|
}
|
|
|
|
// Check if threshold is already crossed.
|
|
CheckSizes(orig);
|
|
}
|
|
|
|
uint64_t ConnSize_Analyzer::GetThreshold(bool bytes, bool orig)
|
|
{
|
|
if ( bytes )
|
|
{
|
|
if ( orig )
|
|
return orig_bytes_thresh;
|
|
else
|
|
return resp_bytes_thresh;
|
|
}
|
|
else
|
|
{
|
|
if ( orig )
|
|
return orig_pkts_thresh;
|
|
else
|
|
return resp_pkts_thresh;
|
|
}
|
|
}
|
|
|
|
void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val)
|
|
{
|
|
// RecordType *connection_type is decleared in NetVar.h
|
|
RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal();
|
|
RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal();
|
|
|
|
// endpoint is the RecordType from NetVar.h
|
|
int pktidx = endpoint->FieldOffset("num_pkts");
|
|
int bytesidx = endpoint->FieldOffset("num_bytes_ip");
|
|
|
|
if ( pktidx < 0 )
|
|
reporter->InternalError("'endpoint' record missing 'num_pkts' field");
|
|
|
|
if ( bytesidx < 0 )
|
|
reporter->InternalError("'endpoint' record missing 'num_bytes_ip' field");
|
|
|
|
orig_endp->Assign(pktidx, new Val(orig_pkts, TYPE_COUNT));
|
|
orig_endp->Assign(bytesidx, new Val(orig_bytes, TYPE_COUNT));
|
|
resp_endp->Assign(pktidx, new Val(resp_pkts, TYPE_COUNT));
|
|
resp_endp->Assign(bytesidx, new Val(resp_bytes, TYPE_COUNT));
|
|
|
|
Analyzer::UpdateConnVal(conn_val);
|
|
}
|
|
|
|
|
|
void ConnSize_Analyzer::FlipRoles()
|
|
{
|
|
Analyzer::FlipRoles();
|
|
uint64_t tmp;
|
|
|
|
tmp = orig_bytes;
|
|
orig_bytes = resp_bytes;
|
|
resp_bytes = tmp;
|
|
|
|
tmp = orig_pkts;
|
|
orig_pkts = resp_pkts;
|
|
resp_pkts = tmp;
|
|
}
|
|
|