Merge of Gregor's conn-size branch.

If 'use_conn_size_analyzer' is true, the event engine tracks number of
packets and raw IP bytes per connection. If report_conn_size_analyzer
is true, these values are included as four new columns into conn.log

I changed conn.bro so that the value of report_conn_size_analyzer
follows that of use_conn_size_analyzer. For the new conn.log, we
probably want to get rid of report_conn_size_analyzer anyway.
This commit is contained in:
Robin Sommer 2011-05-09 16:39:01 -07:00
parent 7524cce186
commit bd9855a380
26 changed files with 340 additions and 49 deletions

@ -1 +1 @@
Subproject commit a8617fdca799bd7af272b712373869698a55b4b7
Subproject commit 4fc13f7c6987b4163609e3df7a31f38501411cb7

View file

@ -66,8 +66,12 @@ type ftp_port: record {
};
type endpoint: record {
size: count;
size: count; # logical size (for TCP: from seq numbers)
state: count;
# The following are set if use_conn_size_analyzer is T.
num_pkts: count &optional; # number of packets on the wire
num_bytes_ip: count &optional; # actual number of IP-level bytes on the wire
};
type endpoint_stats: record {
@ -497,6 +501,12 @@ const encap_hdr_size = 0 &redef;
# ... or just for the following UDP port.
const tunnel_port = 0/udp &redef;
# Whether to use the ConnSize analyzer to count the number of
# packets and IP-level bytes transfered by each endpoint. If
# true, these values are returned in the connection's endpoint
# record val.
const use_conn_size_analyzer = F &redef;
const UDP_INACTIVE = 0;
const UDP_ACTIVE = 1; # means we've seen something from this endpoint

View file

@ -18,9 +18,14 @@ global have_SMTP = F; # if true, we've loaded smtp.bro
# TODO: Do we have a nicer way of defining this prototype?
export { global FTP::is_ftp_data_conn: function(c: connection): bool; }
# Whether to include connection state history in the logs generated
# by record_connection.
const record_state_history = F &redef;
# Whether to add 4 more columns to conn.log with
# orig_packet orig_ip_bytes resp_packets resp_ip_bytes
# Requires use_conn_size_analyzer=T
# Columns are added after history but before addl
const report_conn_size_analyzer = F &redef;
# Activate conn-size analyzer if necessary.
redef use_conn_size_analyzer = (! report_conn_size_analyzer);
# Whether to translate the local address in SensitiveConnection notices
# to a hostname. Meant as a demonstration of the "when" construct.
@ -96,6 +101,12 @@ function conn_size(e: endpoint, trans: transport_proto): string
return "?";
}
function conn_size_from_analyzer(e: endpoint): string
{
return fmt("%d %d", (e?$num_pkts) ? e$num_pkts : 0,
(e?$num_bytes_ip) ? e$num_bytes_ip : 0);
}
function service_name(c: connection): string
{
local p = c$id$resp_p;
@ -300,9 +311,9 @@ function record_connection(f: file, c: connection)
conn_size(c$orig, trans), conn_size(c$resp, trans),
conn_state(c, trans), flags);
if ( record_state_history )
log_msg = fmt("%s %s", log_msg,
c$history == "" ? "X" : c$history);
if ( use_conn_size_analyzer && report_conn_size_analyzer )
log_msg = fmt("%s %s %s", log_msg,
conn_size_from_analyzer(c$orig), conn_size_from_analyzer(c$resp));
if ( addl != "" )
log_msg = fmt("%s %s", log_msg, addl);

View file

