mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Lots of cleanup and API documentation for the analyzer/* classes.
I've used the opportunity to also cleanup DPD's expect_connection() infrastructure, and renamed that bif to schedule_analyzer(), which seems more appropiate. One can now also schedule more than one analyzer per connection. TODOs: - "make install" is probably broken. - Broxygen is probably broken for plugin-defined events. - event groups are broken (do we want to keep them?) - parallel btest is broken, but I'm not sure why ... (tests all pass individually, but lots of error when running in parallel; must be related to *.bif restructuring). - Document API for src/plugin/* - Document API for src/analyzer/Analyzer.h - Document API for scripts/base/frameworks/analyzer
This commit is contained in:
parent
e532aff687
commit
e0c4bd1a82
32 changed files with 994 additions and 550 deletions
|
@ -22,6 +22,9 @@ rest_target(${CMAKE_BINARY_DIR}/src base/const.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/event.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/src base/event.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/input.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/src base/input.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/logging.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/src base/logging.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/protocols/http/events.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/protocols/http/functions.bif.bro)
|
||||||
|
rest_target(${CMAKE_BINARY_DIR}/src base/protocols/ssl/events.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/reporter.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/src base/reporter.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/strings.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/src base/strings.bif.bro)
|
||||||
rest_target(${CMAKE_BINARY_DIR}/src base/types.bif.bro)
|
rest_target(${CMAKE_BINARY_DIR}/src base/types.bif.bro)
|
||||||
|
|
|
@ -45,7 +45,7 @@ export {
|
||||||
## tout: The timeout interval after which to ignore the scheduling request.
|
## tout: The timeout interval after which to ignore the scheduling request.
|
||||||
##
|
##
|
||||||
## Returns: True if succesful.
|
## Returns: True if succesful.
|
||||||
global expect_connection: function(orig: addr, resp: addr, resp_p: port,
|
global schedule_analyzer: function(orig: addr, resp: addr, resp_p: port,
|
||||||
analyzer: Analyzer::Tag, tout: interval) : bool;
|
analyzer: Analyzer::Tag, tout: interval) : bool;
|
||||||
|
|
||||||
## Analyzers to disable at startup.
|
## Analyzers to disable at startup.
|
||||||
|
@ -119,9 +119,9 @@ function name(atype: Analyzer::Tag) : string
|
||||||
return __name(atype);
|
return __name(atype);
|
||||||
}
|
}
|
||||||
|
|
||||||
function expect_connection(orig: addr, resp: addr, resp_p: port,
|
function schedule_analyzer(orig: addr, resp: addr, resp_p: port,
|
||||||
analyzer: Analyzer::Tag, tout: interval) : bool
|
analyzer: Analyzer::Tag, tout: interval) : bool
|
||||||
{
|
{
|
||||||
return __expect_connection(orig, resp, resp_p, analyzer, tout);
|
return __schedule_analyzer(orig, resp, resp_p, analyzer, tout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ event ftp_request(c: connection, command: string, arg: string) &priority=5
|
||||||
{
|
{
|
||||||
c$ftp$passive=F;
|
c$ftp$passive=F;
|
||||||
ftp_data_expected[data$h, data$p] = c$ftp;
|
ftp_data_expected[data$h, data$p] = c$ftp;
|
||||||
Analyzer::expect_connection(id$resp_h, data$h, data$p, Analyzer::ANALYZER_FILE, 5mins);
|
Analyzer::schedule_analyzer(id$resp_h, data$h, data$p, Analyzer::ANALYZER_FILE, 5mins);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -281,7 +281,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
||||||
data$h = id$resp_h;
|
data$h = id$resp_h;
|
||||||
|
|
||||||
ftp_data_expected[data$h, data$p] = c$ftp;
|
ftp_data_expected[data$h, data$p] = c$ftp;
|
||||||
Analyzer::expect_connection(id$orig_h, data$h, data$p, Analyzer::ANALYZER_FILE, 5mins);
|
Analyzer::schedule_analyzer(id$orig_h, data$h, data$p, Analyzer::ANALYZER_FILE, 5mins);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -312,7 +312,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
event expected_connection_seen(c: connection, a: count) &priority=10
|
event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10
|
||||||
{
|
{
|
||||||
local id = c$id;
|
local id = c$id;
|
||||||
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
|
if ( [id$resp_h, id$resp_p] in ftp_data_expected )
|
||||||
|
|
|
@ -104,7 +104,7 @@ event irc_dcc_message(c: connection, is_orig: bool,
|
||||||
c$irc$dcc_file_name = argument;
|
c$irc$dcc_file_name = argument;
|
||||||
c$irc$dcc_file_size = size;
|
c$irc$dcc_file_size = size;
|
||||||
local p = count_to_port(dest_port, tcp);
|
local p = count_to_port(dest_port, tcp);
|
||||||
Analyzer::expect_connection(to_addr("0.0.0.0"), address, p, Analyzer::ANALYZER_FILE, 5 min);
|
Analyzer::schedule_analyzer(to_addr("0.0.0.0"), address, p, Analyzer::ANALYZER_FILE, 5 min);
|
||||||
dcc_expected_transfers[address, p] = c$irc;
|
dcc_expected_transfers[address, p] = c$irc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,7 @@ set(bro_SRCS
|
||||||
|
|
||||||
analyzer/Analyzer.cc
|
analyzer/Analyzer.cc
|
||||||
analyzer/Manager.cc
|
analyzer/Manager.cc
|
||||||
analyzer/PluginComponent.cc
|
analyzer/Component.cc
|
||||||
analyzer/Tag.cc
|
analyzer/Tag.cc
|
||||||
|
|
||||||
protocols/BuiltInAnalyzers.cc
|
protocols/BuiltInAnalyzers.cc
|
||||||
|
|
|
@ -161,8 +161,8 @@ static void add_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr,
|
||||||
// of the dce_rpc_endpoints table.
|
// of the dce_rpc_endpoints table.
|
||||||
// FIXME: Don't hard-code the timeout.
|
// FIXME: Don't hard-code the timeout.
|
||||||
|
|
||||||
analyzer_mgr->ExpectConnection(IPAddr(), addr.addr, addr.port, addr.proto,
|
analyzer_mgr->ScheduleAnalyzer(IPAddr(), addr.addr, addr.port, addr.proto,
|
||||||
"DCE_RPC", 5 * 60, 0);
|
"DCE_RPC", 5 * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
DCE_RPC_Header::DCE_RPC_Header(analyzer::Analyzer* a, const u_char* b)
|
DCE_RPC_Header::DCE_RPC_Header(analyzer::Analyzer* a, const u_char* b)
|
||||||
|
|
|
@ -21,7 +21,7 @@ enum DebugStream {
|
||||||
DBG_STRING, // String code
|
DBG_STRING, // String code
|
||||||
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
||||||
DBG_MAINLOOP, // Main IOSource loop
|
DBG_MAINLOOP, // Main IOSource loop
|
||||||
DBG_DPD, // Dynamic application detection framework
|
DBG_ANALYZER, // Analyzer framework
|
||||||
DBG_TM, // Time-machine packet input via Brocolli
|
DBG_TM, // Time-machine packet input via Brocolli
|
||||||
DBG_LOGGING, // Logging streams
|
DBG_LOGGING, // Logging streams
|
||||||
DBG_INPUT, // Input streams
|
DBG_INPUT, // Input streams
|
||||||
|
|
|
@ -45,23 +45,6 @@ HashKey* BuildConnIDHashKey(const ConnID& id)
|
||||||
return new HashKey(&key, sizeof(key));
|
return new HashKey(&key, sizeof(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
HashKey* BuildExpectedConnHashKey(const analyzer::ExpectedConn& c)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
in6_addr orig;
|
|
||||||
in6_addr resp;
|
|
||||||
uint16 resp_p;
|
|
||||||
uint16 proto;
|
|
||||||
} key;
|
|
||||||
|
|
||||||
key.orig = c.orig.in6;
|
|
||||||
key.resp = c.resp.in6;
|
|
||||||
key.resp_p = c.resp_p;
|
|
||||||
key.proto = c.proto;
|
|
||||||
|
|
||||||
return new HashKey(&key, sizeof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
void IPAddr::Mask(int top_bits_to_keep)
|
void IPAddr::Mask(int top_bits_to_keep)
|
||||||
{
|
{
|
||||||
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
|
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
|
||||||
|
|
|
@ -363,7 +363,6 @@ public:
|
||||||
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
|
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
|
||||||
|
|
||||||
friend HashKey* BuildConnIDHashKey(const ConnID& id);
|
friend HashKey* BuildConnIDHashKey(const ConnID& id);
|
||||||
friend HashKey* BuildExpectedConnHashKey(const analyzer::ExpectedConn& c);
|
|
||||||
|
|
||||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
||||||
|
|
||||||
|
|
12
src/PIA.cc
12
src/PIA.cc
|
@ -63,7 +63,7 @@ void PIA::AddToBuffer(Buffer* buffer, int len, const u_char* data, bool is_orig)
|
||||||
|
|
||||||
void PIA::ReplayPacketBuffer(analyzer::Analyzer* analyzer)
|
void PIA::ReplayPacketBuffer(analyzer::Analyzer* analyzer)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "PIA replaying %d total packet bytes", pkt_buffer.size);
|
DBG_LOG(DBG_ANALYZER, "PIA replaying %d total packet bytes", pkt_buffer.size);
|
||||||
|
|
||||||
for ( DataBlock* b = pkt_buffer.head; b; b = b->next )
|
for ( DataBlock* b = pkt_buffer.head; b; b = b->next )
|
||||||
analyzer->DeliverPacket(b->len, b->data, b->is_orig, -1, 0, 0);
|
analyzer->DeliverPacket(b->len, b->data, b->is_orig, -1, 0, 0);
|
||||||
|
@ -133,7 +133,7 @@ void PIA_UDP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule)
|
||||||
{
|
{
|
||||||
if ( pkt_buffer.state == MATCHING_ONLY )
|
if ( pkt_buffer.state == MATCHING_ONLY )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "analyzer found but buffer already exceeded");
|
DBG_LOG(DBG_ANALYZER, "analyzer found but buffer already exceeded");
|
||||||
// FIXME: This is where to check whether an analyzer
|
// FIXME: This is where to check whether an analyzer
|
||||||
// supports partial connections once we get such.
|
// supports partial connections once we get such.
|
||||||
return;
|
return;
|
||||||
|
@ -180,7 +180,7 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip)
|
||||||
static struct tcphdr* tcp4 = 0;
|
static struct tcphdr* tcp4 = 0;
|
||||||
static IP_Hdr* ip4_hdr = 0;
|
static IP_Hdr* ip4_hdr = 0;
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "PIA_TCP[%d] FirstPacket(%s)", GetID(), (is_orig ? "T" : "F"));
|
DBG_LOG(DBG_ANALYZER, "PIA_TCP[%d] FirstPacket(%s)", GetID(), (is_orig ? "T" : "F"));
|
||||||
|
|
||||||
if ( ! ip )
|
if ( ! ip )
|
||||||
{
|
{
|
||||||
|
@ -266,7 +266,7 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule)
|
||||||
{
|
{
|
||||||
if ( stream_buffer.state == MATCHING_ONLY )
|
if ( stream_buffer.state == MATCHING_ONLY )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "analyzer found but buffer already exceeded");
|
DBG_LOG(DBG_ANALYZER, "analyzer found but buffer already exceeded");
|
||||||
// FIXME: This is where to check whether an analyzer supports
|
// FIXME: This is where to check whether an analyzer supports
|
||||||
// partial connections once we get such.
|
// partial connections once we get such.
|
||||||
return;
|
return;
|
||||||
|
@ -305,7 +305,7 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule)
|
||||||
// (4) We hand the two reassemblers to the TCP Analyzer (our parent),
|
// (4) We hand the two reassemblers to the TCP Analyzer (our parent),
|
||||||
// turning reassembly now on for all subsequent data.
|
// turning reassembly now on for all subsequent data.
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "PIA_TCP switching from packet-mode to stream-mode");
|
DBG_LOG(DBG_ANALYZER, "PIA_TCP switching from packet-mode to stream-mode");
|
||||||
stream_mode = true;
|
stream_mode = true;
|
||||||
|
|
||||||
// FIXME: The reassembler will query the endpoint for state. Not sure
|
// FIXME: The reassembler will query the endpoint for state. Not sure
|
||||||
|
@ -378,7 +378,7 @@ void PIA_TCP::DeactivateAnalyzer(analyzer::Tag tag)
|
||||||
|
|
||||||
void PIA_TCP::ReplayStreamBuffer(analyzer::Analyzer* analyzer)
|
void PIA_TCP::ReplayStreamBuffer(analyzer::Analyzer* analyzer)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "PIA_TCP replaying %d total stream bytes", stream_buffer.size);
|
DBG_LOG(DBG_ANALYZER, "PIA_TCP replaying %d total stream bytes", stream_buffer.size);
|
||||||
|
|
||||||
for ( DataBlock* b = stream_buffer.head; b; b = b->next )
|
for ( DataBlock* b = stream_buffer.head; b; b = b->next )
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,15 +54,12 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
|
||||||
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
|
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
child_analyzer = analyzer::Tag::ERROR;
|
child_analyzer = analyzer::Tag();
|
||||||
|
|
||||||
if ( analyzer != analyzer::Tag::ERROR )
|
|
||||||
analyzer_mgr->ActivateSigs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleActionAnalyzer::PrintDebug()
|
void RuleActionAnalyzer::PrintDebug()
|
||||||
{
|
{
|
||||||
if ( child_analyzer == analyzer::Tag::ERROR )
|
if ( ! child_analyzer )
|
||||||
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer).c_str());
|
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer).c_str());
|
||||||
else
|
else
|
||||||
fprintf(stderr, "|%s:%s|\n",
|
fprintf(stderr, "|%s:%s|\n",
|
||||||
|
@ -74,7 +71,7 @@ void RuleActionAnalyzer::PrintDebug()
|
||||||
void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
{
|
{
|
||||||
if ( ChildAnalyzer() == analyzer::Tag::ERROR )
|
if ( ! ChildAnalyzer() )
|
||||||
{
|
{
|
||||||
if ( ! analyzer_mgr->IsEnabled(Analyzer()) )
|
if ( ! analyzer_mgr->IsEnabled(Analyzer()) )
|
||||||
return;
|
return;
|
||||||
|
@ -103,7 +100,7 @@ void RuleActionEnable::PrintDebug()
|
||||||
void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
{
|
{
|
||||||
if ( ChildAnalyzer() == analyzer::Tag::ERROR )
|
if ( ! ChildAnalyzer() )
|
||||||
{
|
{
|
||||||
if ( state->PIA() )
|
if ( state->PIA() )
|
||||||
state->PIA()->DeactivateAnalyzer(Analyzer());
|
state->PIA()->DeactivateAnalyzer(Analyzer());
|
||||||
|
|
|
@ -1178,7 +1178,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||||
|
|
||||||
Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation);
|
Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation);
|
||||||
conn->SetTransport(tproto);
|
conn->SetTransport(tproto);
|
||||||
analyzer_mgr->BuildInitialAnalyzerTree(tproto, conn, data);
|
analyzer_mgr->BuildInitialAnalyzerTree(conn);
|
||||||
|
|
||||||
bool external = conn->IsExternal();
|
bool external = conn->IsExternal();
|
||||||
|
|
||||||
|
|
|
@ -1874,7 +1874,7 @@ void TCP_ApplicationAnalyzer::DeliverPacket(int len, const u_char* data,
|
||||||
const IP_Hdr* ip, int caplen)
|
const IP_Hdr* ip, int caplen)
|
||||||
{
|
{
|
||||||
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
|
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
|
||||||
DBG_LOG(DBG_DPD, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
DBG_LOG(DBG_ANALYZER, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
||||||
len, is_orig ? "T" : "F", seq, ip, caplen,
|
len, is_orig ? "T" : "F", seq, ip, caplen,
|
||||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@ function Analyzer::__register_for_port%(id: Analyzer::Tag, p: port%) : bool
|
||||||
return new Val(result, TYPE_BOOL);
|
return new Val(result, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function Analyzer::__expect_connection%(orig: addr, resp: addr, resp_p: port,
|
function Analyzer::__schedule_analyzer%(orig: addr, resp: addr, resp_p: port,
|
||||||
analyzer: Analyzer::Tag, tout: interval%) : bool
|
analyzer: Analyzer::Tag, tout: interval%) : bool
|
||||||
%{
|
%{
|
||||||
analyzer_mgr->ExpectConnection(orig->AsAddr(), resp->AsAddr(), resp_p, analyzer->AsEnumVal(), tout, 0);
|
analyzer_mgr->ScheduleAnalyzer(orig->AsAddr(), resp->AsAddr(), resp_p, analyzer->AsEnumVal(), tout);
|
||||||
return new Val(true, TYPE_BOOL);
|
return new Val(true, TYPE_BOOL);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ Analyzer::Analyzer(const char* name, Connection* arg_conn)
|
||||||
output_handler = 0;
|
output_handler = 0;
|
||||||
|
|
||||||
if ( ! tag )
|
if ( ! tag )
|
||||||
reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::PluginComponent?", name);
|
reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
|
||||||
if ( init )
|
if ( init )
|
||||||
analyzer->Init();
|
analyzer->Init();
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "%s added child %s",
|
DBG_LOG(DBG_ANALYZER, "%s added child %s",
|
||||||
fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
|
||||||
LOOP_OVER_CHILDREN(i)
|
LOOP_OVER_CHILDREN(i)
|
||||||
if ( *i == analyzer && ! (analyzer->finished || analyzer->removing) )
|
if ( *i == analyzer && ! (analyzer->finished || analyzer->removing) )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s disabling child %s",
|
DBG_LOG(DBG_ANALYZER, "%s disabling child %s",
|
||||||
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||||
// We just flag it as being removed here but postpone
|
// We just flag it as being removed here but postpone
|
||||||
// actually doing that to later. Otherwise, we'd need
|
// actually doing that to later. Otherwise, we'd need
|
||||||
|
@ -386,7 +386,7 @@ void Analyzer::RemoveChildAnalyzer(ID id)
|
||||||
LOOP_OVER_CHILDREN(i)
|
LOOP_OVER_CHILDREN(i)
|
||||||
if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) )
|
if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s disabling child %s", GetAnalyzerName().c_str(), id,
|
DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName().c_str(), id,
|
||||||
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
|
||||||
// See comment above.
|
// See comment above.
|
||||||
(*i)->removing = true;
|
(*i)->removing = true;
|
||||||
|
@ -440,7 +440,7 @@ Analyzer* Analyzer::FindChild(Tag arg_tag)
|
||||||
Analyzer* Analyzer::FindChild(const string& name)
|
Analyzer* Analyzer::FindChild(const string& name)
|
||||||
{
|
{
|
||||||
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
|
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
|
||||||
return tag != Tag::ERROR ? FindChild(tag) : 0;
|
return tag ? FindChild(tag) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::DeleteChild(analyzer_list::iterator i)
|
void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||||
|
@ -456,7 +456,7 @@ void Analyzer::DeleteChild(analyzer_list::iterator i)
|
||||||
child->removing = false;
|
child->removing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "%s deleted child %s 3",
|
DBG_LOG(DBG_ANALYZER, "%s deleted child %s 3",
|
||||||
fmt_analyzer(this).c_str(), fmt_analyzer(child).c_str());
|
fmt_analyzer(this).c_str(), fmt_analyzer(child).c_str());
|
||||||
|
|
||||||
children.erase(i);
|
children.erase(i);
|
||||||
|
@ -467,7 +467,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||||
{
|
{
|
||||||
if ( HasSupportAnalyzer(analyzer->GetAnalyzerTag(), analyzer->IsOrig()) )
|
if ( HasSupportAnalyzer(analyzer->GetAnalyzerTag(), analyzer->IsOrig()) )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s already has %s %s",
|
DBG_LOG(DBG_ANALYZER, "%s already has %s %s",
|
||||||
fmt_analyzer(this).c_str(),
|
fmt_analyzer(this).c_str(),
|
||||||
analyzer->IsOrig() ? "originator" : "responder",
|
analyzer->IsOrig() ? "originator" : "responder",
|
||||||
fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(analyzer).c_str());
|
||||||
|
@ -495,7 +495,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||||
|
|
||||||
analyzer->Init();
|
analyzer->Init();
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "%s added %s support %s",
|
DBG_LOG(DBG_ANALYZER, "%s added %s support %s",
|
||||||
fmt_analyzer(this).c_str(),
|
fmt_analyzer(this).c_str(),
|
||||||
analyzer->IsOrig() ? "originator" : "responder",
|
analyzer->IsOrig() ? "originator" : "responder",
|
||||||
fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(analyzer).c_str());
|
||||||
|
@ -519,7 +519,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
|
||||||
else
|
else
|
||||||
*head = s->sibling;
|
*head = s->sibling;
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "%s removed support %s",
|
DBG_LOG(DBG_ANALYZER, "%s removed support %s",
|
||||||
fmt_analyzer(this).c_str(),
|
fmt_analyzer(this).c_str(),
|
||||||
analyzer->IsOrig() ? "originator" : "responder",
|
analyzer->IsOrig() ? "originator" : "responder",
|
||||||
fmt_analyzer(analyzer).c_str());
|
fmt_analyzer(analyzer).c_str());
|
||||||
|
@ -544,33 +544,33 @@ bool Analyzer::HasSupportAnalyzer(Tag tag, bool orig)
|
||||||
void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
||||||
int seq, const IP_Hdr* ip, int caplen)
|
int seq, const IP_Hdr* ip, int caplen)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
|
||||||
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
|
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
|
||||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
|
void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s DeliverStream(%d, %s) [%s%s]",
|
DBG_LOG(DBG_ANALYZER, "%s DeliverStream(%d, %s) [%s%s]",
|
||||||
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F",
|
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F",
|
||||||
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::Undelivered(int seq, int len, bool is_orig)
|
void Analyzer::Undelivered(int seq, int len, bool is_orig)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s Undelivered(%d, %d, %s)",
|
DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)",
|
||||||
fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
|
fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::EndOfData(bool is_orig)
|
void Analyzer::EndOfData(bool is_orig)
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s EndOfData(%s)",
|
DBG_LOG(DBG_ANALYZER, "%s EndOfData(%s)",
|
||||||
fmt_analyzer(this).c_str(), is_orig ? "T" : "F");
|
fmt_analyzer(this).c_str(), is_orig ? "T" : "F");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::FlipRoles()
|
void Analyzer::FlipRoles()
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "%s FlipRoles()");
|
DBG_LOG(DBG_ANALYZER, "%s FlipRoles()");
|
||||||
|
|
||||||
LOOP_OVER_CHILDREN(i)
|
LOOP_OVER_CHILDREN(i)
|
||||||
(*i)->FlipRoles();
|
(*i)->FlipRoles();
|
||||||
|
@ -596,7 +596,7 @@ void Analyzer::ProtocolConfirmation()
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(tag.Val());
|
vl->append(tag.AsEnumVal());
|
||||||
vl->append(new Val(id, TYPE_COUNT));
|
vl->append(new Val(id, TYPE_COUNT));
|
||||||
|
|
||||||
// We immediately raise the event so that the analyzer can quickly
|
// We immediately raise the event so that the analyzer can quickly
|
||||||
|
@ -624,7 +624,7 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(tag.Val());
|
vl->append(tag.AsEnumVal());
|
||||||
vl->append(new Val(id, TYPE_COUNT));
|
vl->append(new Val(id, TYPE_COUNT));
|
||||||
vl->append(r);
|
vl->append(r);
|
||||||
|
|
||||||
|
|
29
src/analyzer/Component.cc
Normal file
29
src/analyzer/Component.cc
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
#include "../Desc.h"
|
||||||
|
|
||||||
|
using namespace analyzer;
|
||||||
|
|
||||||
|
Tag::type_t Component::type_counter = 0;
|
||||||
|
|
||||||
|
Component::Component(std::string arg_name, factory_callback arg_factory, Tag::subtype_t arg_subtype, bool arg_enabled, bool arg_partial)
|
||||||
|
: plugin::Component(plugin::component::ANALYZER)
|
||||||
|
{
|
||||||
|
name = arg_name;
|
||||||
|
factory = arg_factory;
|
||||||
|
enabled = arg_enabled;
|
||||||
|
partial = arg_partial;
|
||||||
|
|
||||||
|
tag = analyzer::Tag(++type_counter, arg_subtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::Describe(ODesc* d)
|
||||||
|
{
|
||||||
|
plugin::Component::Describe(d);
|
||||||
|
d->Add(name);
|
||||||
|
d->Add(" (");
|
||||||
|
d->Add(enabled ? "enabled" : "disabled");
|
||||||
|
d->Add(")");
|
||||||
|
}
|
||||||
|
|
121
src/analyzer/Component.h
Normal file
121
src/analyzer/Component.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
|
||||||
|
#ifndef ANALYZER_PLUGIN_COMPONENT_H
|
||||||
|
#define ANALYZER_PLUGIN_COMPONENT_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Tag.h"
|
||||||
|
#include "plugin/Component.h"
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
namespace analyzer {
|
||||||
|
|
||||||
|
class Analyzer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component description for plugins providing analyzers.
|
||||||
|
*
|
||||||
|
* A plugin can provide a specific protocol analyzer by registering this
|
||||||
|
* analyzer component, describing the analyzer.
|
||||||
|
*
|
||||||
|
* This class is safe to copy by value.
|
||||||
|
*/
|
||||||
|
class Component : public plugin::Component {
|
||||||
|
public:
|
||||||
|
typedef bool (*available_callback)();
|
||||||
|
typedef Analyzer* (*factory_callback)(Connection* conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param name The name of the provided analyzer. This name is used
|
||||||
|
* across the system to identify the analyzer, e.g., when calling
|
||||||
|
* analyzer::Manager::InstantiateAnalyzer with a name.
|
||||||
|
*
|
||||||
|
* @param factory A factory function to instantiate instances of the
|
||||||
|
* analyzer's class, which must be derived directly or indirectly
|
||||||
|
* from analyzer::Analyzer. This is typically a static \c
|
||||||
|
* Instatiate() method inside the class that just allocates and
|
||||||
|
* returns a new instance.
|
||||||
|
*
|
||||||
|
* @param subtype A subtype associated with this component that
|
||||||
|
* further. The subtype will be integrated into the analyzer::Tag
|
||||||
|
* that the manager associates with this analyzer, and analyzer
|
||||||
|
* instances can accordingly access it via analyzer::Tag(). If not
|
||||||
|
* used, leave at zero.
|
||||||
|
*
|
||||||
|
* @param enabled If false the analyzer starts out as disabled and
|
||||||
|
* hence won't be used. It can still be enabled later via the
|
||||||
|
* manager, including from script-land.
|
||||||
|
*
|
||||||
|
* @param partial If true, the analyzer can deal with payload from
|
||||||
|
* partial connections, i.e., when Bro enters the stream mid-way
|
||||||
|
* after not seeing the beginning. Note that handling of partial
|
||||||
|
* connections has generally not seen much testing yet as virtually
|
||||||
|
* no existing analyzer supports it.
|
||||||
|
*/
|
||||||
|
Component(std::string name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true, bool partial = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the analyzer. This name is unique across all
|
||||||
|
* analyzers and used to identify it.
|
||||||
|
*/
|
||||||
|
const std::string& Name() const { return name; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analyzer's factory function.
|
||||||
|
*/
|
||||||
|
factory_callback Factory() const { return factory; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the analyzer supports partial connections. Partial
|
||||||
|
* connections are those where Bro starts processing payload
|
||||||
|
* mid-stream, after missing the beginning.
|
||||||
|
*/
|
||||||
|
bool Partial() const { return partial; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the analyzer is currently enabled and hence
|
||||||
|
* available for use.
|
||||||
|
*/
|
||||||
|
bool Enabled() const { return enabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analyzer's tag. Note that this is automatically
|
||||||
|
* generated for each new Components, and hence unique across all of
|
||||||
|
* them.
|
||||||
|
*/
|
||||||
|
analyzer::Tag Tag() const { return tag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables this analyzer.
|
||||||
|
*
|
||||||
|
* @param arg_enabled True to enabled, false to disable.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetEnabled(bool arg_enabled) { enabled = arg_enabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a human-readable description of the component's main
|
||||||
|
* parameters. This goes into the output of \c "bro -NN".
|
||||||
|
*/
|
||||||
|
virtual void Describe(ODesc* d);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name; // The analyzer's name.
|
||||||
|
factory_callback factory; // The analyzer's factory callback.
|
||||||
|
bool partial; // True if the analyzer supports partial connections.
|
||||||
|
analyzer::Tag tag; // The automatically assigned analyzer tag.
|
||||||
|
bool enabled; // True if the analyzer is enabled.
|
||||||
|
|
||||||
|
// Global counter used to generate unique tags.
|
||||||
|
static analyzer::Tag::type_t type_counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
using namespace analyzer;
|
using namespace analyzer;
|
||||||
|
|
||||||
ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
Manager::ConnIndex::ConnIndex(const IPAddr& _orig, const IPAddr& _resp,
|
||||||
uint16 _resp_p, uint16 _proto)
|
uint16 _resp_p, uint16 _proto)
|
||||||
{
|
{
|
||||||
if ( _orig == IPAddr(string("0.0.0.0")) )
|
if ( _orig == IPAddr(string("0.0.0.0")) )
|
||||||
|
@ -25,21 +25,37 @@ ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
||||||
orig = IPAddr(string("::"));
|
orig = IPAddr(string("::"));
|
||||||
else
|
else
|
||||||
orig = _orig;
|
orig = _orig;
|
||||||
|
|
||||||
resp = _resp;
|
resp = _resp;
|
||||||
resp_p = _resp_p;
|
resp_p = _resp_p;
|
||||||
proto = _proto;
|
proto = _proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpectedConn::ExpectedConn(const ExpectedConn& c)
|
Manager::ConnIndex::ConnIndex()
|
||||||
{
|
{
|
||||||
orig = c.orig;
|
orig = resp = IPAddr("0.0.0.0");
|
||||||
resp = c.resp;
|
resp_p = 0;
|
||||||
resp_p = c.resp_p;
|
proto = 0;
|
||||||
proto = c.proto;
|
}
|
||||||
|
|
||||||
|
bool Manager::ConnIndex::operator<(const ConnIndex& other) const
|
||||||
|
{
|
||||||
|
if ( orig != other.orig )
|
||||||
|
return orig < other.orig;
|
||||||
|
|
||||||
|
if ( resp != other.resp )
|
||||||
|
return resp < other.resp;
|
||||||
|
|
||||||
|
if ( proto != other.proto )
|
||||||
|
return proto < other.proto;
|
||||||
|
|
||||||
|
if ( resp_p != other.resp_p )
|
||||||
|
return resp_p < other.resp_p;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::Manager()
|
Manager::Manager()
|
||||||
: expected_conns_queue(AssignedAnalyzer::compare)
|
|
||||||
{
|
{
|
||||||
tag_enum_type = new EnumType("Analyzer::Tag");
|
tag_enum_type = new EnumType("Analyzer::Tag");
|
||||||
::ID* id = install_ID("Tag", "Analyzer", true, true);
|
::ID* id = install_ID("Tag", "Analyzer", true, true);
|
||||||
|
@ -58,26 +74,19 @@ Manager::~Manager()
|
||||||
analyzers_by_port_tcp.clear();
|
analyzers_by_port_tcp.clear();
|
||||||
|
|
||||||
// Clean up expected-connection table.
|
// Clean up expected-connection table.
|
||||||
while ( expected_conns_queue.size() )
|
while ( conns_by_timeout.size() )
|
||||||
{
|
{
|
||||||
AssignedAnalyzer* a = expected_conns_queue.top();
|
ScheduledAnalyzer* a = conns_by_timeout.top();
|
||||||
if ( ! a->deleted )
|
conns_by_timeout.pop();
|
||||||
{
|
|
||||||
HashKey* key = BuildExpectedConnHashKey(a->conn);
|
|
||||||
expected_conns.Remove(key);
|
|
||||||
delete key;
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_conns_queue.pop();
|
|
||||||
delete a;
|
delete a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Init()
|
void Manager::Init()
|
||||||
{
|
{
|
||||||
std::list<PluginComponent*> analyzers = plugin_mgr->Components<PluginComponent>(plugin::component::ANALYZER);
|
std::list<Component*> analyzers = plugin_mgr->Components<Component>(plugin::component::ANALYZER);
|
||||||
|
|
||||||
for ( std::list<PluginComponent*>::const_iterator i = analyzers.begin(); i != analyzers.end(); i++ )
|
for ( std::list<Component*>::const_iterator i = analyzers.begin(); i != analyzers.end(); i++ )
|
||||||
RegisterAnalyzerComponent(*i);
|
RegisterAnalyzerComponent(*i);
|
||||||
|
|
||||||
// Caache these tags.
|
// Caache these tags.
|
||||||
|
@ -91,12 +100,12 @@ void Manager::Init()
|
||||||
void Manager::DumpDebug()
|
void Manager::DumpDebug()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DBG_LOG(DBG_DPD, "Available analyzers after bro_init():");
|
DBG_LOG(DBG_ANALYZER, "Available analyzers after bro_init():");
|
||||||
for ( analyzer_map_by_name::const_iterator i = analyzers_by_name.begin(); i != analyzers_by_name.end(); i++ )
|
for ( analyzer_map_by_name::const_iterator i = analyzers_by_name.begin(); i != analyzers_by_name.end(); i++ )
|
||||||
DBG_LOG(DBG_DPD, " %s (%s)", i->second->Name().c_str(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled");
|
DBG_LOG(DBG_ANALYZER, " %s (%s)", i->second->Name().c_str(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled");
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "");
|
DBG_LOG(DBG_ANALYZER, "");
|
||||||
DBG_LOG(DBG_DPD, "Analyzers by port:");
|
DBG_LOG(DBG_ANALYZER, "Analyzers by port:");
|
||||||
|
|
||||||
for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_tcp.begin(); i != analyzers_by_port_tcp.end(); i++ )
|
for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_tcp.begin(); i != analyzers_by_port_tcp.end(); i++ )
|
||||||
{
|
{
|
||||||
|
@ -105,7 +114,7 @@ void Manager::DumpDebug()
|
||||||
for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ )
|
for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ )
|
||||||
s += GetAnalyzerName(*j) + " ";
|
s += GetAnalyzerName(*j) + " ";
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, " %d/tcp: %s", i->first, s.c_str());
|
DBG_LOG(DBG_ANALYZER, " %d/tcp: %s", i->first, s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_udp.begin(); i != analyzers_by_port_udp.end(); i++ )
|
for ( analyzer_map_by_port::const_iterator i = analyzers_by_port_udp.begin(); i != analyzers_by_port_udp.end(); i++ )
|
||||||
|
@ -115,15 +124,15 @@ void Manager::DumpDebug()
|
||||||
for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ )
|
for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ )
|
||||||
s += GetAnalyzerName(*j) + " ";
|
s += GetAnalyzerName(*j) + " ";
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, " %d/udp: %s", i->first, s.c_str());
|
DBG_LOG(DBG_ANALYZER, " %d/udp: %s", i->first, s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ODesc d;
|
ODesc d;
|
||||||
tag_enum_type->Describe(&d);
|
tag_enum_type->Describe(&d);
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "");
|
DBG_LOG(DBG_ANALYZER, "");
|
||||||
DBG_LOG(DBG_DPD, "Analyzer::Tag type: %s", d.Description());
|
DBG_LOG(DBG_ANALYZER, "Analyzer::Tag type: %s", d.Description());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -133,35 +142,35 @@ void Manager::Done()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::RegisterAnalyzerComponent(PluginComponent* component)
|
void Manager::RegisterAnalyzerComponent(Component* component)
|
||||||
{
|
{
|
||||||
if ( Lookup(component->Name()) )
|
if ( Lookup(component->Name()) )
|
||||||
reporter->FatalError("Analyzer %s defined more than once", component->Name().c_str());
|
reporter->FatalError("Analyzer %s defined more than once", component->Name().c_str());
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "Registering analyzer %s (tag %s)",
|
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s (tag %s)",
|
||||||
component->Name().c_str(), component->Tag().AsString().c_str());
|
component->Name().c_str(), component->Tag().AsString().c_str());
|
||||||
|
|
||||||
analyzers_by_name.insert(std::make_pair(component->Name(), component));
|
analyzers_by_name.insert(std::make_pair(component->Name(), component));
|
||||||
analyzers_by_tag.insert(std::make_pair(component->Tag(), component));
|
analyzers_by_tag.insert(std::make_pair(component->Tag(), component));
|
||||||
analyzers_by_val.insert(std::make_pair(component->Tag().Val()->InternalInt(), component));
|
analyzers_by_val.insert(std::make_pair(component->Tag().AsEnumVal()->InternalInt(), component));
|
||||||
|
|
||||||
// Install enum "Analyzer::ANALYZER_*"
|
// Install enum "Analyzer::ANALYZER_*"
|
||||||
string name = to_upper(component->Name());
|
string name = to_upper(component->Name());
|
||||||
string id = fmt("ANALYZER_%s", name.c_str());
|
string id = fmt("ANALYZER_%s", name.c_str());
|
||||||
tag_enum_type->AddName("Analyzer", id.c_str(), component->Tag().Val()->InternalInt(), true);
|
tag_enum_type->AddName("Analyzer", id.c_str(), component->Tag().AsEnumVal()->InternalInt(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::EnableAnalyzer(Tag tag)
|
bool Manager::EnableAnalyzer(Tag tag)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(tag);
|
Component* p = Lookup(tag);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to enable non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to enable non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "Enabling analyzer %s", p->Name().c_str());
|
DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name().c_str());
|
||||||
p->SetEnabled(true);
|
p->SetEnabled(true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -169,15 +178,15 @@ bool Manager::EnableAnalyzer(Tag tag)
|
||||||
|
|
||||||
bool Manager::EnableAnalyzer(EnumVal* val)
|
bool Manager::EnableAnalyzer(EnumVal* val)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(val);
|
Component* p = Lookup(val);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to enable non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to enable non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "Enabling analyzer %s", p->Name().c_str());
|
DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name().c_str());
|
||||||
p->SetEnabled(true);
|
p->SetEnabled(true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -185,15 +194,15 @@ bool Manager::EnableAnalyzer(EnumVal* val)
|
||||||
|
|
||||||
bool Manager::DisableAnalyzer(Tag tag)
|
bool Manager::DisableAnalyzer(Tag tag)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(tag);
|
Component* p = Lookup(tag);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to disable non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to disable non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "Disabling analyzer %s", p->Name().c_str());
|
DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name().c_str());
|
||||||
p->SetEnabled(false);
|
p->SetEnabled(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -201,15 +210,15 @@ bool Manager::DisableAnalyzer(Tag tag)
|
||||||
|
|
||||||
bool Manager::DisableAnalyzer(EnumVal* val)
|
bool Manager::DisableAnalyzer(EnumVal* val)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(val);
|
Component* p = Lookup(val);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to disable non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to disable non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "Disabling analyzer %s", p->Name().c_str());
|
DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name().c_str());
|
||||||
p->SetEnabled(false);
|
p->SetEnabled(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -220,11 +229,11 @@ bool Manager::IsEnabled(Tag tag)
|
||||||
if ( ! tag )
|
if ( ! tag )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
PluginComponent* p = Lookup(tag);
|
Component* p = Lookup(tag);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to check non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to check non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,11 +242,11 @@ bool Manager::IsEnabled(Tag tag)
|
||||||
|
|
||||||
bool Manager::IsEnabled(EnumVal* val)
|
bool Manager::IsEnabled(EnumVal* val)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(val);
|
Component* p = Lookup(val);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to check non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to check non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,11 +256,11 @@ bool Manager::IsEnabled(EnumVal* val)
|
||||||
|
|
||||||
bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port)
|
bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(val);
|
Component* p = Lookup(val);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to register port for non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to register port for non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,11 +269,11 @@ bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port)
|
||||||
|
|
||||||
bool Manager::UnregisterAnalyzerForPort(EnumVal* val, PortVal* port)
|
bool Manager::UnregisterAnalyzerForPort(EnumVal* val, PortVal* port)
|
||||||
{
|
{
|
||||||
PluginComponent* p = Lookup(val);
|
Component* p = Lookup(val);
|
||||||
|
|
||||||
if ( ! p )
|
if ( ! p )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_DPD, "Asked to unregister port fork non-existing analyzer");
|
DBG_LOG(DBG_ANALYZER, "Asked to unregister port fork non-existing analyzer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +286,7 @@ bool Manager::RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::string name = GetAnalyzerName(tag);
|
std::string name = GetAnalyzerName(tag);
|
||||||
DBG_LOG(DBG_DPD, "Registering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto);
|
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
l->insert(tag);
|
l->insert(tag);
|
||||||
|
@ -290,7 +299,7 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::string name = GetAnalyzerName(tag);
|
std::string name = GetAnalyzerName(tag);
|
||||||
DBG_LOG(DBG_DPD, "Unregistering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto);
|
DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
l->erase(tag);
|
l->erase(tag);
|
||||||
|
@ -299,7 +308,7 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po
|
||||||
|
|
||||||
Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn)
|
Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn)
|
||||||
{
|
{
|
||||||
PluginComponent* c = Lookup(tag);
|
Component* c = Lookup(tag);
|
||||||
|
|
||||||
if ( ! c )
|
if ( ! c )
|
||||||
reporter->InternalError("request to instantiate unknown analyzer");
|
reporter->InternalError("request to instantiate unknown analyzer");
|
||||||
|
@ -329,7 +338,7 @@ const string& Manager::GetAnalyzerName(Tag tag)
|
||||||
if ( ! tag )
|
if ( ! tag )
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
PluginComponent* c = Lookup(tag);
|
Component* c = Lookup(tag);
|
||||||
|
|
||||||
if ( ! c )
|
if ( ! c )
|
||||||
reporter->InternalError("request for name of unknown analyzer tag %s", tag.AsString().c_str());
|
reporter->InternalError("request for name of unknown analyzer tag %s", tag.AsString().c_str());
|
||||||
|
@ -344,14 +353,14 @@ const string& Manager::GetAnalyzerName(Val* val)
|
||||||
|
|
||||||
Tag Manager::GetAnalyzerTag(const string& name)
|
Tag Manager::GetAnalyzerTag(const string& name)
|
||||||
{
|
{
|
||||||
PluginComponent* c = Lookup(name);
|
Component* c = Lookup(name);
|
||||||
return c ? c->Tag() : Tag::ERROR;
|
return c ? c->Tag() : Tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
Tag Manager::GetAnalyzerTag(const char* name)
|
Tag Manager::GetAnalyzerTag(const char* name)
|
||||||
{
|
{
|
||||||
PluginComponent* c = Lookup(name);
|
Component* c = Lookup(name);
|
||||||
return c ? c->Tag() : Tag::ERROR;
|
return c ? c->Tag() : Tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumType* Manager::GetTagEnumType()
|
EnumType* Manager::GetTagEnumType()
|
||||||
|
@ -359,26 +368,25 @@ EnumType* Manager::GetTagEnumType()
|
||||||
return tag_enum_type;
|
return tag_enum_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component* Manager::Lookup(const string& name)
|
||||||
PluginComponent* Manager::Lookup(const string& name)
|
|
||||||
{
|
{
|
||||||
analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name));
|
analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name));
|
||||||
return i != analyzers_by_name.end() ? i->second : 0;
|
return i != analyzers_by_name.end() ? i->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginComponent* Manager::Lookup(const char* name)
|
Component* Manager::Lookup(const char* name)
|
||||||
{
|
{
|
||||||
analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name));
|
analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name));
|
||||||
return i != analyzers_by_name.end() ? i->second : 0;
|
return i != analyzers_by_name.end() ? i->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginComponent* Manager::Lookup(const Tag& tag)
|
Component* Manager::Lookup(const Tag& tag)
|
||||||
{
|
{
|
||||||
analyzer_map_by_tag::const_iterator i = analyzers_by_tag.find(tag);
|
analyzer_map_by_tag::const_iterator i = analyzers_by_tag.find(tag);
|
||||||
return i != analyzers_by_tag.end() ? i->second : 0;
|
return i != analyzers_by_tag.end() ? i->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginComponent* Manager::Lookup(EnumVal* val)
|
Component* Manager::Lookup(EnumVal* val)
|
||||||
{
|
{
|
||||||
analyzer_map_by_val::const_iterator i = analyzers_by_val.find(val->InternalInt());
|
analyzer_map_by_val::const_iterator i = analyzers_by_val.find(val->InternalInt());
|
||||||
return i != analyzers_by_val.end() ? i->second : 0;
|
return i != analyzers_by_val.end() ? i->second : 0;
|
||||||
|
@ -419,69 +427,39 @@ Manager::tag_set* Manager::LookupPort(PortVal* val, bool add_if_not_found)
|
||||||
return LookupPort(val->PortType(), val->Port(), add_if_not_found);
|
return LookupPort(val->PortType(), val->Port(), add_if_not_found);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tag Manager::GetExpected(int proto, const Connection* conn)
|
bool Manager::BuildInitialAnalyzerTree(Connection* conn)
|
||||||
{
|
|
||||||
if ( ! expected_conns.Length() )
|
|
||||||
return Tag::ERROR;
|
|
||||||
|
|
||||||
ExpectedConn c(conn->OrigAddr(), conn->RespAddr(),
|
|
||||||
ntohs(conn->RespPort()), proto);
|
|
||||||
|
|
||||||
HashKey* key = BuildExpectedConnHashKey(c);
|
|
||||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
|
||||||
delete key;
|
|
||||||
|
|
||||||
if ( ! a )
|
|
||||||
{
|
|
||||||
// Wildcard for originator.
|
|
||||||
c.orig = IPAddr(string("::"));
|
|
||||||
|
|
||||||
HashKey* key = BuildExpectedConnHashKey(c);
|
|
||||||
a = expected_conns.Lookup(key);
|
|
||||||
delete key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! a )
|
|
||||||
return Tag::ERROR;
|
|
||||||
|
|
||||||
// We don't delete it here. It will be expired eventually.
|
|
||||||
return a->analyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
|
||||||
const u_char* data)
|
|
||||||
{
|
{
|
||||||
Analyzer* analyzer = 0;
|
Analyzer* analyzer = 0;
|
||||||
TCP_Analyzer* tcp = 0;
|
TCP_Analyzer* tcp = 0;
|
||||||
UDP_Analyzer* udp = 0;
|
UDP_Analyzer* udp = 0;
|
||||||
ICMP_Analyzer* icmp = 0;
|
ICMP_Analyzer* icmp = 0;
|
||||||
TransportLayerAnalyzer* root = 0;
|
TransportLayerAnalyzer* root = 0;
|
||||||
Tag expected = Tag::ERROR;
|
tag_set expected;
|
||||||
PIA* pia = 0;
|
PIA* pia = 0;
|
||||||
bool analyzed = false;
|
bool analyzed = false;
|
||||||
bool check_port = false;
|
bool check_port = false;
|
||||||
|
|
||||||
switch ( proto ) {
|
switch ( conn->ConnTransport() ) {
|
||||||
|
|
||||||
case TRANSPORT_TCP:
|
case TRANSPORT_TCP:
|
||||||
root = tcp = new TCP_Analyzer(conn);
|
root = tcp = new TCP_Analyzer(conn);
|
||||||
pia = new PIA_TCP(conn);
|
pia = new PIA_TCP(conn);
|
||||||
expected = GetExpected(proto, conn);
|
expected = GetScheduled(conn);
|
||||||
check_port = true;
|
check_port = true;
|
||||||
DBG_DPD(conn, "activated TCP analyzer");
|
DBG_ANALYZER(conn, "activated TCP analyzer");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRANSPORT_UDP:
|
case TRANSPORT_UDP:
|
||||||
root = udp = new UDP_Analyzer(conn);
|
root = udp = new UDP_Analyzer(conn);
|
||||||
pia = new PIA_UDP(conn);
|
pia = new PIA_UDP(conn);
|
||||||
expected = GetExpected(proto, conn);
|
expected = GetScheduled(conn);
|
||||||
check_port = true;
|
check_port = true;
|
||||||
DBG_DPD(conn, "activated UDP analyzer");
|
DBG_ANALYZER(conn, "activated UDP analyzer");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRANSPORT_ICMP: {
|
case TRANSPORT_ICMP: {
|
||||||
root = icmp = new ICMP_Analyzer(conn);
|
root = icmp = new ICMP_Analyzer(conn);
|
||||||
DBG_DPD(conn, "activated ICMP analyzer");
|
DBG_ANALYZER(conn, "activated ICMP analyzer");
|
||||||
analyzed = true;
|
analyzed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -492,34 +470,34 @@ bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||||
|
|
||||||
if ( ! root )
|
if ( ! root )
|
||||||
{
|
{
|
||||||
DBG_DPD(conn, "cannot build analyzer tree");
|
DBG_ANALYZER(conn, "cannot build analyzer tree");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any scheduled analyzer?
|
// Any scheduled analyzer?
|
||||||
if ( expected )
|
for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ )
|
||||||
{
|
{
|
||||||
Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(expected, conn);
|
Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(*i, conn);
|
||||||
|
|
||||||
if ( analyzer )
|
if ( analyzer )
|
||||||
{
|
{
|
||||||
root->AddChildAnalyzer(analyzer, false);
|
root->AddChildAnalyzer(analyzer, false);
|
||||||
|
|
||||||
DBG_DPD_ARGS(conn, "activated %s analyzer as scheduled",
|
DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled",
|
||||||
analyzer_mgr->GetAnalyzerName(expected).c_str());
|
analyzer_mgr->GetAnalyzerName(*i).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hmm... Do we want *just* the expected analyzer, or all
|
// Hmm... Do we want *just* the expected analyzer, or all
|
||||||
// other potential analyzers as well? For now we only take
|
// other potential analyzers as well? For now we only take
|
||||||
// the scheduled one.
|
// the scheduled ones.
|
||||||
}
|
if ( expected.size() == 0 )
|
||||||
|
|
||||||
else
|
|
||||||
{ // Let's see if it's a port we know.
|
{ // Let's see if it's a port we know.
|
||||||
if ( check_port && ! dpd_ignore_ports )
|
if ( check_port && ! dpd_ignore_ports )
|
||||||
{
|
{
|
||||||
int resp_port = ntohs(conn->RespPort());
|
int resp_port = ntohs(conn->RespPort());
|
||||||
tag_set* ports = LookupPort(proto, resp_port, false);
|
tag_set* ports = LookupPort(conn->ConnTransport(), resp_port, false);
|
||||||
|
|
||||||
if ( ports )
|
if ( ports )
|
||||||
{
|
{
|
||||||
|
@ -531,7 +509,7 @@ bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
root->AddChildAnalyzer(analyzer, false);
|
root->AddChildAnalyzer(analyzer, false);
|
||||||
DBG_DPD_ARGS(conn, "activated %s analyzer due to port %d",
|
DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d",
|
||||||
analyzer_mgr->GetAnalyzerName(*j).c_str(), resp_port);
|
analyzer_mgr->GetAnalyzerName(*j).c_str(), resp_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -622,78 +600,116 @@ bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||||
if ( ! analyzed )
|
if ( ! analyzed )
|
||||||
conn->SetLifetime(non_analyzed_lifetime);
|
conn->SetLifetime(non_analyzed_lifetime);
|
||||||
|
|
||||||
if ( expected != Tag::ERROR )
|
for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ )
|
||||||
conn->Event(expected_connection_seen, 0,
|
conn->Event(scheduled_analyzer_applied, 0, i->AsEnumVal());
|
||||||
new Val(expected, TYPE_COUNT));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ExpectConnection(const IPAddr& orig, const IPAddr& resp,
|
void Manager::ExpireScheduledAnalyzers()
|
||||||
uint16 resp_p,
|
|
||||||
TransportProto proto, Tag analyzer,
|
|
||||||
double timeout, void* cookie)
|
|
||||||
{
|
{
|
||||||
// Use the chance to see if the oldest entry is already expired.
|
if ( ! network_time )
|
||||||
if ( expected_conns_queue.size() )
|
return;
|
||||||
{
|
|
||||||
AssignedAnalyzer* a = expected_conns_queue.top();
|
|
||||||
if ( a->timeout < network_time )
|
|
||||||
{
|
|
||||||
if ( ! a->deleted )
|
|
||||||
{
|
|
||||||
HashKey* key = BuildExpectedConnHashKey(a->conn);
|
|
||||||
expected_conns.Remove(key);
|
|
||||||
delete key;
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_conns_queue.pop();
|
while ( conns_by_timeout.size() )
|
||||||
|
{
|
||||||
|
ScheduledAnalyzer* a = conns_by_timeout.top();
|
||||||
|
|
||||||
DBG_LOG(DBG_DPD, "Expired expected %s analyzer for %s",
|
if ( a->timeout > network_time )
|
||||||
analyzer_mgr->GetAnalyzerName(analyzer).c_str(),
|
return;
|
||||||
fmt_conn_id(a->conn.orig, 0,
|
|
||||||
a->conn.resp,
|
conns_by_timeout.pop();
|
||||||
a->conn.resp_p));
|
|
||||||
|
std::pair<conns_map::iterator, conns_map::iterator> all = conns.equal_range(a->conn);
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for ( conns_map::iterator i = all.first; i != all.second; i++ )
|
||||||
|
{
|
||||||
|
if ( i->second != a )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
conns.erase(i);
|
||||||
|
|
||||||
|
DBG_LOG(DBG_ANALYZER, "Expiring expected analyzer %s for connection %s",
|
||||||
|
analyzer_mgr->GetAnalyzerName(a->analyzer).c_str(),
|
||||||
|
fmt_conn_id(a->conn.orig, 0, a->conn.resp, a->conn.resp_p));
|
||||||
|
|
||||||
delete a;
|
delete a;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpectedConn c(orig, resp, resp_p, proto);
|
void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp,
|
||||||
|
uint16 resp_p,
|
||||||
|
TransportProto proto, Tag analyzer,
|
||||||
|
double timeout)
|
||||||
|
{
|
||||||
|
if ( ! network_time )
|
||||||
|
{
|
||||||
|
reporter->Warning("cannot schedule analyzers before processing begins; ignored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HashKey* key = BuildExpectedConnHashKey(c);
|
assert(timeout);
|
||||||
|
|
||||||
AssignedAnalyzer* a = expected_conns.Lookup(key);
|
// Use the chance to see if the oldest entry is already expired.
|
||||||
|
ExpireScheduledAnalyzers();
|
||||||
if ( a )
|
|
||||||
a->deleted = true;
|
|
||||||
|
|
||||||
a = new AssignedAnalyzer(c);
|
|
||||||
|
|
||||||
|
ScheduledAnalyzer* a = new ScheduledAnalyzer;
|
||||||
|
a->conn = ConnIndex(orig, resp, resp_p, proto);
|
||||||
a->analyzer = analyzer;
|
a->analyzer = analyzer;
|
||||||
a->cookie = cookie;
|
|
||||||
a->timeout = network_time + timeout;
|
a->timeout = network_time + timeout;
|
||||||
a->deleted = false;
|
|
||||||
|
|
||||||
expected_conns.Insert(key, a);
|
conns.insert(std::make_pair(a->conn, a));
|
||||||
expected_conns_queue.push(a);
|
conns_by_timeout.push(a);
|
||||||
delete key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ExpectConnection(const IPAddr& orig, const IPAddr& resp,
|
void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp,
|
||||||
uint16 resp_p,
|
uint16 resp_p,
|
||||||
TransportProto proto, const string& analyzer,
|
TransportProto proto, const string& analyzer,
|
||||||
double timeout, void* cookie)
|
double timeout)
|
||||||
{
|
{
|
||||||
Tag tag = GetAnalyzerTag(analyzer);
|
Tag tag = GetAnalyzerTag(analyzer);
|
||||||
|
|
||||||
if ( tag != Tag::ERROR )
|
if ( tag != Tag() )
|
||||||
ExpectConnection(orig, resp, resp_p, proto, tag, timeout, cookie);
|
ScheduleAnalyzer(orig, resp, resp_p, proto, tag, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ExpectConnection(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p,
|
void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p,
|
||||||
Val* analyzer, double timeout, void* cookie)
|
Val* analyzer, double timeout)
|
||||||
{
|
{
|
||||||
EnumVal* ev = analyzer->AsEnumVal();
|
EnumVal* ev = analyzer->AsEnumVal();
|
||||||
return ExpectConnection(orig, resp, resp_p->Port(), resp_p->PortType(), Tag(ev), timeout, cookie);
|
return ScheduleAnalyzer(orig, resp, resp_p->Port(), resp_p->PortType(), Tag(ev), timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::tag_set Manager::GetScheduled(const Connection* conn)
|
||||||
|
{
|
||||||
|
ConnIndex c(conn->OrigAddr(), conn->RespAddr(),
|
||||||
|
ntohs(conn->RespPort()), conn->ConnTransport());
|
||||||
|
|
||||||
|
std::pair<conns_map::iterator, conns_map::iterator> all = conns.equal_range(c);
|
||||||
|
|
||||||
|
tag_set result;
|
||||||
|
|
||||||
|
for ( conns_map::iterator i = all.first; i != all.second; i++ )
|
||||||
|
result.insert(i->second->analyzer);
|
||||||
|
|
||||||
|
// Try wildcard for originator.
|
||||||
|
c.orig = IPAddr(string("::"));
|
||||||
|
all = conns.equal_range(c);
|
||||||
|
|
||||||
|
for ( conns_map::iterator i = all.first; i != all.second; i++ )
|
||||||
|
{
|
||||||
|
if ( i->second->timeout > network_time )
|
||||||
|
result.insert(i->second->analyzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't delete scheduled analyzers here. They will be expired
|
||||||
|
// eventually.
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
// The central management unit for dynamic analyzer selection.
|
/**
|
||||||
|
* The central management unit for registering and instantiating analyzers.
|
||||||
|
*
|
||||||
|
* For each protocol that Bro supports, there's one class derived from
|
||||||
|
* analyzer::Analyzer. Once we have decided that a connection's payload is to
|
||||||
|
* be parsed as a given protocol, we instantiate the corresponding
|
||||||
|
* analyzer-derived class and add the new instance as a child node into the
|
||||||
|
* connection's analyzer tree.
|
||||||
|
*
|
||||||
|
* In addition to the analyzer-derived class itself, for each protocol
|
||||||
|
* there's also "meta-class" derived from analyzer::Component that describes
|
||||||
|
* the analyzer, including status information on if that particular protocol
|
||||||
|
* analysis is currently enabled.
|
||||||
|
*
|
||||||
|
* To identify an analyzer (or to be precise: a component), the manager
|
||||||
|
* maintains mappings of (1) analyzer::Tag to component, and (2)
|
||||||
|
* human-readable analyzer name to component.
|
||||||
|
*/
|
||||||
#ifndef ANALYZER_MANAGER_H
|
#ifndef ANALYZER_MANAGER_H
|
||||||
#define ANALYZER_MANAGER_H
|
#define ANALYZER_MANAGER_H
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "Analyzer.h"
|
#include "Analyzer.h"
|
||||||
#include "PluginComponent.h"
|
#include "Component.h"
|
||||||
#include "Tag.h"
|
#include "Tag.h"
|
||||||
|
|
||||||
#include "../Dict.h"
|
#include "../Dict.h"
|
||||||
|
@ -15,139 +31,333 @@
|
||||||
|
|
||||||
namespace analyzer {
|
namespace analyzer {
|
||||||
|
|
||||||
// Manager debug logging, which includes the connection id into the message.
|
/**
|
||||||
#ifdef DEBUG
|
* Class maintaining and scheduling available protocol analyzers.
|
||||||
# define DBG_DPD(conn, txt) \
|
*
|
||||||
DBG_LOG(DBG_DPD, "%s " txt, \
|
* The manager maintains a registry of all available protocol analyzers,
|
||||||
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
* including a mapping between their textual names and analyzer::Tag. It
|
||||||
conn->RespAddr(), ntohs(conn->RespPort())));
|
* instantantiates new analyzers on demand. For new connections, the manager
|
||||||
# define DBG_DPD_ARGS(conn, fmt, args...) \
|
* sets up their initial analyzer tree, including adding the right \c PIA,
|
||||||
DBG_LOG(DBG_DPD, "%s " fmt, \
|
* respecting well-known ports, and tracking any analyzers specifically
|
||||||
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
* scheduled for individidual connections.
|
||||||
conn->RespAddr(), ntohs(conn->RespPort())), ##args);
|
*/
|
||||||
#else
|
|
||||||
# define DBG_DPD(conn, txt)
|
|
||||||
# define DBG_DPD_ARGS(conn, fmt, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Map index to assign expected connections to analyzers.
|
|
||||||
class ExpectedConn {
|
|
||||||
public:
|
|
||||||
ExpectedConn(const IPAddr& _orig, const IPAddr& _resp,
|
|
||||||
uint16 _resp_p, uint16 _proto);
|
|
||||||
|
|
||||||
ExpectedConn(const ExpectedConn& c);
|
|
||||||
|
|
||||||
IPAddr orig;
|
|
||||||
IPAddr resp;
|
|
||||||
uint16 resp_p;
|
|
||||||
uint16 proto;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Associates an analyzer for an expected future connection.
|
|
||||||
class AssignedAnalyzer {
|
|
||||||
public:
|
|
||||||
AssignedAnalyzer(const ExpectedConn& c)
|
|
||||||
: conn(c) { }
|
|
||||||
|
|
||||||
ExpectedConn conn;
|
|
||||||
Tag analyzer;
|
|
||||||
double timeout;
|
|
||||||
void* cookie;
|
|
||||||
bool deleted;
|
|
||||||
|
|
||||||
static bool compare(const AssignedAnalyzer* a1, const AssignedAnalyzer* a2)
|
|
||||||
{ return a1->timeout > a2->timeout; }
|
|
||||||
};
|
|
||||||
|
|
||||||
declare(PDict, AssignedAnalyzer);
|
|
||||||
|
|
||||||
class Manager {
|
class Manager {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
Manager();
|
Manager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
~Manager();
|
~Manager();
|
||||||
|
|
||||||
void Init(); // Called before script's are parsed.
|
/**
|
||||||
|
* Initializes the manager's operation. Must be called before scripts
|
||||||
|
* are parsed.
|
||||||
|
*/
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finished the manager's operations.
|
||||||
|
*/
|
||||||
void Done();
|
void Done();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumps out the state of all registered analyzers to the \c analyzer
|
||||||
|
* debug stream. Should be called only after any \c bro_init events
|
||||||
|
* have executed to ensure that any of their changes are applied.
|
||||||
|
*/
|
||||||
void DumpDebug(); // Called after bro_init() events.
|
void DumpDebug(); // Called after bro_init() events.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables an analyzer type. Only enabled analyzers will be
|
||||||
|
* instantiated for new connections.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*
|
||||||
|
* @return True if sucessful.
|
||||||
|
*/
|
||||||
bool EnableAnalyzer(Tag tag);
|
bool EnableAnalyzer(Tag tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables an analyzer type. Only enabled analyzers will be
|
||||||
|
* instantiated for new connections.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag as an enum of script type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*
|
||||||
|
* @return True if sucessful.
|
||||||
|
*/
|
||||||
bool EnableAnalyzer(EnumVal* tag);
|
bool EnableAnalyzer(EnumVal* tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables an analyzer type. Disabled analyzers will not be
|
||||||
|
* instantiated for new connections.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*
|
||||||
|
* @return True if sucessful.
|
||||||
|
*/
|
||||||
bool DisableAnalyzer(Tag tag);
|
bool DisableAnalyzer(Tag tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables an analyzer type. Disabled analyzers will not be
|
||||||
|
* instantiated for new connections.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag as an enum of script type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*
|
||||||
|
* @return True if sucessful.
|
||||||
|
*/
|
||||||
bool DisableAnalyzer(EnumVal* tag);
|
bool DisableAnalyzer(EnumVal* tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if an analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*/
|
||||||
bool IsEnabled(Tag tag);
|
bool IsEnabled(Tag tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if an analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag as an enum of script type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*/
|
||||||
bool IsEnabled(EnumVal* tag);
|
bool IsEnabled(EnumVal* tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a well-known port for an analyzer. Once registered,
|
||||||
|
* connection on that port will start with a corresponding analyzer
|
||||||
|
* assigned.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag as an enum of script type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*
|
||||||
|
* @param port The well-known port.
|
||||||
|
*
|
||||||
|
* @return True if sucessful.
|
||||||
|
*/
|
||||||
bool RegisterAnalyzerForPort(EnumVal* tag, PortVal* port);
|
bool RegisterAnalyzerForPort(EnumVal* tag, PortVal* port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a well-known port for an analyzer. Once registered,
|
||||||
|
* connection on that port will start with a corresponding analyzer
|
||||||
|
* assigned.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*
|
||||||
|
* @param proto The port's protocol.
|
||||||
|
*
|
||||||
|
* @param port The port's number.
|
||||||
|
*
|
||||||
|
* @return True if sucessful.
|
||||||
|
*/
|
||||||
bool RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port);
|
bool RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a well-known port for an anlyzers.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag as an enum of script type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*
|
||||||
|
* @param port The well-known port.
|
||||||
|
*
|
||||||
|
* @return True if sucessful (incl. when the port wasn't actually
|
||||||
|
* registered for the analyzer).
|
||||||
|
*
|
||||||
|
*/
|
||||||
bool UnregisterAnalyzerForPort(EnumVal* tag, PortVal* port);
|
bool UnregisterAnalyzerForPort(EnumVal* tag, PortVal* port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a well-known port for an anlyzers.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*
|
||||||
|
* @param proto The port's protocol.
|
||||||
|
*
|
||||||
|
* @param port The port's number.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag as an enum of script type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*/
|
||||||
bool UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port);
|
bool UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new analyzer instance for a connection.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*
|
||||||
|
* @param conn The connection the analyzer is to be associated with.
|
||||||
|
*
|
||||||
|
* @return The new analyzer instance. Note that the analyzer will not
|
||||||
|
* have been added to the connection's analyzer tree yet. Returns
|
||||||
|
* null if tag is invalid or the requested analyzer is disabled.
|
||||||
|
*/
|
||||||
Analyzer* InstantiateAnalyzer(Tag tag, Connection* c); // Null if disabled or not available.
|
Analyzer* InstantiateAnalyzer(Tag tag, Connection* c); // Null if disabled or not available.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new analyzer instance for a connection.
|
||||||
|
*
|
||||||
|
* @param name The name of the analyzer.
|
||||||
|
*
|
||||||
|
* @param conn The connection the analyzer is to be associated with.
|
||||||
|
*
|
||||||
|
* @return The new analyzer instance. Note that the analyzer will not
|
||||||
|
* have been added to the connection's analyzer tree yet. Returns
|
||||||
|
* null if the name is not known or if the requested analyzer that is
|
||||||
|
* disabled.
|
||||||
|
*/
|
||||||
Analyzer* InstantiateAnalyzer(const char* name, Connection* c); // Null if disabled or not available.
|
Analyzer* InstantiateAnalyzer(const char* name, Connection* c); // Null if disabled or not available.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates an analyzer tag into corresponding analyzer name.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer tag.
|
||||||
|
*
|
||||||
|
* @return The name, or an empty string if the tag is invalid.
|
||||||
|
*/
|
||||||
const string& GetAnalyzerName(Tag tag);
|
const string& GetAnalyzerName(Tag tag);
|
||||||
const string& GetAnalyzerName(Val* val);
|
|
||||||
Tag GetAnalyzerTag(const string& name); // Tag::ERROR when not known.
|
|
||||||
Tag GetAnalyzerTag(const char* name); // Tag::ERROR when not known.
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates an script-level analyzer tag into corresponding
|
||||||
|
* analyzer name.
|
||||||
|
*
|
||||||
|
* @param val The analyzer tag as an script-level enum value of type
|
||||||
|
* \c Analyzer::Tag.
|
||||||
|
*
|
||||||
|
* @return The name, or an empty string if the tag is invalid.
|
||||||
|
*/
|
||||||
|
const string& GetAnalyzerName(Val* val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates an analyzer name into the corresponding tag.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
*
|
||||||
|
* @return The tag. If the name does not correspond to a valid
|
||||||
|
* analyzer, the returned tag will evaluate to false.
|
||||||
|
*/
|
||||||
|
Tag GetAnalyzerTag(const string& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates an analyzer name into the corresponding tag.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
*
|
||||||
|
* @return The tag. If the name does not correspond to a valid
|
||||||
|
* analyzer, the returned tag will evaluate to false.
|
||||||
|
*/
|
||||||
|
Tag GetAnalyzerTag(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enum type that corresponds to the script-level type \c
|
||||||
|
* Analyzer::Tag.
|
||||||
|
*/
|
||||||
EnumType* GetTagEnumType();
|
EnumType* GetTagEnumType();
|
||||||
|
|
||||||
// Given info about the first packet, build initial analyzer tree.
|
/**
|
||||||
//
|
* Given the first packet of a connection, builds its initial
|
||||||
// It would be more flexible if we simply pass in the IP header and
|
* analyzer tree.
|
||||||
// then extract the information we need. However, when this method
|
*
|
||||||
// is called from the session management, protocol and ports have
|
* @param conn The connection to add the initial set of analyzers to.
|
||||||
// already been extracted there and it would be a waste to do it
|
*
|
||||||
// again.
|
* @return False if the tree cannot be build; that's usually an
|
||||||
//
|
* internally error.
|
||||||
// Returns 0 if we can't build a tree (e.g., because the necessary
|
*/
|
||||||
// analyzers have not been converted to the Manager framework yet...)
|
bool BuildInitialAnalyzerTree(Connection* conn);
|
||||||
bool BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
|
||||||
const u_char* data);
|
|
||||||
|
|
||||||
// Schedules a particular analyzer for an upcoming connection. 0 acts
|
/**
|
||||||
// as a wildcard for orig. (Cookie is currently unused. Eventually,
|
* Schedules a particular analyzer for an upcoming connection. Once
|
||||||
// we may pass it on to the analyzer).
|
* the connection is seen, BuildInitAnalyzerTree() will add the
|
||||||
void ExpectConnection(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
|
* specified analyzer to its tree.
|
||||||
TransportProto proto, Tag analyzer,
|
*
|
||||||
double timeout, void* cookie);
|
* @param orig The connection's anticipated originator address.
|
||||||
|
* 0.0.0.0 can be used as a wildcard matching any originator.
|
||||||
|
*
|
||||||
|
* @param resp The connection's anticipated responder address (no
|
||||||
|
* wilcard).
|
||||||
|
*
|
||||||
|
* @param resp_p The connection's anticipated responder port.
|
||||||
|
*
|
||||||
|
* @param proto The connection's anticipated transport protocol.
|
||||||
|
*
|
||||||
|
* @param analyzer The analyzer to use once the connection is seen.
|
||||||
|
*
|
||||||
|
* @param timeout An interval after which to timeout the request to
|
||||||
|
* schedule this analyzer. Must be non-zero.
|
||||||
|
*/
|
||||||
|
void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
|
||||||
|
TransportProto proto, Tag analyzer, double timeout);
|
||||||
|
|
||||||
void ExpectConnection(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
|
/**
|
||||||
|
* Schedules a particular analyzer for an upcoming connection. Once
|
||||||
|
* the connection is seen, BuildInitAnalyzerTree() will add the
|
||||||
|
* specified analyzer to its tree.
|
||||||
|
*
|
||||||
|
* @param orig The connection's anticipated originator address. 0 can
|
||||||
|
* be used as a wildcard matching any originator.
|
||||||
|
*
|
||||||
|
* @param resp The The connection's anticipated responder address (no
|
||||||
|
* wilcard).
|
||||||
|
*
|
||||||
|
* @param resp_p The connection's anticipated responder port.
|
||||||
|
*
|
||||||
|
* @param proto The connection's anticipated transport protocol.
|
||||||
|
*
|
||||||
|
* @param analyzer The name of the analyzer to use once the
|
||||||
|
* connection is seen.
|
||||||
|
*
|
||||||
|
* @param timeout An interval after which to timeout the request to
|
||||||
|
* schedule this analyzer. Must be non-zero.
|
||||||
|
*/
|
||||||
|
void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
|
||||||
TransportProto proto, const string& analyzer,
|
TransportProto proto, const string& analyzer,
|
||||||
double timeout, void* cookie);
|
double timeout);
|
||||||
|
|
||||||
void ExpectConnection(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p,
|
/**
|
||||||
Val* val, double timeout, void* cookie);
|
* Schedules a particular analyzer for an upcoming connection. Once
|
||||||
|
* the connection is seen, BuildInitAnalyzerTree() will add the
|
||||||
// Activates signature matching for protocol detection. (Called when
|
* specified analyzer to its tree.
|
||||||
// an Manager signatures is found.)
|
*
|
||||||
void ActivateSigs() { sigs_activated = true; }
|
* @param orig The connection's anticipated originator address. 0 can
|
||||||
bool SigsActivated() const { return sigs_activated; }
|
* be used as a wildcard matching any originator.
|
||||||
|
*
|
||||||
|
* @param resp The connection's anticipated responder address (no
|
||||||
|
* wilcard).
|
||||||
|
*
|
||||||
|
* @param resp_p The connection's anticipated responder port.
|
||||||
|
*
|
||||||
|
* @param analyzer The analyzer to use once the connection is seen as
|
||||||
|
* an enum value of script-type \c Analyzer::Tag.
|
||||||
|
*
|
||||||
|
* @param timeout An interval after which to timeout the request to
|
||||||
|
* schedule this analyzer. Must be non-zero.
|
||||||
|
*/
|
||||||
|
void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p,
|
||||||
|
Val* analyzer, double timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef set<Tag> tag_set;
|
typedef set<Tag> tag_set;
|
||||||
typedef map<string, PluginComponent*> analyzer_map_by_name;
|
typedef map<string, Component*> analyzer_map_by_name;
|
||||||
typedef map<Tag, PluginComponent*> analyzer_map_by_tag;
|
typedef map<Tag, Component*> analyzer_map_by_tag;
|
||||||
typedef map<int, PluginComponent*> analyzer_map_by_val;
|
typedef map<int, Component*> analyzer_map_by_val;
|
||||||
typedef map<uint32, tag_set*> analyzer_map_by_port;
|
typedef map<uint32, tag_set*> analyzer_map_by_port;
|
||||||
|
|
||||||
void RegisterAnalyzerComponent(PluginComponent* component); // Takes ownership.
|
void RegisterAnalyzerComponent(Component* component); // Takes ownership.
|
||||||
|
|
||||||
PluginComponent* Lookup(const string& name);
|
Component* Lookup(const string& name);
|
||||||
PluginComponent* Lookup(const char* name);
|
Component* Lookup(const char* name);
|
||||||
PluginComponent* Lookup(const Tag& tag);
|
Component* Lookup(const Tag& tag);
|
||||||
PluginComponent* Lookup(EnumVal* val);
|
Component* Lookup(EnumVal* val);
|
||||||
|
|
||||||
tag_set* LookupPort(PortVal* val, bool add_if_not_found);
|
tag_set* LookupPort(PortVal* val, bool add_if_not_found);
|
||||||
tag_set* LookupPort(TransportProto proto, uint32 port, bool add_if_not_found);
|
tag_set* LookupPort(TransportProto proto, uint32 port, bool add_if_not_found);
|
||||||
|
|
||||||
// Return analyzer if any has been scheduled with ExpectConnection()
|
tag_set GetScheduled(const Connection* conn);
|
||||||
// Tag::::Error if none.
|
void ExpireScheduledAnalyzers();
|
||||||
Tag GetExpected(int proto, const Connection* conn);
|
|
||||||
|
|
||||||
analyzer_map_by_port analyzers_by_port_tcp;
|
analyzer_map_by_port analyzers_by_port_tcp;
|
||||||
analyzer_map_by_port analyzers_by_port_udp;
|
analyzer_map_by_port analyzers_by_port_udp;
|
||||||
|
@ -163,21 +373,62 @@ private:
|
||||||
|
|
||||||
EnumType* tag_enum_type;
|
EnumType* tag_enum_type;
|
||||||
|
|
||||||
// True if signature-matching has been activated.
|
//// Data structures to track analyzed scheduled for future connections.
|
||||||
bool sigs_activated;
|
|
||||||
|
|
||||||
PDict(AssignedAnalyzer) expected_conns;
|
// The index for a scheduled connection.
|
||||||
|
struct ConnIndex {
|
||||||
|
IPAddr orig;
|
||||||
|
IPAddr resp;
|
||||||
|
uint16 resp_p;
|
||||||
|
uint16 proto;
|
||||||
|
|
||||||
typedef priority_queue<
|
ConnIndex(const IPAddr& _orig, const IPAddr& _resp,
|
||||||
AssignedAnalyzer*,
|
uint16 _resp_p, uint16 _proto);
|
||||||
vector<AssignedAnalyzer*>,
|
ConnIndex();
|
||||||
bool (*)(const AssignedAnalyzer*,
|
|
||||||
const AssignedAnalyzer*)> conn_queue;
|
bool operator<(const ConnIndex& other) const;
|
||||||
conn_queue expected_conns_queue;
|
};
|
||||||
|
|
||||||
|
// Information associated with a scheduled connection.
|
||||||
|
struct ScheduledAnalyzer {
|
||||||
|
ConnIndex conn;
|
||||||
|
Tag analyzer;
|
||||||
|
double timeout;
|
||||||
|
|
||||||
|
struct Comparator {
|
||||||
|
bool operator() (ScheduledAnalyzer* a, ScheduledAnalyzer* b) {
|
||||||
|
return a->timeout > b->timeout;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::multimap<ConnIndex, ScheduledAnalyzer*> conns_map;
|
||||||
|
typedef std::priority_queue<ScheduledAnalyzer*,
|
||||||
|
vector<ScheduledAnalyzer*>,
|
||||||
|
ScheduledAnalyzer::Comparator> conns_queue;
|
||||||
|
|
||||||
|
conns_map conns;
|
||||||
|
conns_queue conns_by_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern analyzer::Manager* analyzer_mgr;
|
extern analyzer::Manager* analyzer_mgr;
|
||||||
|
|
||||||
|
// Macros for anayzer debug logging which include the connection id into the
|
||||||
|
// message.
|
||||||
|
#ifdef DEBUG
|
||||||
|
# define DBG_ANALYZER(conn, txt) \
|
||||||
|
DBG_LOG(DBG_ANALYZER, "%s " txt, \
|
||||||
|
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
||||||
|
conn->RespAddr(), ntohs(conn->RespPort())));
|
||||||
|
# define DBG_ANALYZER_ARGS(conn, fmt, args...) \
|
||||||
|
DBG_LOG(DBG_ANALYZER, "%s " fmt, \
|
||||||
|
fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \
|
||||||
|
conn->RespAddr(), ntohs(conn->RespPort())), ##args);
|
||||||
|
#else
|
||||||
|
# define DBG_ANALYZER(conn, txt)
|
||||||
|
# define DBG_ANALYZER_ARGS(conn, fmt, args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
|
|
||||||
#include "PluginComponent.h"
|
|
||||||
|
|
||||||
#include "../Desc.h"
|
|
||||||
|
|
||||||
using namespace analyzer;
|
|
||||||
|
|
||||||
Tag::type_t PluginComponent::type_counter = 0;
|
|
||||||
|
|
||||||
PluginComponent::PluginComponent(std::string arg_name, factory_callback arg_factory, bool arg_enabled, bool arg_partial)
|
|
||||||
: Component(plugin::component::ANALYZER)
|
|
||||||
{
|
|
||||||
name = arg_name;
|
|
||||||
factory = arg_factory;
|
|
||||||
enabled = arg_enabled;
|
|
||||||
partial = arg_partial;
|
|
||||||
|
|
||||||
tag = analyzer::Tag(++type_counter, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginComponent::PluginComponent(std::string arg_name, Tag::subtype_t arg_stype, factory_callback arg_factory, bool arg_enabled, bool arg_partial)
|
|
||||||
: Component(plugin::component::ANALYZER)
|
|
||||||
{
|
|
||||||
name = arg_name;
|
|
||||||
factory = arg_factory;
|
|
||||||
enabled = arg_enabled;
|
|
||||||
partial = arg_partial;
|
|
||||||
|
|
||||||
tag = analyzer::Tag(++type_counter, arg_stype);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginComponent::Describe(ODesc* d)
|
|
||||||
{
|
|
||||||
plugin::Component::Describe(d);
|
|
||||||
d->Add(name);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
|
|
||||||
#ifndef ANALYZER_PLUGIN_COMPONENT_H
|
|
||||||
#define ANALYZER_PLUGIN_COMPONENT_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../config.h"
|
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
#include "plugin/Component.h"
|
|
||||||
#include "Tag.h"
|
|
||||||
|
|
||||||
class Connection;
|
|
||||||
|
|
||||||
namespace analyzer {
|
|
||||||
|
|
||||||
class Analyzer;
|
|
||||||
|
|
||||||
// This can be copied by value.
|
|
||||||
class PluginComponent : public plugin::Component {
|
|
||||||
public:
|
|
||||||
typedef bool (*available_callback)();
|
|
||||||
typedef Analyzer* (*factory_callback)(Connection* conn);
|
|
||||||
|
|
||||||
PluginComponent(std::string name, factory_callback factory, bool enabled, bool partial);
|
|
||||||
PluginComponent(std::string name, Tag::subtype_t subtype, factory_callback factory, bool enabled, bool partial);
|
|
||||||
|
|
||||||
const std::string& Name() const { return name; }
|
|
||||||
factory_callback Factory() const { return factory; }
|
|
||||||
bool Partial() const { return partial; }
|
|
||||||
bool Enabled() const { return enabled; }
|
|
||||||
analyzer::Tag Tag() const { return tag; }
|
|
||||||
|
|
||||||
void SetEnabled(bool arg_enabled) { enabled = arg_enabled; }
|
|
||||||
|
|
||||||
virtual void Describe(ODesc* d);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
factory_callback factory;
|
|
||||||
bool partial;
|
|
||||||
|
|
||||||
analyzer::Tag tag;
|
|
||||||
bool enabled;
|
|
||||||
|
|
||||||
static analyzer::Tag::type_t type_counter;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -6,11 +6,10 @@
|
||||||
|
|
||||||
using namespace analyzer;
|
using namespace analyzer;
|
||||||
|
|
||||||
Tag Tag::ERROR;
|
|
||||||
|
|
||||||
Tag::Tag(type_t arg_type, subtype_t arg_subtype)
|
Tag::Tag(type_t arg_type, subtype_t arg_subtype)
|
||||||
{
|
{
|
||||||
assert(arg_type > 0);
|
assert(arg_type > 0);
|
||||||
|
|
||||||
type = arg_type;
|
type = arg_type;
|
||||||
subtype = arg_subtype;
|
subtype = arg_subtype;
|
||||||
int64_t i = (int64)(type) | ((int64)subtype << 31);
|
int64_t i = (int64)(type) | ((int64)subtype << 31);
|
||||||
|
@ -23,6 +22,7 @@ Tag::Tag(type_t arg_type, subtype_t arg_subtype)
|
||||||
Tag::Tag(EnumVal* arg_val)
|
Tag::Tag(EnumVal* arg_val)
|
||||||
{
|
{
|
||||||
assert(val);
|
assert(val);
|
||||||
|
|
||||||
val = arg_val;
|
val = arg_val;
|
||||||
Ref(val);
|
Ref(val);
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ Tag::Tag()
|
||||||
val = 0;
|
val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumVal* Tag::Val()
|
EnumVal* Tag::AsEnumVal() const
|
||||||
{
|
{
|
||||||
if ( ! val )
|
if ( ! val )
|
||||||
{
|
{
|
||||||
|
@ -66,4 +66,3 @@ std::string Tag::AsString() const
|
||||||
{
|
{
|
||||||
return fmt("%" PRIu32 "/%" PRIu32, type, subtype);
|
return fmt("%" PRIu32 "/%" PRIu32, type, subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,6 @@
|
||||||
#ifndef ANALYZER_TAG_H
|
#ifndef ANALYZER_TAG_H
|
||||||
#define ANALYZER_TAG_H
|
#define ANALYZER_TAG_H
|
||||||
|
|
||||||
// Each kind of analyzer gets a tag consisting of a main type and subtype.
|
|
||||||
// The former is an identifier that's unique all analyzer classes. The latter
|
|
||||||
// is passed through analyzer instances, yet not further interpreted by the
|
|
||||||
// analyzer infrastructure; it allows an analyzer to branch out into a set of
|
|
||||||
// sub-analyzers internally. Jointly, main type and subtype form an analyzer
|
|
||||||
// "tag". Each unique tag corresponds to a single "analyzer" from the user's
|
|
||||||
// perspective.
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -17,41 +9,129 @@ class EnumVal;
|
||||||
|
|
||||||
namespace analyzer {
|
namespace analyzer {
|
||||||
|
|
||||||
/// This has supports all operations to be used as a map index.
|
class Manager;
|
||||||
|
class Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to identify an analyzdr type.
|
||||||
|
*
|
||||||
|
* Each analyzer type gets a tag consisting of a main type and subtype. The
|
||||||
|
* former is an identifier that's unique all analyzer classes. The latter is
|
||||||
|
* passed through to the analyzer instances for their use, yet not further
|
||||||
|
* interpreted by the analyzer infrastructure; it allows an analyzer to
|
||||||
|
* branch out into a set of sub-analyzers internally. Jointly, main type and
|
||||||
|
* subtype form an analyzer "tag". Each unique tag corresponds to a single
|
||||||
|
* "analyzer" from the user's perspective. At the script layer, these tags
|
||||||
|
* are mapped into enums of type \c Analyzer::Tag. Internally, the
|
||||||
|
* analyzer::Mangager maintains the mapping of tag to analyzer (and it also
|
||||||
|
* assigns them their main types), and analyzer::Component creates new
|
||||||
|
* tags.
|
||||||
|
*
|
||||||
|
* The Tag class supports all operations necessary to act at the index in a
|
||||||
|
* \c std::map.
|
||||||
|
*/
|
||||||
class Tag {
|
class Tag {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Type for the analyzer's main type.
|
||||||
|
*/
|
||||||
typedef uint32 type_t;
|
typedef uint32 type_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type for the analyzer's subtype.
|
||||||
|
*/
|
||||||
typedef uint32 subtype_t;
|
typedef uint32 subtype_t;
|
||||||
|
|
||||||
Tag(type_t type, subtype_t subtype = 0);
|
/*
|
||||||
Tag(EnumVal* val);
|
* Copy constructor.
|
||||||
|
*/
|
||||||
Tag(const Tag& other);
|
Tag(const Tag& other);
|
||||||
Tag(); // Tag::ERROR value
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. This initializes the tag with an error value
|
||||||
|
* that will make \c operator \c bool return false.
|
||||||
|
*/
|
||||||
|
Tag();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tag's main type.
|
||||||
|
*/
|
||||||
type_t Type() const { return type; }
|
type_t Type() const { return type; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tag's subtype.
|
||||||
|
*/
|
||||||
subtype_t Subtype() const { return subtype; }
|
subtype_t Subtype() const { return subtype; }
|
||||||
|
|
||||||
// Returns an identifying integer for this tag that's guaranteed to
|
/**
|
||||||
// be unique across all tags.
|
* Returns the \c Analyzer::Tag enum that corresponds to this tag.
|
||||||
EnumVal* Val();
|
* The returned value is \a does not have its ref-count increased.
|
||||||
|
*/
|
||||||
|
EnumVal* AsEnumVal() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the numerical values for main and subtype inside a string
|
||||||
|
* suitable for printing. This is primarily for debugging.
|
||||||
|
*/
|
||||||
std::string AsString() const;
|
std::string AsString() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns false if the tag represents an error value rather than a
|
||||||
|
* legal analyzer type.
|
||||||
|
*/
|
||||||
operator bool() const { return *this != Tag(); }
|
operator bool() const { return *this != Tag(); }
|
||||||
bool operator==(const Tag& other) const { return type == other.type && subtype == other.subtype; }
|
|
||||||
bool operator!=(const Tag& other) const { return type != other.type || subtype != other.subtype; }
|
/**
|
||||||
|
* Compares two tags for equality.
|
||||||
|
*/
|
||||||
|
bool operator==(const Tag& other) const
|
||||||
|
{
|
||||||
|
return type == other.type && subtype == other.subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two tags for inequality.
|
||||||
|
*/
|
||||||
|
bool operator!=(const Tag& other) const
|
||||||
|
{
|
||||||
|
return type != other.type || subtype != other.subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two tags for less-than relationship.
|
||||||
|
*/
|
||||||
bool operator<(const Tag& other) const
|
bool operator<(const Tag& other) const
|
||||||
{
|
{
|
||||||
return type != other.type ? type < other.type : (subtype < other.subtype);
|
return type != other.type ? type < other.type : (subtype < other.subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class analyzer::Manager;
|
||||||
|
friend class analyzer::Component;
|
||||||
|
|
||||||
static Tag ERROR;
|
/**
|
||||||
|
* Constructor. Note
|
||||||
|
*
|
||||||
|
* @param type The main type. Note that the \a analyzer::Manager
|
||||||
|
* manages the value space internally, so noone else should assign
|
||||||
|
* any main tyoes.
|
||||||
|
*
|
||||||
|
* @param subtype The sub type, which is left to an analyzer for
|
||||||
|
* interpretation. By default it's set to zero.
|
||||||
|
*/
|
||||||
|
Tag(type_t type, subtype_t subtype = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param val An enuam value of script type \c Analyzer::Tag.
|
||||||
|
*/
|
||||||
|
Tag(EnumVal* val);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
type_t type;
|
type_t type; // Main type.
|
||||||
subtype_t subtype;
|
subtype_t subtype; // Subtype.
|
||||||
EnumVal* val;
|
mutable EnumVal* val; // Analyzer::Tag value.
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_reused
|
## connection_pending connection_rejected connection_reset connection_reused
|
||||||
## connection_state_remove connection_status_update connection_timeout
|
## connection_state_remove connection_status_update connection_timeout
|
||||||
## expected_connection_seen new_connection_contents partial_connection
|
## scheduled_analyzer_applied new_connection_contents partial_connection
|
||||||
##
|
##
|
||||||
## .. note::
|
## .. note::
|
||||||
##
|
##
|
||||||
|
@ -168,7 +168,7 @@ event tunnel_changed%(c: connection, e: EncapsulatingConnVector%);
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_reused
|
## connection_pending connection_rejected connection_reset connection_reused
|
||||||
## connection_state_remove connection_status_update connection_timeout
|
## connection_state_remove connection_status_update connection_timeout
|
||||||
## expected_connection_seen new_connection partial_connection
|
## scheduled_analyzer_applied new_connection partial_connection
|
||||||
event new_connection_contents%(c: connection%);
|
event new_connection_contents%(c: connection%);
|
||||||
|
|
||||||
## Generated for an unsuccessful connection attempt. This event is raised when
|
## Generated for an unsuccessful connection attempt. This event is raised when
|
||||||
|
@ -183,7 +183,7 @@ event new_connection_contents%(c: connection%);
|
||||||
## connection_external connection_finished connection_first_ACK
|
## connection_external connection_finished connection_first_ACK
|
||||||
## connection_half_finished connection_partial_close connection_pending
|
## connection_half_finished connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_attempt%(c: connection%);
|
event connection_attempt%(c: connection%);
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ event connection_attempt%(c: connection%);
|
||||||
## connection_external connection_finished connection_first_ACK
|
## connection_external connection_finished connection_first_ACK
|
||||||
## connection_half_finished connection_partial_close connection_pending
|
## connection_half_finished connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_established%(c: connection%);
|
event connection_established%(c: connection%);
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ event connection_established%(c: connection%);
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_reused
|
## connection_pending connection_rejected connection_reset connection_reused
|
||||||
## connection_state_remove connection_status_update connection_timeout
|
## connection_state_remove connection_status_update connection_timeout
|
||||||
## expected_connection_seen new_connection new_connection_contents
|
## scheduled_analyzer_applied new_connection new_connection_contents
|
||||||
##
|
##
|
||||||
event partial_connection%(c: connection%);
|
event partial_connection%(c: connection%);
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ event partial_connection%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_pending
|
## connection_first_ACK connection_half_finished connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_partial_close%(c: connection%);
|
event connection_partial_close%(c: connection%);
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ event connection_partial_close%(c: connection%);
|
||||||
## connection_established connection_external connection_first_ACK
|
## connection_established connection_external connection_first_ACK
|
||||||
## connection_half_finished connection_partial_close connection_pending
|
## connection_half_finished connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_finished%(c: connection%);
|
event connection_finished%(c: connection%);
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ event connection_finished%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_partial_close connection_pending
|
## connection_first_ACK connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_half_finished%(c: connection%);
|
event connection_half_finished%(c: connection%);
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ event connection_half_finished%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_reset connection_reused connection_state_remove
|
## connection_pending connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
##
|
##
|
||||||
## c: The connection.
|
## c: The connection.
|
||||||
|
@ -294,7 +294,7 @@ event connection_rejected%(c: connection%);
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reused
|
## connection_pending connection_rejected connection_reused
|
||||||
## connection_state_remove connection_status_update connection_timeout
|
## connection_state_remove connection_status_update connection_timeout
|
||||||
## expected_connection_seen new_connection new_connection_contents
|
## scheduled_analyzer_applied new_connection new_connection_contents
|
||||||
## partial_connection
|
## partial_connection
|
||||||
event connection_reset%(c: connection%);
|
event connection_reset%(c: connection%);
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ event connection_reset%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection bro_done
|
## new_connection new_connection_contents partial_connection bro_done
|
||||||
event connection_pending%(c: connection%);
|
event connection_pending%(c: connection%);
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ event connection_pending%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_reused
|
## connection_pending connection_rejected connection_reset connection_reused
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection udp_inactivity_timeout
|
## new_connection new_connection_contents partial_connection udp_inactivity_timeout
|
||||||
## tcp_inactivity_timeout icmp_inactivity_timeout conn_stats
|
## tcp_inactivity_timeout icmp_inactivity_timeout conn_stats
|
||||||
event connection_state_remove%(c: connection%);
|
event connection_state_remove%(c: connection%);
|
||||||
|
@ -339,7 +339,7 @@ event connection_state_remove%(c: connection%);
|
||||||
## connection_external connection_finished connection_first_ACK
|
## connection_external connection_finished connection_first_ACK
|
||||||
## connection_half_finished connection_partial_close connection_pending
|
## connection_half_finished connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
##
|
##
|
||||||
## .. note::
|
## .. note::
|
||||||
|
@ -360,7 +360,7 @@ event connection_SYN_packet%(c: connection, pkt: SYN_packet%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_half_finished connection_partial_close connection_pending
|
## connection_half_finished connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
##
|
##
|
||||||
## .. note::
|
## .. note::
|
||||||
|
@ -379,7 +379,7 @@ event connection_first_ACK%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_reused
|
## connection_pending connection_rejected connection_reset connection_reused
|
||||||
## connection_state_remove connection_status_update expected_connection_seen
|
## connection_state_remove connection_status_update scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
##
|
##
|
||||||
## .. note::
|
## .. note::
|
||||||
|
@ -402,7 +402,7 @@ event connection_timeout%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_state_remove
|
## connection_pending connection_rejected connection_reset connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_reused%(c: connection%);
|
event connection_reused%(c: connection%);
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ event connection_reused%(c: connection%);
|
||||||
## connection_established connection_external connection_finished
|
## connection_established connection_external connection_finished
|
||||||
## connection_first_ACK connection_half_finished connection_partial_close
|
## connection_first_ACK connection_half_finished connection_partial_close
|
||||||
## connection_pending connection_rejected connection_reset connection_reused
|
## connection_pending connection_rejected connection_reset connection_reused
|
||||||
## connection_state_remove connection_timeout expected_connection_seen
|
## connection_state_remove connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_status_update%(c: connection%);
|
event connection_status_update%(c: connection%);
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ event connection_flow_label_changed%(c: connection, is_orig: bool, old_label: co
|
||||||
## connection_external connection_finished connection_first_ACK
|
## connection_external connection_finished connection_first_ACK
|
||||||
## connection_half_finished connection_partial_close connection_pending
|
## connection_half_finished connection_partial_close connection_pending
|
||||||
## connection_rejected connection_reset connection_reused connection_state_remove
|
## connection_rejected connection_reset connection_reused connection_state_remove
|
||||||
## connection_status_update connection_timeout expected_connection_seen
|
## connection_status_update connection_timeout scheduled_analyzer_applied
|
||||||
## new_connection new_connection_contents partial_connection
|
## new_connection new_connection_contents partial_connection
|
||||||
event connection_EOF%(c: connection, is_orig: bool%);
|
event connection_EOF%(c: connection, is_orig: bool%);
|
||||||
|
|
||||||
|
@ -481,7 +481,7 @@ event connection_external%(c: connection, tag: string%);
|
||||||
##
|
##
|
||||||
## .. todo:: We don't have a good way to document the automatically generated
|
## .. todo:: We don't have a good way to document the automatically generated
|
||||||
## ``ANALYZER_*`` constants right now.
|
## ``ANALYZER_*`` constants right now.
|
||||||
event expected_connection_seen%(c: connection, a: count%);
|
event scheduled_analyzer_applied%(c: connection, a: Analyzer::Tag%);
|
||||||
|
|
||||||
## Generated for every packet Bro sees. This is a very low-level and expensive
|
## Generated for every packet Bro sees. This is a very low-level and expensive
|
||||||
## event that should be avoided when at all possible. It's usually infeasible to
|
## event that should be avoided when at all possible. It's usually infeasible to
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#ifndef PLUGIN_MACROS_H
|
#ifndef PLUGIN_MACROS_H
|
||||||
#define PLUGIN_MACROS_H
|
#define PLUGIN_MACROS_H
|
||||||
|
|
||||||
#include "analyzer/PluginComponent.h"
|
#include "analyzer/Component.h"
|
||||||
|
|
||||||
#define BRO_PLUGIN_VERSION_BUILTIN -1
|
#define BRO_PLUGIN_VERSION_BUILTIN -1
|
||||||
#define BRO_PLUGIN_API_VERSION 1
|
#define BRO_PLUGIN_API_VERSION 1
|
||||||
|
@ -36,7 +36,10 @@
|
||||||
std::list<std::pair<std::string, int> > __bif_##file##_init(); \
|
std::list<std::pair<std::string, int> > __bif_##file##_init(); \
|
||||||
AddBifInitFunction(&__bif_##file##_init);
|
AddBifInitFunction(&__bif_##file##_init);
|
||||||
|
|
||||||
#define BRO_PLUGIN_ANALYZER(tag, factory, enabled, partial) \
|
#define BRO_PLUGIN_ANALYZER(tag, factory) \
|
||||||
AddComponent(new ::analyzer::PluginComponent(tag, factory, enabled, partial));
|
AddComponent(new ::analyzer::Component(tag, factory));
|
||||||
|
|
||||||
|
#define BRO_PLUGIN_ANALYZER_EXT(tag, factory, enabled, partial) \
|
||||||
|
AddComponent(new ::analyzer::Component(tag, factory, 0, enabled, partial));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// analyzers into separate plugins.
|
// analyzers into separate plugins.
|
||||||
|
|
||||||
#include "BuiltInAnalyzers.h"
|
#include "BuiltInAnalyzers.h"
|
||||||
#include "analyzer/PluginComponent.h"
|
#include "analyzer/Component.h"
|
||||||
|
|
||||||
#include "../binpac_bro.h"
|
#include "../binpac_bro.h"
|
||||||
|
|
||||||
|
@ -47,8 +47,13 @@ using namespace analyzer;
|
||||||
|
|
||||||
BuiltinAnalyzers builtin_analyzers;
|
BuiltinAnalyzers builtin_analyzers;
|
||||||
|
|
||||||
#define DEFINE_ANALYZER(name, factory, enabled, partial) \
|
#define DEFINE_ANALYZER(name, factory) \
|
||||||
AddComponent(new PluginComponent(name, factory, enabled, partial))
|
AddComponent(new Component(name, factory))
|
||||||
|
|
||||||
|
#define DEFINE_ANALYZER_VERSION_BINPAC(name, factory) \
|
||||||
|
AddComponent(new Component(name, factory, 0, FLAGS_use_binpac))
|
||||||
|
#define DEFINE_ANALYZER_VERSION_NON_BINPAC(name, factory) \
|
||||||
|
AddComponent(new Component(name, factory, 0, ! FLAGS_use_binpac))
|
||||||
|
|
||||||
void BuiltinAnalyzers::Init()
|
void BuiltinAnalyzers::Init()
|
||||||
{
|
{
|
||||||
|
@ -58,72 +63,69 @@ void BuiltinAnalyzers::Init()
|
||||||
desc.version = BRO_PLUGIN_VERSION_BUILTIN;
|
desc.version = BRO_PLUGIN_VERSION_BUILTIN;
|
||||||
SetDescription(desc);
|
SetDescription(desc);
|
||||||
|
|
||||||
DEFINE_ANALYZER("PIA_TCP", PIA_TCP::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("PIA_TCP", PIA_TCP::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("PIA_UDP", PIA_UDP::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("PIA_UDP", PIA_UDP::InstantiateAnalyzer);
|
||||||
|
|
||||||
DEFINE_ANALYZER("ICMP", ICMP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("ICMP", ICMP_Analyzer::InstantiateAnalyzer);
|
||||||
|
|
||||||
DEFINE_ANALYZER("TCP", TCP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("TCP", TCP_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("UDP", UDP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("UDP", UDP_Analyzer::InstantiateAnalyzer);
|
||||||
|
|
||||||
DEFINE_ANALYZER("BITTORRENT", BitTorrent_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("BITTORRENT", BitTorrent_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("BITTORRENTTRACKER", BitTorrentTracker_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("BITTORRENTTRACKER", BitTorrentTracker_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("DCE_RPC", DCE_RPC_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("DCE_RPC", DCE_RPC_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("DNS", DNS_Analyzer::InstantiateAnalyzer, ! FLAGS_use_binpac, false);
|
DEFINE_ANALYZER_VERSION_NON_BINPAC("DNS", DNS_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("FINGER", Finger_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("FINGER", Finger_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("FTP", FTP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("FTP", FTP_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("GNUTELLA", Gnutella_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("GNUTELLA", Gnutella_Analyzer::InstantiateAnalyzer);
|
||||||
// DEFINE_ANALYZER("HTTP", HTTP_Analyzer::InstantiateAnalyzer, ! FLAGS_use_binpac, false);
|
DEFINE_ANALYZER("IDENT", Ident_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("IDENT", Ident_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("IRC", IRC_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("IRC", IRC_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("LOGIN", 0); // just a base class
|
||||||
DEFINE_ANALYZER("LOGIN", 0, true, false); // just a base class
|
DEFINE_ANALYZER("NCP", NCP_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("NCP", NCP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("NETBIOSSSN", NetbiosSSN_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("NETBIOSSSN", NetbiosSSN_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("NFS", NFS_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("NFS", NFS_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("NTP", NTP_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("NTP", NTP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("POP3", POP3_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("POP3", POP3_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("PORTMAPPER", Portmapper_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("PORTMAPPER", Portmapper_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("RPC", 0);
|
||||||
DEFINE_ANALYZER("RPC", 0, true, false);
|
DEFINE_ANALYZER("RSH", Rsh_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("RSH", Rsh_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("SMB", SMB_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("SMB", SMB_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("SMTP", SMTP_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("SMTP", SMTP_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("SSH", SSH_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("SSH", SSH_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("TELNET", Telnet_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("TELNET", Telnet_Analyzer::InstantiateAnalyzer, true, false);
|
|
||||||
|
|
||||||
DEFINE_ANALYZER("DHCP_BINPAC", DHCP_Analyzer_binpac::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("DHCP_BINPAC", DHCP_Analyzer_binpac::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("DNS_TCP_BINPAC", DNS_TCP_Analyzer_binpac::InstantiateAnalyzer, FLAGS_use_binpac, false);
|
DEFINE_ANALYZER_VERSION_BINPAC("DNS_TCP_BINPAC", DNS_TCP_Analyzer_binpac::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("DNS_UDP_BINPAC", DNS_UDP_Analyzer_binpac::InstantiateAnalyzer, FLAGS_use_binpac, false);
|
DEFINE_ANALYZER_VERSION_BINPAC("DNS_UDP_BINPAC", DNS_UDP_Analyzer_binpac::InstantiateAnalyzer);
|
||||||
// DEFINE_ANALYZER("HTTP_BINPAC", HTTP_Analyzer_binpac::InstantiateAnalyzer, FLAGS_use_binpac, false);
|
DEFINE_ANALYZER("SYSLOG_BINPAC", Syslog_Analyzer_binpac::InstantiateAnalyzer);
|
||||||
// DEFINE_ANALYZER("SSL", SSL_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("MODBUS", ModbusTCP_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("SYSLOG_BINPAC", Syslog_Analyzer_binpac::InstantiateAnalyzer, true, false);
|
|
||||||
DEFINE_ANALYZER("MODBUS", ModbusTCP_Analyzer::InstantiateAnalyzer, true, false);
|
|
||||||
|
|
||||||
DEFINE_ANALYZER("AYIYA", AYIYA_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("AYIYA", AYIYA_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("SOCKS", SOCKS_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("SOCKS", SOCKS_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("TEREDO", Teredo_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("TEREDO", Teredo_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("GTPV1", GTPv1_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("GTPV1", GTPv1_Analyzer::InstantiateAnalyzer);
|
||||||
|
|
||||||
DEFINE_ANALYZER("FILE", File_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("FILE", File_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("BACKDOOR", BackDoor_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("BACKDOOR", BackDoor_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("INTERCONN", InterConn_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("INTERCONN", InterConn_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("STEPPINGSTONE", SteppingStone_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("STEPPINGSTONE", SteppingStone_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("TCPSTATS", TCPStats_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("TCPSTATS", TCPStats_Analyzer::InstantiateAnalyzer);
|
||||||
DEFINE_ANALYZER("CONNSIZE", ConnSize_Analyzer::InstantiateAnalyzer, true, false);
|
DEFINE_ANALYZER("CONNSIZE", ConnSize_Analyzer::InstantiateAnalyzer);
|
||||||
|
|
||||||
DEFINE_ANALYZER("CONTENTS", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS", 0);
|
||||||
DEFINE_ANALYZER("CONTENTLINE", 0, true, false);
|
DEFINE_ANALYZER("CONTENTLINE", 0);
|
||||||
DEFINE_ANALYZER("NVT", 0, true, false);
|
DEFINE_ANALYZER("NVT", 0);
|
||||||
DEFINE_ANALYZER("ZIP", 0, true, false);
|
DEFINE_ANALYZER("ZIP", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_DNS", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_DNS", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_NETBIOSSSN", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_NETBIOSSSN", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_NCP", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_NCP", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_RLOGIN", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_RLOGIN", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_RSH", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_RSH", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_DCE_RPC", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_DCE_RPC", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_SMB", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_SMB", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_RPC", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_RPC", 0);
|
||||||
DEFINE_ANALYZER("CONTENTS_NFS", 0, true, false);
|
DEFINE_ANALYZER("CONTENTS_NFS", 0);
|
||||||
DEFINE_ANALYZER("FTP_ADAT", 0, true, false);
|
DEFINE_ANALYZER("FTP_ADAT", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
BRO_PLUGIN_BEGIN(HTTP)
|
BRO_PLUGIN_BEGIN(HTTP)
|
||||||
BRO_PLUGIN_DESCRIPTION = "HTTP Analyzer";
|
BRO_PLUGIN_DESCRIPTION = "HTTP Analyzer";
|
||||||
BRO_PLUGIN_ANALYZER("HTTP", HTTP_Analyzer::InstantiateAnalyzer, true, false);
|
BRO_PLUGIN_ANALYZER("HTTP", HTTP_Analyzer::InstantiateAnalyzer);
|
||||||
BRO_PLUGIN_BIF_FILE(events);
|
BRO_PLUGIN_BIF_FILE(events);
|
||||||
BRO_PLUGIN_BIF_FILE(functions);
|
BRO_PLUGIN_BIF_FILE(functions);
|
||||||
BRO_PLUGIN_END
|
BRO_PLUGIN_END
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
|
|
||||||
BRO_PLUGIN_BEGIN(SSL)
|
BRO_PLUGIN_BEGIN(SSL)
|
||||||
BRO_PLUGIN_DESCRIPTION = "SSL Analyzer";
|
BRO_PLUGIN_DESCRIPTION = "SSL Analyzer";
|
||||||
BRO_PLUGIN_ANALYZER("SSL", SSL_Analyzer::InstantiateAnalyzer, true, false);
|
BRO_PLUGIN_ANALYZER("SSL", SSL_Analyzer::InstantiateAnalyzer);
|
||||||
BRO_PLUGIN_BIF_FILE(events);
|
BRO_PLUGIN_BIF_FILE(events);
|
||||||
BRO_PLUGIN_END
|
BRO_PLUGIN_END
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path loaded_scripts
|
#path loaded_scripts
|
||||||
#open 2013-03-26-20-58-03
|
#open 2013-04-01-19-44-31
|
||||||
#fields name
|
#fields name
|
||||||
#types string
|
#types string
|
||||||
scripts/base/init-bare.bro
|
scripts/base/init-bare.bro
|
||||||
build/src/base/const.bif.bro
|
build/scripts/base/bif/const.bif.bro
|
||||||
build/src/base/types.bif.bro
|
build/scripts/base/bif/types.bif.bro
|
||||||
build/src/base/strings.bif.bro
|
build/scripts/base/bif/strings.bif.bro
|
||||||
build/src/base/bro.bif.bro
|
build/scripts/base/bif/bro.bif.bro
|
||||||
build/src/base/reporter.bif.bro
|
build/scripts/base/bif/reporter.bif.bro
|
||||||
build/src/base/event.bif.bro
|
build/scripts/base/bif/event.bif.bro
|
||||||
scripts/base/frameworks/logging/__load__.bro
|
scripts/base/frameworks/logging/__load__.bro
|
||||||
scripts/base/frameworks/logging/./main.bro
|
scripts/base/frameworks/logging/./main.bro
|
||||||
build/src/base/logging.bif.bro
|
build/scripts/base/bif/logging.bif.bro
|
||||||
scripts/base/frameworks/logging/./postprocessors/__load__.bro
|
scripts/base/frameworks/logging/./postprocessors/__load__.bro
|
||||||
scripts/base/frameworks/logging/./postprocessors/./scp.bro
|
scripts/base/frameworks/logging/./postprocessors/./scp.bro
|
||||||
scripts/base/frameworks/logging/./postprocessors/./sftp.bro
|
scripts/base/frameworks/logging/./postprocessors/./sftp.bro
|
||||||
|
@ -25,12 +25,16 @@ scripts/base/init-bare.bro
|
||||||
scripts/base/frameworks/logging/./writers/none.bro
|
scripts/base/frameworks/logging/./writers/none.bro
|
||||||
scripts/base/frameworks/input/__load__.bro
|
scripts/base/frameworks/input/__load__.bro
|
||||||
scripts/base/frameworks/input/./main.bro
|
scripts/base/frameworks/input/./main.bro
|
||||||
build/src/base/input.bif.bro
|
build/scripts/base/bif/input.bif.bro
|
||||||
scripts/base/frameworks/input/./readers/ascii.bro
|
scripts/base/frameworks/input/./readers/ascii.bro
|
||||||
scripts/base/frameworks/input/./readers/raw.bro
|
scripts/base/frameworks/input/./readers/raw.bro
|
||||||
scripts/base/frameworks/input/./readers/benchmark.bro
|
scripts/base/frameworks/input/./readers/benchmark.bro
|
||||||
scripts/base/frameworks/analyzer/__load__.bro
|
scripts/base/frameworks/analyzer/__load__.bro
|
||||||
scripts/base/frameworks/analyzer/./main.bro
|
scripts/base/frameworks/analyzer/./main.bro
|
||||||
build/src/base/analyzer.bif.bro
|
build/scripts/base/bif/analyzer.bif.bro
|
||||||
|
build/scripts/base/bif/plugins/__load__.bro
|
||||||
|
build/scripts/base/bif/plugins/./HTTP.events.bif.bro
|
||||||
|
build/scripts/base/bif/plugins/./HTTP.functions.bif.bro
|
||||||
|
build/scripts/base/bif/plugins/./SSL.events.bif.bro
|
||||||
scripts/policy/misc/loaded-scripts.bro
|
scripts/policy/misc/loaded-scripts.bro
|
||||||
#close 2013-03-26-20-58-03
|
#close 2013-04-01-19-44-31
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path loaded_scripts
|
#path loaded_scripts
|
||||||
#open 2013-03-26-20-58-16
|
#open 2013-04-01-19-44-38
|
||||||
#fields name
|
#fields name
|
||||||
#types string
|
#types string
|
||||||
scripts/base/init-bare.bro
|
scripts/base/init-bare.bro
|
||||||
build/src/base/const.bif.bro
|
build/scripts/base/bif/const.bif.bro
|
||||||
build/src/base/types.bif.bro
|
build/scripts/base/bif/types.bif.bro
|
||||||
build/src/base/strings.bif.bro
|
build/scripts/base/bif/strings.bif.bro
|
||||||
build/src/base/bro.bif.bro
|
build/scripts/base/bif/bro.bif.bro
|
||||||
build/src/base/reporter.bif.bro
|
build/scripts/base/bif/reporter.bif.bro
|
||||||
build/src/base/event.bif.bro
|
build/scripts/base/bif/event.bif.bro
|
||||||
scripts/base/frameworks/logging/__load__.bro
|
scripts/base/frameworks/logging/__load__.bro
|
||||||
scripts/base/frameworks/logging/./main.bro
|
scripts/base/frameworks/logging/./main.bro
|
||||||
build/src/base/logging.bif.bro
|
build/scripts/base/bif/logging.bif.bro
|
||||||
scripts/base/frameworks/logging/./postprocessors/__load__.bro
|
scripts/base/frameworks/logging/./postprocessors/__load__.bro
|
||||||
scripts/base/frameworks/logging/./postprocessors/./scp.bro
|
scripts/base/frameworks/logging/./postprocessors/./scp.bro
|
||||||
scripts/base/frameworks/logging/./postprocessors/./sftp.bro
|
scripts/base/frameworks/logging/./postprocessors/./sftp.bro
|
||||||
|
@ -25,13 +25,17 @@ scripts/base/init-bare.bro
|
||||||
scripts/base/frameworks/logging/./writers/none.bro
|
scripts/base/frameworks/logging/./writers/none.bro
|
||||||
scripts/base/frameworks/input/__load__.bro
|
scripts/base/frameworks/input/__load__.bro
|
||||||
scripts/base/frameworks/input/./main.bro
|
scripts/base/frameworks/input/./main.bro
|
||||||
build/src/base/input.bif.bro
|
build/scripts/base/bif/input.bif.bro
|
||||||
scripts/base/frameworks/input/./readers/ascii.bro
|
scripts/base/frameworks/input/./readers/ascii.bro
|
||||||
scripts/base/frameworks/input/./readers/raw.bro
|
scripts/base/frameworks/input/./readers/raw.bro
|
||||||
scripts/base/frameworks/input/./readers/benchmark.bro
|
scripts/base/frameworks/input/./readers/benchmark.bro
|
||||||
scripts/base/frameworks/analyzer/__load__.bro
|
scripts/base/frameworks/analyzer/__load__.bro
|
||||||
scripts/base/frameworks/analyzer/./main.bro
|
scripts/base/frameworks/analyzer/./main.bro
|
||||||
build/src/base/analyzer.bif.bro
|
build/scripts/base/bif/analyzer.bif.bro
|
||||||
|
build/scripts/base/bif/plugins/__load__.bro
|
||||||
|
build/scripts/base/bif/plugins/./HTTP.events.bif.bro
|
||||||
|
build/scripts/base/bif/plugins/./HTTP.functions.bif.bro
|
||||||
|
build/scripts/base/bif/plugins/./SSL.events.bif.bro
|
||||||
scripts/base/init-default.bro
|
scripts/base/init-default.bro
|
||||||
scripts/base/utils/site.bro
|
scripts/base/utils/site.bro
|
||||||
scripts/base/utils/./patterns.bro
|
scripts/base/utils/./patterns.bro
|
||||||
|
@ -122,4 +126,4 @@ scripts/base/init-default.bro
|
||||||
scripts/base/protocols/syslog/./main.bro
|
scripts/base/protocols/syslog/./main.bro
|
||||||
scripts/base/misc/find-checksum-offloading.bro
|
scripts/base/misc/find-checksum-offloading.bro
|
||||||
scripts/policy/misc/loaded-scripts.bro
|
scripts/policy/misc/loaded-scripts.bro
|
||||||
#close 2013-03-26-20-58-16
|
#close 2013-04-01-19-44-38
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_DNS
|
||||||
|
APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_FTP
|
||||||
|
APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_SSH
|
||||||
|
APPLIED:, 1299491995.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=6/tcp], Analyzer::ANALYZER_HTTP
|
||||||
|
APPLIED:, 1299499195.0, [orig_h=10.0.0.2, orig_p=20/tcp, resp_h=10.0.0.3, resp_p=8/tcp], Analyzer::ANALYZER_DNS
|
|
@ -0,0 +1,36 @@
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: bro -b -r ${TRACES}/rotation.trace %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
global x = 0;
|
||||||
|
|
||||||
|
event new_connection(c: connection)
|
||||||
|
{
|
||||||
|
# Make sure expiration executes.
|
||||||
|
Analyzer::schedule_analyzer(1.2.3.4, 1.2.3.4, 8/tcp, Analyzer::ANALYZER_MODBUS, 100hrs);
|
||||||
|
|
||||||
|
if ( x > 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
x = 1;
|
||||||
|
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_SSH, 100hrs);
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_HTTP, 100hrs);
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_DNS, 100hrs);
|
||||||
|
Analyzer::schedule_analyzer(0.0.0.0, 10.0.0.3, 6/tcp, Analyzer::ANALYZER_FTP, 100hrs);
|
||||||
|
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 7/tcp, Analyzer::ANALYZER_SSH, 1sec);
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 8/tcp, Analyzer::ANALYZER_HTTP, 1sec);
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 8/tcp, Analyzer::ANALYZER_DNS, 100hrs);
|
||||||
|
Analyzer::schedule_analyzer(10.0.0.2, 10.0.0.3, 9/tcp, Analyzer::ANALYZER_FTP, 1sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag)
|
||||||
|
{
|
||||||
|
print "APPLIED:", network_time(), c$id, a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue