zeek/src/analyzer/protocol/conn-size/ConnSize.cc
Robin Sommer 1e010fbb76 Merge remote-tracking branch 'origin/topic/johanna/conn-threshold'
* 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
2015-04-17 13:02:31 -07:00

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;
}