@ -36,6 +36,7 @@
#include "SSH.h"
#include "SSLProxy.h"
#include "SSL-binpac.h"
#include "ConnSizeAnalyzer.h"
// Keep same order here as in AnalyzerTag definition!
const Analyzer::Config Analyzer::analyzer_configs[] = {
@ -151,6 +152,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
{ AnalyzerTag::TCPStats, "TCPSTATS",
TCPStats_Analyzer::InstantiateAnalyzer,
TCPStats_Analyzer::Available, 0, false },
{ AnalyzerTag::ConnSize, "CONNSIZE",
ConnSize_Analyzer::InstantiateAnalyzer,
ConnSize_Analyzer::Available, 0, false },
{ AnalyzerTag::Contents, "CONTENTS", 0, 0, 0, false },
{ AnalyzerTag::ContentLine, "CONTENTLINE", 0, 0, 0, false },
@ -852,6 +856,12 @@ unsigned int Analyzer::MemoryAllocation() const
return mem;
}
void Analyzer::UpdateConnVal(RecordVal *conn_val)
{
LOOP_OVER_CHILDREN(i)
(*i)->UpdateConnVal(conn_val);
}
void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen)
{

View file

@ -227,6 +227,13 @@ public:
virtual unsigned int MemoryAllocation() const;
// Called whenever the connection value needs to be updated. Per
// default, this method will be called for each analyzer in the tree.
// Analyzers can use this method to attach additional data to the
// connections. A call to BuildConnVal will in turn trigger a call to
// UpdateConnVal.
virtual void UpdateConnVal(RecordVal *conn_val);
// The following methods are proxies: calls are directly forwarded
// to the connection instance. These are for convenience only,
// allowing us to reuse more of the old analyzer code unchanged.
@ -366,7 +373,6 @@ public:
: Analyzer(tag, conn) { pia = 0; }
virtual void Done();
virtual void UpdateEndpointVal(RecordVal* endp, int is_orig) = 0;
virtual bool IsReuse(double t, const u_char* pkt) = 0;
virtual void SetContentsFile(unsigned int direction, BroFile* f);

View file

@ -38,6 +38,8 @@ namespace AnalyzerTag {
// Other
File, Backdoor, InterConn, SteppingStone, TCPStats,
ConnSize,
// Support-analyzers
Contents, ContentLine, NVT, Zip, Contents_DNS, Contents_NCP,

View file

@ -295,6 +295,7 @@ set(bro_SRCS
CompHash.cc
Conn.cc
ConnCompressor.cc
ConnSizeAnalyzer.cc
ContentLine.cc
DCE_RPC.cc
DFA.cc

View file

@ -152,7 +152,6 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id)
proto = TRANSPORT_UNKNOWN;
conn_val = 0;
orig_endp = resp_endp = 0;
login_conn = 0;
is_active = 1;
@ -401,12 +400,12 @@ RecordVal* Connection::BuildConnVal()
conn_val->Assign(0, id_val);
orig_endp = new RecordVal(endpoint);
RecordVal *orig_endp = new RecordVal(endpoint);
orig_endp->Assign(0, new Val(0, TYPE_COUNT));
orig_endp->Assign(1, new Val(0, TYPE_COUNT));
conn_val->Assign(1, orig_endp);
resp_endp = new RecordVal(endpoint);
RecordVal *resp_endp = new RecordVal(endpoint);
resp_endp->Assign(0, new Val(0, TYPE_COUNT));
resp_endp->Assign(1, new Val(0, TYPE_COUNT));
conn_val->Assign(2, resp_endp);
@ -425,10 +424,7 @@ RecordVal* Connection::BuildConnVal()
}
if ( root_analyzer )
{
root_analyzer->UpdateEndpointVal(orig_endp, 1);
root_analyzer->UpdateEndpointVal(resp_endp, 0);
}
root_analyzer->UpdateConnVal(conn_val);
conn_val->Assign(3, new Val(start_time, TYPE_TIME)); // ###
conn_val->Assign(4, new Val(last_time - start_time, TYPE_INTERVAL));
@ -803,10 +799,6 @@ void Connection::FlipRoles()
resp_port = orig_port;
orig_port = tmp_port;
RecordVal* tmp_rc = resp_endp;
resp_endp = orig_endp;
orig_endp = tmp_rc;
Unref(conn_val);
conn_val = 0;
@ -902,8 +894,6 @@ bool Connection::DoSerialize(SerialInfo* info) const
return false;
SERIALIZE_OPTIONAL(conn_val);
SERIALIZE_OPTIONAL(orig_endp);
SERIALIZE_OPTIONAL(resp_endp);
// FIXME: RuleEndpointState not yet serializable.
// FIXME: Analyzers not yet serializable.
@ -967,10 +957,6 @@ bool Connection::DoUnserialize(UnserialInfo* info)
UNSERIALIZE_OPTIONAL(conn_val,
(RecordVal*) Val::Unserialize(info, connection_type));
UNSERIALIZE_OPTIONAL(orig_endp,
(RecordVal*) Val::Unserialize(info, endpoint));
UNSERIALIZE_OPTIONAL(resp_endp,
(RecordVal*) Val::Unserialize(info, endpoint));
int iproto;

View file

@ -338,8 +338,6 @@ protected:
double start_time, last_time;
double inactivity_timeout;
RecordVal* conn_val;
RecordVal* orig_endp;
RecordVal* resp_endp;
LoginConn* login_conn; // either nil, or this
int suppress_event; // suppress certain events to once per conn.

View file

@ -4,6 +4,7 @@
#include "ConnCompressor.h"
#include "Event.h"
#include "ConnSizeAnalyzer.h"
#include "net_util.h"
// The basic model of the compressor is to wait for an answer before
@ -45,6 +46,11 @@
// - We don't match signatures on connections which are completely handled
// by the compressor. Matching would require significant additional state
// w/o being very helpful.
//
// - If use_conn_size_analyzer is True, the reported counts for bytes and
// packets may not account for some packets/data that is part of those
// packets which the connection compressor handles. The error, if any, will
// however be small.
#ifdef DEBUG
@ -234,7 +240,7 @@ Connection* ConnCompressor::NextPacket(double t, HashKey* key, const IP_Hdr* ip,
else if ( addr_eq(ip->SrcAddr(), SrcAddr(pending)) &&
tp->th_sport == SrcPort(pending) )
// Another packet from originator.
tc = NextFromOrig(pending, t, key, tp);
tc = NextFromOrig(pending, t, key, ip, tp);
else
// A reply.
@ -329,11 +335,15 @@ Connection* ConnCompressor::FirstFromOrig(double t, HashKey* key,
}
Connection* ConnCompressor::NextFromOrig(PendingConn* pending, double t,
HashKey* key, const tcphdr* tp)
HashKey* key, const IP_Hdr* ip,
const tcphdr* tp)
{
// Another packet from the same host without seeing an answer so far.
DBG_LOG(DBG_COMPRESSOR, "%s same again", fmt_conn_id(pending));
++pending->num_pkts;
++pending->num_bytes_ip += ip->PayloadLen();
// New window scale overrides old - not great, this is a (subtle)
// evasion opportunity.
if ( TCP_Analyzer::ParseTCPOptions(tp, parse_tcp_options, 0, 0,
@ -611,6 +621,8 @@ void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key,
c->RST = (tp->th_flags & TH_RST) != 0;
c->ACK = (tp->th_flags & TH_ACK) != 0;
c->uid = Connection::CalculateNextUID();
c->num_bytes_ip = ip->TotalLen();
c->num_pkts = 1;
c->invalid = 0;
if ( TCP_Analyzer::ParseTCPOptions(tp, parse_tcp_options, 0, 0, c) < 0 )
@ -851,8 +863,23 @@ void ConnCompressor::Event(const PendingConn* pending, double t,
TRANSPORT_TCP));
orig_endp->Assign(0, new Val(orig_size, TYPE_COUNT));
orig_endp->Assign(1, new Val(orig_state, TYPE_COUNT));
if ( ConnSize_Analyzer::Available() )
{
orig_endp->Assign(2, new Val(pending->num_pkts, TYPE_COUNT));
orig_endp->Assign(3, new Val(pending->num_bytes_ip, TYPE_COUNT));
}
else
{
orig_endp->Assign(2, new Val(0, TYPE_COUNT));
orig_endp->Assign(3, new Val(0, TYPE_COUNT));
}
resp_endp->Assign(0, new Val(0, TYPE_COUNT));
resp_endp->Assign(1, new Val(resp_state, TYPE_COUNT));
resp_endp->Assign(2, new Val(0, TYPE_COUNT));
resp_endp->Assign(3, new Val(0, TYPE_COUNT));
}
else
{
@ -862,10 +889,26 @@ void ConnCompressor::Event(const PendingConn* pending, double t,
id_val->Assign(2, new AddrVal(SrcAddr(pending)));
id_val->Assign(3, new PortVal(ntohs(SrcPort(pending)),
TRANSPORT_TCP));
orig_endp->Assign(0, new Val(0, TYPE_COUNT));
orig_endp->Assign(1, new Val(resp_state, TYPE_COUNT));
orig_endp->Assign(2, new Val(0, TYPE_COUNT));
orig_endp->Assign(3, new Val(0, TYPE_COUNT));
resp_endp->Assign(0, new Val(orig_size, TYPE_COUNT));
resp_endp->Assign(1, new Val(orig_state, TYPE_COUNT));
if ( ConnSize_Analyzer::Available() )
{
resp_endp->Assign(2, new Val(pending->num_pkts, TYPE_COUNT));
resp_endp->Assign(3, new Val(pending->num_bytes_ip, TYPE_COUNT));
}
else
{
resp_endp->Assign(2, new Val(0, TYPE_COUNT));
resp_endp->Assign(3, new Val(0, TYPE_COUNT));
}
DBG_LOG(DBG_COMPRESSOR, "%s swapped direction", fmt_conn_id(pending));
}

View file

@ -98,6 +98,10 @@ public:
hash_t hash;
uint16 window;
uint64 uid;
// The following are set if use_conn_size_analyzer is T.
uint16 num_pkts;
uint16 num_bytes_ip;
};
private:
@ -119,8 +123,8 @@ private:
const IP_Hdr* ip, const tcphdr* tp);
// Called for more packets from the orginator w/o seeing a response.
Connection* NextFromOrig(PendingConn* pending,
double t, HashKey* key, const tcphdr* tp);
Connection* NextFromOrig(PendingConn* pending, double t, HashKey* key,
const IP_Hdr* ip, const tcphdr* tp);
// Called for the first response packet. Instantiates a Connection.
Connection* Response(PendingConn* pending, double t, HashKey* key,

90
src/ConnSizeAnalyzer.cc Normal file
View file

@ -0,0 +1,90 @@
// $Id$
//
// See the file "COPYING" in the main distribution directory for copyright.
//
// See ConnSize.h for more extensive comments.
#include "ConnSizeAnalyzer.h"
#include "TCP.h"
ConnSize_Analyzer::ConnSize_Analyzer(Connection* c)
: Analyzer(AnalyzerTag::ConnSize, c)
{
}
ConnSize_Analyzer::~ConnSize_Analyzer()
{
}
void ConnSize_Analyzer::Init()
{
Analyzer::Init();
orig_bytes = 0;
orig_pkts = 0;
resp_bytes = 0;
resp_pkts = 0;
}
void ConnSize_Analyzer::Done()
{
Analyzer::Done();
}
void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int 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 ++;
}
}
void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val)
{
// RecordType *connection_type is decleared in NetVar.h
int orig_endp_idx = connection_type->FieldOffset("orig");
int resp_endp_idx = connection_type->FieldOffset("resp");
RecordVal *orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
// endpoint is the RecordType from NetVar.h
// TODO: or orig_endp->Type()->AsRecordVal()->FieldOffset()
int pktidx = endpoint->FieldOffset("num_pkts");
int bytesidx = endpoint->FieldOffset("num_bytes_ip");
// TODO: error handling?
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;
}

41
src/ConnSizeAnalyzer.h Normal file
View file

@ -0,0 +1,41 @@
// $Id$
//
// See the file "COPYING" in the main distribution directory for copyright.
//
#ifndef CONNSTATS_H
#define CONNSTATS_H
#include "Analyzer.h"
#include "NetVar.h"
class ConnSize_Analyzer : public Analyzer {
public:
ConnSize_Analyzer(Connection* c);
virtual ~ConnSize_Analyzer();
virtual void Init();
virtual void Done();
// from Analyzer.h
virtual void UpdateConnVal(RecordVal *conn_val);
virtual void FlipRoles();
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ConnSize_Analyzer(conn); }
static bool Available() { return BifConst::use_conn_size_analyzer ; }
protected:
virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen);
uint64_t orig_bytes;
uint64_t resp_bytes;
uint64_t orig_pkts;
uint64_t resp_pkts;
};
#endif

View file

@ -10,6 +10,7 @@
#include "BackDoor.h"
#include "InterConn.h"
#include "SteppingStone.h"
#include "ConnSizeAnalyzer.h"
ExpectedConn::ExpectedConn(const uint32* _orig, const uint32* _resp,
@ -189,6 +190,8 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
const u_char* data)
{
TCP_Analyzer* tcp = 0;
UDP_Analyzer* udp = 0;
ICMP_Analyzer* icmp = 0;
TransportLayerAnalyzer* root = 0;
AnalyzerTag::Tag expected = AnalyzerTag::Error;
analyzer_map* ports = 0;
@ -206,7 +209,7 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
break;
case TRANSPORT_UDP:
root = new UDP_Analyzer(conn);
root = udp = new UDP_Analyzer(conn);
pia = new PIA_UDP(conn);
expected = GetExpected(proto, conn);
ports = &udp_ports;
@ -221,7 +224,7 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
case ICMP_ECHOREPLY:
if ( ICMP_Echo_Analyzer::Available() )
{
root = new ICMP_Echo_Analyzer(conn);
root = icmp = new ICMP_Echo_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Echo analyzer");
}
break;
@ -229,7 +232,7 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
case ICMP_UNREACH:
if ( ICMP_Unreachable_Analyzer::Available() )
{
root = new ICMP_Unreachable_Analyzer(conn);
root = icmp = new ICMP_Unreachable_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Unreachable analyzer");
}
break;
@ -237,14 +240,14 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
case ICMP_TIMXCEED:
if ( ICMP_TimeExceeded_Analyzer::Available() )
{
root = new ICMP_TimeExceeded_Analyzer(conn);
root = icmp = new ICMP_TimeExceeded_Analyzer(conn);
DBG_DPD(conn, "activated ICMP Time Exceeded analyzer");
}
break;
}
if ( ! root )
root = new ICMP_Analyzer(conn);
root = icmp = new ICMP_Analyzer(conn);
analyzed = true;
break;
@ -363,6 +366,16 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
// we cannot add it as a normal child.
if ( TCPStats_Analyzer::Available() )
tcp->AddChildPacketAnalyzer(new TCPStats_Analyzer(conn));
// Add ConnSize analyzer. Needs to see packets, not stream.
if ( ConnSize_Analyzer::Available() )
tcp->AddChildPacketAnalyzer(new ConnSize_Analyzer(conn));
}
else
{
if ( ConnSize_Analyzer::Available() )
root->AddChildAnalyzer(new ConnSize_Analyzer(conn), false);
}
if ( pia )

View file

@ -79,6 +79,9 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
NextICMP(current_timestamp, icmpp, len, caplen, data);
if ( caplen >= len )
ForwardPacket(len, data, is_orig, seq, ip, caplen);
if ( rule_matcher )
matcher_state.Match(Rule::PAYLOAD, data, len, is_orig,
false, false, true);
@ -252,6 +255,20 @@ void ICMP_Analyzer::Describe(ODesc* d) const
d->Add(dotted_addr(Conn()->RespAddr()));
}
void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val)
{
int orig_endp_idx = connection_type->FieldOffset("orig");
int resp_endp_idx = connection_type->FieldOffset("resp");
RecordVal *orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
UpdateEndpointVal(orig_endp, 1);
UpdateEndpointVal(resp_endp, 0);
// Call children's UpdateConnVal
Analyzer::UpdateConnVal(conn_val);
}
void ICMP_Analyzer::UpdateEndpointVal(RecordVal* endp, int is_orig)
{
Conn()->EnableStatusUpdateTimer();

View file

@ -18,6 +18,8 @@ class ICMP_Analyzer : public TransportLayerAnalyzer {
public:
ICMP_Analyzer(Connection* conn);
virtual void UpdateConnVal(RecordVal *conn_val);
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new ICMP_Analyzer(conn); }
@ -30,7 +32,6 @@ protected:
virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen);
virtual void UpdateEndpointVal(RecordVal* endp, int is_orig);
virtual bool IsReuse(double t, const u_char* pkt);
virtual unsigned int MemoryAllocation() const;
@ -52,6 +53,9 @@ protected:
int request_len, reply_len;
RuleMatcherState matcher_state;
private:
void UpdateEndpointVal(RecordVal* endp, int is_orig);
};
class ICMP_Echo_Analyzer : public ICMP_Analyzer {

View file

@ -2,7 +2,7 @@
//
// See the file "COPYING" in the main distribution directory for copyright.
#include "NetVar.h"
#include "PIA.h"
#include "File.h"
#include "TCP.h"
@ -922,9 +922,6 @@ int TCP_Analyzer::DeliverData(double t, const u_char* data, int len, int caplen,
int need_contents = endpoint->DataSent(t, data_seq,
len, caplen, data, ip, tp);
LOOP_OVER_GIVEN_CHILDREN(i, packet_children)
(*i)->NextPacket(len, data, is_orig, data_seq, ip, caplen);
return need_contents;
}
@ -1053,6 +1050,12 @@ void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
CheckRecording(need_contents, flags);
// Handle child_packet analyzers. Note: This happens *after* the
// packet has been processed and the TCP state updated.
LOOP_OVER_GIVEN_CHILDREN(i, packet_children)
(*i)->NextPacket(len, data, is_orig,
base_seq - endpoint->StartSeq(), ip, caplen);
if ( ! reassembling )
ForwardPacket(len, data, is_orig,
base_seq - endpoint->StartSeq(), ip, caplen);
@ -1082,11 +1085,25 @@ void TCP_Analyzer::FlipRoles()
resp->is_orig = !resp->is_orig;
}
void TCP_Analyzer::UpdateEndpointVal(RecordVal* endp, int is_orig)
void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val)
{
TCP_Endpoint* s = is_orig ? orig : resp;
endp->Assign(0, new Val(s->Size(), TYPE_COUNT));
endp->Assign(1, new Val(int(s->state), TYPE_COUNT));
int orig_endp_idx = connection_type->FieldOffset("orig");
int resp_endp_idx = connection_type->FieldOffset("resp");
RecordVal *orig_endp_val = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp_val = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT));
orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT));
resp_endp_val->Assign(0, new Val(resp->Size(), TYPE_COUNT));
resp_endp_val->Assign(1, new Val(int(resp->state), TYPE_COUNT));
// Call children's UpdateConnVal
Analyzer::UpdateConnVal(conn_val);
// Have to do packet_children ourselves.
LOOP_OVER_GIVEN_CHILDREN(i, packet_children)
(*i)->UpdateConnVal(conn_val);
}
Val* TCP_Analyzer::BuildSYNPacketVal(int is_orig, const IP_Hdr* ip,

View file

@ -77,6 +77,9 @@ public:
const u_char* option, TCP_Analyzer* analyzer,
bool is_orig, void* cookie);
// From Analyzer.h
virtual void UpdateConnVal(RecordVal *conn_val);
// Needs to be static because it's passed as a pointer-to-function
// rather than pointer-to-member-function.
static int ParseTCPOptions(const struct tcphdr* tcp,
@ -100,7 +103,6 @@ protected:
virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig);
virtual void FlipRoles();
virtual void UpdateEndpointVal(RecordVal* endp, int is_orig);
virtual bool IsReuse(double t, const u_char* pkt);
// Returns the TCP header pointed to by data (which we assume is

View file

@ -162,6 +162,22 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
ForwardPacket(len, data, is_orig, seq, ip, caplen);
}
void UDP_Analyzer::UpdateConnVal(RecordVal *conn_val)
{
int orig_endp_idx = connection_type->FieldOffset("orig");
int resp_endp_idx = connection_type->FieldOffset("resp");
RecordVal *orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
UpdateEndpointVal(orig_endp, 1);
UpdateEndpointVal(resp_endp, 0);
// Call children's UpdateConnVal
Analyzer::UpdateConnVal(conn_val);
}
void UDP_Analyzer::UpdateEndpointVal(RecordVal* endp, int is_orig)
{
bro_int_t size = is_orig ? request_len : reply_len;

View file

@ -19,6 +19,8 @@ public:
virtual void Init();
virtual void UpdateConnVal(RecordVal *conn_val);
static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new UDP_Analyzer(conn); }
@ -28,12 +30,14 @@ protected:
virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen);
virtual void UpdateEndpointVal(RecordVal* endp, int is_orig);
virtual bool IsReuse(double t, const u_char* pkt);
virtual unsigned int MemoryAllocation() const;
bro_int_t request_len, reply_len;
private:
void UpdateEndpointVal(RecordVal* endp, int is_orig);
#define HIST_ORIG_DATA_PKT 0x1
#define HIST_RESP_DATA_PKT 0x2
#define HIST_ORIG_CORRUPT_PKT 0x4

View file

@ -5,3 +5,5 @@
const ignore_keep_alive_rexmit: bool;
const skip_http_data: bool;
const parse_udp_tunnels: bool;
const use_conn_size_analyzer: bool;

View file

@ -0,0 +1,5 @@
1128727430.350788 ? 141.42.64.125 125.190.109.199 other 56729 12345 tcp ? ? S0 X 1 60 0 0 cc=1
1144876538.705610 5.921003 169.229.147.203 239.255.255.253 other 49370 427 udp 147 ? S0 X 3 231 0 0
1144876599.397603 0.815763 192.150.186.169 194.64.249.244 http 53063 80 tcp 377 445 SF X 6 677 5 713
1144876709.032670 9.000191 169.229.147.43 239.255.255.253 other 49370 427 udp 196 ? S0 X 4 308 0 0
1144876697.068273 0.000650 192.150.186.169 192.150.186.15 icmp-unreach 3 3 icmp 56 ? OTH X 2 112 0 0

View file

@ -0,0 +1,5 @@
1128727430.350788 ? 141.42.64.125 125.190.109.199 other 56729 12345 tcp ? ? S0 X 1 60 0 0
1144876538.705610 5.921003 169.229.147.203 239.255.255.253 other 49370 427 udp 147 ? S0 X 3 231 0 0
1144876599.397603 0.815763 192.150.186.169 194.64.249.244 http 53063 80 tcp 377 445 SF X 6 697 5 713
1144876709.032670 9.000191 169.229.147.43 239.255.255.253 other 49370 427 udp 196 ? S0 X 4 308 0 0
1144876697.068273 0.000650 192.150.186.169 192.150.186.15 icmp-unreach 3 3 icmp 56 ? OTH X 2 112 0 0

Binary file not shown.

View file

@ -0,0 +1,2 @@
# @TEST-EXEC: bro -C -r ${TRACES}/conn-size.trace tcp udp icmp report_conn_size_analyzer=T
# @TEST-EXEC: btest-diff conn.log

View file

@ -0,0 +1,2 @@
# @TEST-EXEC: bro -C -r ${TRACES}/conn-size.trace tcp udp icmp report_conn_size_analyzer=T use_connection_compressor=F
# @TEST-EXEC: btest-diff conn.log