diff --git a/doc/scripts/DocSourcesList.cmake b/doc/scripts/DocSourcesList.cmake index af8f2de94b..c71d7798ea 100644 --- a/doc/scripts/DocSourcesList.cmake +++ b/doc/scripts/DocSourcesList.cmake @@ -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/input.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/strings.bif.bro) rest_target(${CMAKE_BINARY_DIR}/src base/types.bif.bro) diff --git a/scripts/base/frameworks/analyzer/main.bro b/scripts/base/frameworks/analyzer/main.bro index ea5ccb727c..dcadb402fb 100644 --- a/scripts/base/frameworks/analyzer/main.bro +++ b/scripts/base/frameworks/analyzer/main.bro @@ -45,7 +45,7 @@ export { ## tout: The timeout interval after which to ignore the scheduling request. ## ## 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; ## Analyzers to disable at startup. @@ -119,9 +119,9 @@ function name(atype: Analyzer::Tag) : string 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 { - return __expect_connection(orig, resp, resp_p, analyzer, tout); + return __schedule_analyzer(orig, resp, resp_p, analyzer, tout); } diff --git a/scripts/base/protocols/ftp/main.bro b/scripts/base/protocols/ftp/main.bro index e2b77e0099..868fa99bef 100644 --- a/scripts/base/protocols/ftp/main.bro +++ b/scripts/base/protocols/ftp/main.bro @@ -228,7 +228,7 @@ event ftp_request(c: connection, command: string, arg: string) &priority=5 { c$ftp$passive=F; 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 { @@ -281,7 +281,7 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior data$h = id$resp_h; 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 { @@ -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; if ( [id$resp_h, id$resp_p] in ftp_data_expected ) diff --git a/scripts/base/protocols/irc/dcc-send.bro b/scripts/base/protocols/irc/dcc-send.bro index 621ad42826..45746aae2b 100644 --- a/scripts/base/protocols/irc/dcc-send.bro +++ b/scripts/base/protocols/irc/dcc-send.bro @@ -104,7 +104,7 @@ event irc_dcc_message(c: connection, is_orig: bool, c$irc$dcc_file_name = argument; c$irc$dcc_file_size = size; 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; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31192a8757..5109f71105 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -400,7 +400,7 @@ set(bro_SRCS analyzer/Analyzer.cc analyzer/Manager.cc - analyzer/PluginComponent.cc + analyzer/Component.cc analyzer/Tag.cc protocols/BuiltInAnalyzers.cc diff --git a/src/DCE_RPC.cc b/src/DCE_RPC.cc index 0cb9ab3c3f..f01edc9c8a 100644 --- a/src/DCE_RPC.cc +++ b/src/DCE_RPC.cc @@ -161,8 +161,8 @@ static void add_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr, // of the dce_rpc_endpoints table. // FIXME: Don't hard-code the timeout. - analyzer_mgr->ExpectConnection(IPAddr(), addr.addr, addr.port, addr.proto, - "DCE_RPC", 5 * 60, 0); + analyzer_mgr->ScheduleAnalyzer(IPAddr(), addr.addr, addr.port, addr.proto, + "DCE_RPC", 5 * 60); } DCE_RPC_Header::DCE_RPC_Header(analyzer::Analyzer* a, const u_char* b) diff --git a/src/DebugLogger.h b/src/DebugLogger.h index ca422072c5..74eea4520d 100644 --- a/src/DebugLogger.h +++ b/src/DebugLogger.h @@ -21,7 +21,7 @@ enum DebugStream { DBG_STRING, // String code DBG_NOTIFIERS, // Notifiers (see StateAccess.h) DBG_MAINLOOP, // Main IOSource loop - DBG_DPD, // Dynamic application detection framework + DBG_ANALYZER, // Analyzer framework DBG_TM, // Time-machine packet input via Brocolli DBG_LOGGING, // Logging streams DBG_INPUT, // Input streams diff --git a/src/IPAddr.cc b/src/IPAddr.cc index cc52de31ed..7fd3755042 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -45,23 +45,6 @@ HashKey* BuildConnIDHashKey(const ConnID& id) 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) { if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 ) diff --git a/src/IPAddr.h b/src/IPAddr.h index e79f3aa0a9..0c6942c61e 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -363,7 +363,6 @@ public: void ConvertToThreadingValue(threading::Value::addr_t* v) const; friend HashKey* BuildConnIDHashKey(const ConnID& id); - friend HashKey* BuildExpectedConnHashKey(const analyzer::ExpectedConn& c); unsigned int MemoryAllocation() const { return padded_sizeof(*this); } diff --git a/src/PIA.cc b/src/PIA.cc index f2eb633cd4..2e4cf06e86 100644 --- a/src/PIA.cc +++ b/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) { - 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 ) 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 ) { - 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 partial connections once we get such. return; @@ -180,7 +180,7 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip) static struct tcphdr* tcp4 = 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 ) { @@ -266,7 +266,7 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule) { 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 // partial connections once we get such. 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), // 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; // 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) { - 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 ) { diff --git a/src/RuleAction.cc b/src/RuleAction.cc index c0a4809c88..7d594e695f 100644 --- a/src/RuleAction.cc +++ b/src/RuleAction.cc @@ -54,15 +54,12 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer) reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str()); } else - child_analyzer = analyzer::Tag::ERROR; - - if ( analyzer != analyzer::Tag::ERROR ) - analyzer_mgr->ActivateSigs(); + child_analyzer = analyzer::Tag(); } void RuleActionAnalyzer::PrintDebug() { - if ( child_analyzer == analyzer::Tag::ERROR ) + if ( ! child_analyzer ) fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer).c_str()); else fprintf(stderr, "|%s:%s|\n", @@ -74,7 +71,7 @@ void RuleActionAnalyzer::PrintDebug() void RuleActionEnable::DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len) { - if ( ChildAnalyzer() == analyzer::Tag::ERROR ) + if ( ! ChildAnalyzer() ) { if ( ! analyzer_mgr->IsEnabled(Analyzer()) ) return; @@ -103,7 +100,7 @@ void RuleActionEnable::PrintDebug() void RuleActionDisable::DoAction(const Rule* parent, RuleEndpointState* state, const u_char* data, int len) { - if ( ChildAnalyzer() == analyzer::Tag::ERROR ) + if ( ! ChildAnalyzer() ) { if ( state->PIA() ) state->PIA()->DeactivateAnalyzer(Analyzer()); diff --git a/src/Sessions.cc b/src/Sessions.cc index 7586899e14..782bf4c496 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -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); conn->SetTransport(tproto); - analyzer_mgr->BuildInitialAnalyzerTree(tproto, conn, data); + analyzer_mgr->BuildInitialAnalyzerTree(conn); bool external = conn->IsExternal(); diff --git a/src/TCP.cc b/src/TCP.cc index feb21c3271..058e6608ca 100644 --- a/src/TCP.cc +++ b/src/TCP.cc @@ -1874,7 +1874,7 @@ void TCP_ApplicationAnalyzer::DeliverPacket(int len, const u_char* data, const IP_Hdr* ip, int 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, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } diff --git a/src/analyzer.bif b/src/analyzer.bif index 2ce5af992d..92b533308a 100644 --- a/src/analyzer.bif +++ b/src/analyzer.bif @@ -26,10 +26,10 @@ function Analyzer::__register_for_port%(id: Analyzer::Tag, p: port%) : 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_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); %} diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index 6ef67eb497..ff02e83f18 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -75,7 +75,7 @@ Analyzer::Analyzer(const char* name, Connection* arg_conn) output_handler = 0; 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 ) 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()); } @@ -368,7 +368,7 @@ void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer) LOOP_OVER_CHILDREN(i) 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()); // We just flag it as being removed here but postpone // actually doing that to later. Otherwise, we'd need @@ -386,7 +386,7 @@ void Analyzer::RemoveChildAnalyzer(ID id) LOOP_OVER_CHILDREN(i) 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()); // See comment above. (*i)->removing = true; @@ -440,7 +440,7 @@ Analyzer* Analyzer::FindChild(Tag arg_tag) Analyzer* Analyzer::FindChild(const string& 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) @@ -456,7 +456,7 @@ void Analyzer::DeleteChild(analyzer_list::iterator i) 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()); children.erase(i); @@ -467,7 +467,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer) { 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(), analyzer->IsOrig() ? "originator" : "responder", fmt_analyzer(analyzer).c_str()); @@ -495,7 +495,7 @@ void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer) 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(), analyzer->IsOrig() ? "originator" : "responder", fmt_analyzer(analyzer).c_str()); @@ -519,7 +519,7 @@ void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer) else *head = s->sibling; - DBG_LOG(DBG_DPD, "%s removed support %s", + DBG_LOG(DBG_ANALYZER, "%s removed support %s", fmt_analyzer(this).c_str(), analyzer->IsOrig() ? "originator" : "responder", 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, 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_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } 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_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } 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"); } 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"); } void Analyzer::FlipRoles() { - DBG_LOG(DBG_DPD, "%s FlipRoles()"); + DBG_LOG(DBG_ANALYZER, "%s FlipRoles()"); LOOP_OVER_CHILDREN(i) (*i)->FlipRoles(); @@ -596,7 +596,7 @@ void Analyzer::ProtocolConfirmation() val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(tag.Val()); + vl->append(tag.AsEnumVal()); vl->append(new Val(id, TYPE_COUNT)); // 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; vl->append(BuildConnVal()); - vl->append(tag.Val()); + vl->append(tag.AsEnumVal()); vl->append(new Val(id, TYPE_COUNT)); vl->append(r); diff --git a/src/analyzer/Component.cc b/src/analyzer/Component.cc new file mode 100644 index 0000000000..9640d6d8ac --- /dev/null +++ b/src/analyzer/Component.cc @@ -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(")"); + } + diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h new file mode 100644 index 0000000000..0a48c0546f --- /dev/null +++ b/src/analyzer/Component.h @@ -0,0 +1,121 @@ + +#ifndef ANALYZER_PLUGIN_COMPONENT_H +#define ANALYZER_PLUGIN_COMPONENT_H + +#include + +#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 diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 060595aea2..e30976b9e3 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -16,8 +16,8 @@ using namespace analyzer; -ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp, - uint16 _resp_p, uint16 _proto) +Manager::ConnIndex::ConnIndex(const IPAddr& _orig, const IPAddr& _resp, + uint16 _resp_p, uint16 _proto) { if ( _orig == IPAddr(string("0.0.0.0")) ) // don't use the IPv4 mapping, use the literal unspecified address @@ -25,21 +25,37 @@ ExpectedConn::ExpectedConn(const IPAddr& _orig, const IPAddr& _resp, orig = IPAddr(string("::")); else orig = _orig; + resp = _resp; resp_p = _resp_p; proto = _proto; } -ExpectedConn::ExpectedConn(const ExpectedConn& c) +Manager::ConnIndex::ConnIndex() { - orig = c.orig; - resp = c.resp; - resp_p = c.resp_p; - proto = c.proto; + orig = resp = IPAddr("0.0.0.0"); + resp_p = 0; + proto = 0; + } + +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() - : expected_conns_queue(AssignedAnalyzer::compare) { tag_enum_type = new EnumType("Analyzer::Tag"); ::ID* id = install_ID("Tag", "Analyzer", true, true); @@ -58,26 +74,19 @@ Manager::~Manager() analyzers_by_port_tcp.clear(); // Clean up expected-connection table. - while ( expected_conns_queue.size() ) + while ( conns_by_timeout.size() ) { - AssignedAnalyzer* a = expected_conns_queue.top(); - if ( ! a->deleted ) - { - HashKey* key = BuildExpectedConnHashKey(a->conn); - expected_conns.Remove(key); - delete key; - } - - expected_conns_queue.pop(); + ScheduledAnalyzer* a = conns_by_timeout.top(); + conns_by_timeout.pop(); delete a; } } void Manager::Init() { - std::list analyzers = plugin_mgr->Components(plugin::component::ANALYZER); + std::list analyzers = plugin_mgr->Components(plugin::component::ANALYZER); - for ( std::list::const_iterator i = analyzers.begin(); i != analyzers.end(); i++ ) + for ( std::list::const_iterator i = analyzers.begin(); i != analyzers.end(); i++ ) RegisterAnalyzerComponent(*i); // Caache these tags. @@ -91,12 +100,12 @@ void Manager::Init() void Manager::DumpDebug() { #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++ ) - 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_DPD, "Analyzers by port:"); + DBG_LOG(DBG_ANALYZER, ""); + 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++ ) { @@ -105,7 +114,7 @@ void Manager::DumpDebug() for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); 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++ ) @@ -115,15 +124,15 @@ void Manager::DumpDebug() for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); 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 ODesc d; tag_enum_type->Describe(&d); - DBG_LOG(DBG_DPD, ""); - DBG_LOG(DBG_DPD, "Analyzer::Tag type: %s", d.Description()); + DBG_LOG(DBG_ANALYZER, ""); + DBG_LOG(DBG_ANALYZER, "Analyzer::Tag type: %s", d.Description()); #endif #endif @@ -133,35 +142,35 @@ void Manager::Done() { } -void Manager::RegisterAnalyzerComponent(PluginComponent* component) +void Manager::RegisterAnalyzerComponent(Component* component) { if ( Lookup(component->Name()) ) 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()); analyzers_by_name.insert(std::make_pair(component->Name(), 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_*" string name = to_upper(component->Name()); 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) { - PluginComponent* p = Lookup(tag); + Component* p = Lookup(tag); if ( ! p ) { - DBG_LOG(DBG_DPD, "Asked to enable non-existing analyzer"); + DBG_LOG(DBG_ANALYZER, "Asked to enable non-existing analyzer"); 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); return true; @@ -169,15 +178,15 @@ bool Manager::EnableAnalyzer(Tag tag) bool Manager::EnableAnalyzer(EnumVal* val) { - PluginComponent* p = Lookup(val); + Component* p = Lookup(val); if ( ! p ) { - DBG_LOG(DBG_DPD, "Asked to enable non-existing analyzer"); + DBG_LOG(DBG_ANALYZER, "Asked to enable non-existing analyzer"); 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); return true; @@ -185,15 +194,15 @@ bool Manager::EnableAnalyzer(EnumVal* val) bool Manager::DisableAnalyzer(Tag tag) { - PluginComponent* p = Lookup(tag); + Component* p = Lookup(tag); if ( ! p ) { - DBG_LOG(DBG_DPD, "Asked to disable non-existing analyzer"); + DBG_LOG(DBG_ANALYZER, "Asked to disable non-existing analyzer"); 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); return true; @@ -201,15 +210,15 @@ bool Manager::DisableAnalyzer(Tag tag) bool Manager::DisableAnalyzer(EnumVal* val) { - PluginComponent* p = Lookup(val); + Component* p = Lookup(val); if ( ! p ) { - DBG_LOG(DBG_DPD, "Asked to disable non-existing analyzer"); + DBG_LOG(DBG_ANALYZER, "Asked to disable non-existing analyzer"); 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); return true; @@ -220,11 +229,11 @@ bool Manager::IsEnabled(Tag tag) if ( ! tag ) return false; - PluginComponent* p = Lookup(tag); + Component* p = Lookup(tag); if ( ! p ) { - DBG_LOG(DBG_DPD, "Asked to check non-existing analyzer"); + DBG_LOG(DBG_ANALYZER, "Asked to check non-existing analyzer"); return false; } @@ -233,11 +242,11 @@ bool Manager::IsEnabled(Tag tag) bool Manager::IsEnabled(EnumVal* val) { - PluginComponent* p = Lookup(val); + Component* p = Lookup(val); if ( ! p ) { - DBG_LOG(DBG_DPD, "Asked to check non-existing analyzer"); + DBG_LOG(DBG_ANALYZER, "Asked to check non-existing analyzer"); return false; } @@ -247,11 +256,11 @@ bool Manager::IsEnabled(EnumVal* val) bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port) { - PluginComponent* p = Lookup(val); + Component* p = Lookup(val); 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; } @@ -260,11 +269,11 @@ bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port) bool Manager::UnregisterAnalyzerForPort(EnumVal* val, PortVal* port) { - PluginComponent* p = Lookup(val); + Component* p = Lookup(val); 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; } @@ -277,7 +286,7 @@ bool Manager::RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port #ifdef DEBUG 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 l->insert(tag); @@ -290,7 +299,7 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po #ifdef DEBUG 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 l->erase(tag); @@ -299,7 +308,7 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn) { - PluginComponent* c = Lookup(tag); + Component* c = Lookup(tag); if ( ! c ) reporter->InternalError("request to instantiate unknown analyzer"); @@ -329,7 +338,7 @@ const string& Manager::GetAnalyzerName(Tag tag) if ( ! tag ) return error; - PluginComponent* c = Lookup(tag); + Component* c = Lookup(tag); if ( ! c ) 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) { - PluginComponent* c = Lookup(name); - return c ? c->Tag() : Tag::ERROR; + Component* c = Lookup(name); + return c ? c->Tag() : Tag(); } Tag Manager::GetAnalyzerTag(const char* name) { - PluginComponent* c = Lookup(name); - return c ? c->Tag() : Tag::ERROR; + Component* c = Lookup(name); + return c ? c->Tag() : Tag(); } EnumType* Manager::GetTagEnumType() @@ -359,26 +368,25 @@ EnumType* Manager::GetTagEnumType() return tag_enum_type; } - -PluginComponent* Manager::Lookup(const string& name) +Component* Manager::Lookup(const string& name) { analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name)); 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)); 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); 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()); 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); } -Tag Manager::GetExpected(int proto, const 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) +bool Manager::BuildInitialAnalyzerTree(Connection* conn) { Analyzer* analyzer = 0; TCP_Analyzer* tcp = 0; UDP_Analyzer* udp = 0; ICMP_Analyzer* icmp = 0; TransportLayerAnalyzer* root = 0; - Tag expected = Tag::ERROR; + tag_set expected; PIA* pia = 0; bool analyzed = false; bool check_port = false; - switch ( proto ) { + switch ( conn->ConnTransport() ) { case TRANSPORT_TCP: root = tcp = new TCP_Analyzer(conn); pia = new PIA_TCP(conn); - expected = GetExpected(proto, conn); + expected = GetScheduled(conn); check_port = true; - DBG_DPD(conn, "activated TCP analyzer"); + DBG_ANALYZER(conn, "activated TCP analyzer"); break; case TRANSPORT_UDP: root = udp = new UDP_Analyzer(conn); pia = new PIA_UDP(conn); - expected = GetExpected(proto, conn); + expected = GetScheduled(conn); check_port = true; - DBG_DPD(conn, "activated UDP analyzer"); + DBG_ANALYZER(conn, "activated UDP analyzer"); break; case TRANSPORT_ICMP: { root = icmp = new ICMP_Analyzer(conn); - DBG_DPD(conn, "activated ICMP analyzer"); + DBG_ANALYZER(conn, "activated ICMP analyzer"); analyzed = true; break; } @@ -492,34 +470,34 @@ bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn, if ( ! root ) { - DBG_DPD(conn, "cannot build analyzer tree"); + DBG_ANALYZER(conn, "cannot build analyzer tree"); return false; } // 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 ) { root->AddChildAnalyzer(analyzer, false); - DBG_DPD_ARGS(conn, "activated %s analyzer as scheduled", - analyzer_mgr->GetAnalyzerName(expected).c_str()); + DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled", + analyzer_mgr->GetAnalyzerName(*i).c_str()); } - // Hmm... Do we want *just* the expected analyzer, or all - // other potential analyzers as well? For now we only take - // the scheduled one. } - else + // Hmm... Do we want *just* the expected analyzer, or all + // other potential analyzers as well? For now we only take + // the scheduled ones. + if ( expected.size() == 0 ) { // Let's see if it's a port we know. if ( check_port && ! dpd_ignore_ports ) { 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 ) { @@ -531,7 +509,7 @@ bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn, continue; 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); } } @@ -622,78 +600,116 @@ bool Manager::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn, if ( ! analyzed ) conn->SetLifetime(non_analyzed_lifetime); - if ( expected != Tag::ERROR ) - conn->Event(expected_connection_seen, 0, - new Val(expected, TYPE_COUNT)); + for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ ) + conn->Event(scheduled_analyzer_applied, 0, i->AsEnumVal()); return true; } -void Manager::ExpectConnection(const IPAddr& orig, const IPAddr& resp, - uint16 resp_p, - TransportProto proto, Tag analyzer, - double timeout, void* cookie) +void Manager::ExpireScheduledAnalyzers() { - // Use the chance to see if the oldest entry is already expired. - if ( expected_conns_queue.size() ) + if ( ! network_time ) + return; + + while ( conns_by_timeout.size() ) { - AssignedAnalyzer* a = expected_conns_queue.top(); - if ( a->timeout < network_time ) + ScheduledAnalyzer* a = conns_by_timeout.top(); + + if ( a->timeout > network_time ) + return; + + conns_by_timeout.pop(); + + std::pair all = conns.equal_range(a->conn); + + bool found = false; + + for ( conns_map::iterator i = all.first; i != all.second; i++ ) { - if ( ! a->deleted ) - { - HashKey* key = BuildExpectedConnHashKey(a->conn); - expected_conns.Remove(key); - delete key; - } + if ( i->second != a ) + continue; - expected_conns_queue.pop(); + conns.erase(i); - DBG_LOG(DBG_DPD, "Expired expected %s analyzer for %s", - analyzer_mgr->GetAnalyzerName(analyzer).c_str(), - fmt_conn_id(a->conn.orig, 0, - a->conn.resp, - a->conn.resp_p)); + 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; + found = true; + break; } + + assert(found); } - - ExpectedConn c(orig, resp, resp_p, proto); - - HashKey* key = BuildExpectedConnHashKey(c); - - AssignedAnalyzer* a = expected_conns.Lookup(key); - - if ( a ) - a->deleted = true; - - a = new AssignedAnalyzer(c); - - a->analyzer = analyzer; - a->cookie = cookie; - a->timeout = network_time + timeout; - a->deleted = false; - - expected_conns.Insert(key, a); - expected_conns_queue.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, + TransportProto proto, Tag analyzer, + double timeout) + { + if ( ! network_time ) + { + reporter->Warning("cannot schedule analyzers before processing begins; ignored"); + return; + } + + assert(timeout); + + // Use the chance to see if the oldest entry is already expired. + ExpireScheduledAnalyzers(); + + ScheduledAnalyzer* a = new ScheduledAnalyzer; + a->conn = ConnIndex(orig, resp, resp_p, proto); + a->analyzer = analyzer; + a->timeout = network_time + timeout; + + conns.insert(std::make_pair(a->conn, a)); + conns_by_timeout.push(a); + } + +void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, TransportProto proto, const string& analyzer, - double timeout, void* cookie) + double timeout) { Tag tag = GetAnalyzerTag(analyzer); - if ( tag != Tag::ERROR ) - ExpectConnection(orig, resp, resp_p, proto, tag, timeout, cookie); + if ( tag != Tag() ) + ScheduleAnalyzer(orig, resp, resp_p, proto, tag, timeout); } -void Manager::ExpectConnection(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p, - Val* analyzer, double timeout, void* cookie) +void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p, + Val* analyzer, double timeout) { 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 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; } diff --git a/src/analyzer/Manager.h b/src/analyzer/Manager.h index 33b27ed38a..0284504f35 100644 --- a/src/analyzer/Manager.h +++ b/src/analyzer/Manager.h @@ -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 #define ANALYZER_MANAGER_H #include #include "Analyzer.h" -#include "PluginComponent.h" +#include "Component.h" #include "Tag.h" #include "../Dict.h" @@ -15,139 +31,333 @@ namespace analyzer { -// Manager debug logging, which includes the connection id into the message. -#ifdef DEBUG -# define DBG_DPD(conn, txt) \ - DBG_LOG(DBG_DPD, "%s " txt, \ - fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \ - conn->RespAddr(), ntohs(conn->RespPort()))); -# define DBG_DPD_ARGS(conn, fmt, args...) \ - DBG_LOG(DBG_DPD, "%s " fmt, \ - fmt_conn_id(conn->OrigAddr(), ntohs(conn->OrigPort()), \ - 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 maintaining and scheduling available protocol analyzers. + * + * The manager maintains a registry of all available protocol analyzers, + * including a mapping between their textual names and analyzer::Tag. It + * instantantiates new analyzers on demand. For new connections, the manager + * sets up their initial analyzer tree, including adding the right \c PIA, + * respecting well-known ports, and tracking any analyzers specifically + * scheduled for individidual connections. + */ class Manager { public: + /** + * Constructor. + */ Manager(); + + /** + * Destructor. + */ ~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(); + + /** + * 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. + /** + * 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); + + /** + * 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); + /** + * 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); + + /** + * 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); + /** + * Returns true if an analyzer is enabled. + * + * @param tag The analyzer's 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); + /** + * 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); + + /** + * 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); + /** + * 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); + + /** + * 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); + /** + * 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. + + /** + * 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. + /** + * 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(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(); - // Given info about the first packet, build initial analyzer tree. - // - // It would be more flexible if we simply pass in the IP header and - // then extract the information we need. However, when this method - // is called from the session management, protocol and ports have - // already been extracted there and it would be a waste to do it - // again. - // - // 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(TransportProto proto, Connection* conn, - const u_char* data); + /** + * Given the first packet of a connection, builds its initial + * analyzer tree. + * + * @param conn The connection to add the initial set of analyzers to. + * + * @return False if the tree cannot be build; that's usually an + * internally error. + */ + bool BuildInitialAnalyzerTree(Connection* conn); - // Schedules a particular analyzer for an upcoming connection. 0 acts - // as a wildcard for orig. (Cookie is currently unused. Eventually, - // we may pass it on to the analyzer). - void ExpectConnection(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, - TransportProto proto, Tag analyzer, - double timeout, void* cookie); + /** + * 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.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, - double timeout, void* cookie); + double timeout); - void ExpectConnection(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p, - Val* val, double timeout, void* cookie); - - // Activates signature matching for protocol detection. (Called when - // an Manager signatures is found.) - void ActivateSigs() { sigs_activated = true; } - bool SigsActivated() const { return sigs_activated; } + /** + * 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 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: typedef set tag_set; - typedef map analyzer_map_by_name; - typedef map analyzer_map_by_tag; - typedef map analyzer_map_by_val; + typedef map analyzer_map_by_name; + typedef map analyzer_map_by_tag; + typedef map analyzer_map_by_val; typedef map analyzer_map_by_port; - void RegisterAnalyzerComponent(PluginComponent* component); // Takes ownership. + void RegisterAnalyzerComponent(Component* component); // Takes ownership. - PluginComponent* Lookup(const string& name); - PluginComponent* Lookup(const char* name); - PluginComponent* Lookup(const Tag& tag); - PluginComponent* Lookup(EnumVal* val); + Component* Lookup(const string& name); + Component* Lookup(const char* name); + Component* Lookup(const Tag& tag); + Component* Lookup(EnumVal* val); tag_set* LookupPort(PortVal* val, 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::::Error if none. - Tag GetExpected(int proto, const Connection* conn); + tag_set GetScheduled(const Connection* conn); + void ExpireScheduledAnalyzers(); analyzer_map_by_port analyzers_by_port_tcp; analyzer_map_by_port analyzers_by_port_udp; @@ -163,21 +373,62 @@ private: EnumType* tag_enum_type; - // True if signature-matching has been activated. - bool sigs_activated; + //// Data structures to track analyzed scheduled for future connections. - PDict(AssignedAnalyzer) expected_conns; + // The index for a scheduled connection. + struct ConnIndex { + IPAddr orig; + IPAddr resp; + uint16 resp_p; + uint16 proto; - typedef priority_queue< - AssignedAnalyzer*, - vector, - bool (*)(const AssignedAnalyzer*, - const AssignedAnalyzer*)> conn_queue; - conn_queue expected_conns_queue; + ConnIndex(const IPAddr& _orig, const IPAddr& _resp, + uint16 _resp_p, uint16 _proto); + ConnIndex(); + + bool operator<(const ConnIndex& other) const; + }; + + // 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 conns_map; + typedef std::priority_queue, + ScheduledAnalyzer::Comparator> conns_queue; + + conns_map conns; + conns_queue conns_by_timeout; }; } 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 diff --git a/src/analyzer/PluginComponent.cc b/src/analyzer/PluginComponent.cc deleted file mode 100644 index fed3ca225a..0000000000 --- a/src/analyzer/PluginComponent.cc +++ /dev/null @@ -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); - } - diff --git a/src/analyzer/PluginComponent.h b/src/analyzer/PluginComponent.h deleted file mode 100644 index baad63f9f8..0000000000 --- a/src/analyzer/PluginComponent.h +++ /dev/null @@ -1,51 +0,0 @@ - -#ifndef ANALYZER_PLUGIN_COMPONENT_H -#define ANALYZER_PLUGIN_COMPONENT_H - -#include - -#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 diff --git a/src/analyzer/Tag.cc b/src/analyzer/Tag.cc index fbf1bcd2b7..0b765742dc 100644 --- a/src/analyzer/Tag.cc +++ b/src/analyzer/Tag.cc @@ -6,11 +6,10 @@ using namespace analyzer; -Tag Tag::ERROR; - Tag::Tag(type_t arg_type, subtype_t arg_subtype) { assert(arg_type > 0); + type = arg_type; subtype = arg_subtype; 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) { assert(val); + val = arg_val; Ref(val); @@ -37,7 +37,7 @@ Tag::Tag(const Tag& other) : type(other.type), subtype(other.subtype) subtype = other.subtype; val = other.val; - if ( val ) + if ( val ) Ref(val); } @@ -48,7 +48,7 @@ Tag::Tag() val = 0; } -EnumVal* Tag::Val() +EnumVal* Tag::AsEnumVal() const { if ( ! val ) { @@ -66,4 +66,3 @@ std::string Tag::AsString() const { return fmt("%" PRIu32 "/%" PRIu32, type, subtype); } - diff --git a/src/analyzer/Tag.h b/src/analyzer/Tag.h index dab8563982..90a6804dc4 100644 --- a/src/analyzer/Tag.h +++ b/src/analyzer/Tag.h @@ -2,14 +2,6 @@ #ifndef 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 "util.h" @@ -17,41 +9,129 @@ class EnumVal; 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 { public: + /** + * Type for the analyzer's main type. + */ typedef uint32 type_t; + + /** + * Type for the analyzer's subtype. + */ typedef uint32 subtype_t; - Tag(type_t type, subtype_t subtype = 0); - Tag(EnumVal* val); + /* + * Copy constructor. + */ 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; } + + /** + * Returns the tag's subtype. + */ subtype_t Subtype() const { return subtype; } - // Returns an identifying integer for this tag that's guaranteed to - // be unique across all tags. - EnumVal* Val(); + /** + * Returns the \c Analyzer::Tag enum that corresponds to this tag. + * 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; + /** + * Returns false if the tag represents an error value rather than a + * legal analyzer type. + */ 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 { 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: - type_t type; - subtype_t subtype; - EnumVal* val; + type_t type; // Main type. + subtype_t subtype; // Subtype. + mutable EnumVal* val; // Analyzer::Tag value. }; } diff --git a/src/event.bif b/src/event.bif index fbc02ef8b5..65ff3a5731 100644 --- a/src/event.bif +++ b/src/event.bif @@ -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_pending connection_rejected connection_reset connection_reused ## 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:: ## @@ -168,7 +168,7 @@ event tunnel_changed%(c: connection, e: EncapsulatingConnVector%); ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_reused ## 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%); ## 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_half_finished connection_partial_close connection_pending ## 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 event connection_attempt%(c: connection%); @@ -199,7 +199,7 @@ event connection_attempt%(c: connection%); ## connection_external connection_finished connection_first_ACK ## connection_half_finished connection_partial_close connection_pending ## 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 event connection_established%(c: connection%); @@ -215,7 +215,7 @@ event connection_established%(c: connection%); ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reset connection_reused ## 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%); @@ -231,7 +231,7 @@ event partial_connection%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_pending ## 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 event connection_partial_close%(c: connection%); @@ -244,7 +244,7 @@ event connection_partial_close%(c: connection%); ## connection_established connection_external connection_first_ACK ## connection_half_finished connection_partial_close connection_pending ## 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 event connection_finished%(c: connection%); @@ -258,7 +258,7 @@ event connection_finished%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_partial_close connection_pending ## 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 event connection_half_finished%(c: connection%); @@ -270,7 +270,7 @@ event connection_half_finished%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## 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 ## ## c: The connection. @@ -294,7 +294,7 @@ event connection_rejected%(c: connection%); ## connection_first_ACK connection_half_finished connection_partial_close ## connection_pending connection_rejected connection_reused ## 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 event connection_reset%(c: connection%); @@ -306,7 +306,7 @@ event connection_reset%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## 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 event connection_pending%(c: connection%); @@ -323,7 +323,7 @@ event connection_pending%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## 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 ## tcp_inactivity_timeout icmp_inactivity_timeout conn_stats event connection_state_remove%(c: connection%); @@ -339,7 +339,7 @@ event connection_state_remove%(c: connection%); ## connection_external connection_finished connection_first_ACK ## connection_half_finished connection_partial_close connection_pending ## 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 ## ## .. note:: @@ -360,7 +360,7 @@ event connection_SYN_packet%(c: connection, pkt: SYN_packet%); ## connection_established connection_external connection_finished ## connection_half_finished connection_partial_close connection_pending ## 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 ## ## .. note:: @@ -379,7 +379,7 @@ event connection_first_ACK%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## 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 ## ## .. note:: @@ -402,7 +402,7 @@ event connection_timeout%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## 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 event connection_reused%(c: connection%); @@ -416,7 +416,7 @@ event connection_reused%(c: connection%); ## connection_established connection_external connection_finished ## connection_first_ACK connection_half_finished connection_partial_close ## 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 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_half_finished connection_partial_close connection_pending ## 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 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 ## ``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 ## event that should be avoided when at all possible. It's usually infeasible to diff --git a/src/plugin/Macros.h b/src/plugin/Macros.h index f10d6adf45..f132927560 100644 --- a/src/plugin/Macros.h +++ b/src/plugin/Macros.h @@ -2,7 +2,7 @@ #ifndef PLUGIN_MACROS_H #define PLUGIN_MACROS_H -#include "analyzer/PluginComponent.h" +#include "analyzer/Component.h" #define BRO_PLUGIN_VERSION_BUILTIN -1 #define BRO_PLUGIN_API_VERSION 1 @@ -36,7 +36,10 @@ std::list > __bif_##file##_init(); \ AddBifInitFunction(&__bif_##file##_init); -#define BRO_PLUGIN_ANALYZER(tag, factory, enabled, partial) \ - AddComponent(new ::analyzer::PluginComponent(tag, factory, enabled, partial)); +#define BRO_PLUGIN_ANALYZER(tag, factory) \ + 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 diff --git a/src/protocols/BuiltInAnalyzers.cc b/src/protocols/BuiltInAnalyzers.cc index 0c96ab17e4..ff7bd11c1c 100644 --- a/src/protocols/BuiltInAnalyzers.cc +++ b/src/protocols/BuiltInAnalyzers.cc @@ -3,7 +3,7 @@ // analyzers into separate plugins. #include "BuiltInAnalyzers.h" -#include "analyzer/PluginComponent.h" +#include "analyzer/Component.h" #include "../binpac_bro.h" @@ -47,8 +47,13 @@ using namespace analyzer; BuiltinAnalyzers builtin_analyzers; -#define DEFINE_ANALYZER(name, factory, enabled, partial) \ - AddComponent(new PluginComponent(name, factory, enabled, partial)) +#define DEFINE_ANALYZER(name, factory) \ + 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() { @@ -58,72 +63,69 @@ void BuiltinAnalyzers::Init() desc.version = BRO_PLUGIN_VERSION_BUILTIN; SetDescription(desc); - DEFINE_ANALYZER("PIA_TCP", PIA_TCP::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("PIA_UDP", PIA_UDP::InstantiateAnalyzer, true, false); + DEFINE_ANALYZER("PIA_TCP", PIA_TCP::InstantiateAnalyzer); + 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("UDP", UDP_Analyzer::InstantiateAnalyzer, true, false); + DEFINE_ANALYZER("TCP", TCP_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("UDP", UDP_Analyzer::InstantiateAnalyzer); - DEFINE_ANALYZER("BITTORRENT", BitTorrent_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("BITTORRENTTRACKER", BitTorrentTracker_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("DCE_RPC", DCE_RPC_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("DNS", DNS_Analyzer::InstantiateAnalyzer, ! FLAGS_use_binpac, false); - DEFINE_ANALYZER("FINGER", Finger_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("FTP", FTP_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("GNUTELLA", Gnutella_Analyzer::InstantiateAnalyzer, true, false); - // DEFINE_ANALYZER("HTTP", HTTP_Analyzer::InstantiateAnalyzer, ! FLAGS_use_binpac, false); - DEFINE_ANALYZER("IDENT", Ident_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("IRC", IRC_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("LOGIN", 0, true, false); // just a base class - DEFINE_ANALYZER("NCP", NCP_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("NETBIOSSSN", NetbiosSSN_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("NFS", NFS_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("NTP", NTP_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("POP3", POP3_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("PORTMAPPER", Portmapper_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("RPC", 0, true, false); - DEFINE_ANALYZER("RSH", Rsh_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("SMB", SMB_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("SMTP", SMTP_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("SSH", SSH_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("TELNET", Telnet_Analyzer::InstantiateAnalyzer, true, false); + DEFINE_ANALYZER("BITTORRENT", BitTorrent_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("BITTORRENTTRACKER", BitTorrentTracker_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("DCE_RPC", DCE_RPC_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER_VERSION_NON_BINPAC("DNS", DNS_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("FINGER", Finger_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("FTP", FTP_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("GNUTELLA", Gnutella_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("IDENT", Ident_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("IRC", IRC_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("LOGIN", 0); // just a base class + DEFINE_ANALYZER("NCP", NCP_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("NETBIOSSSN", NetbiosSSN_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("NFS", NFS_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("NTP", NTP_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("POP3", POP3_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("PORTMAPPER", Portmapper_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("RPC", 0); + DEFINE_ANALYZER("RSH", Rsh_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("SMB", SMB_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("SMTP", SMTP_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("SSH", SSH_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("TELNET", Telnet_Analyzer::InstantiateAnalyzer); - DEFINE_ANALYZER("DHCP_BINPAC", DHCP_Analyzer_binpac::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("DNS_TCP_BINPAC", DNS_TCP_Analyzer_binpac::InstantiateAnalyzer, FLAGS_use_binpac, false); - DEFINE_ANALYZER("DNS_UDP_BINPAC", DNS_UDP_Analyzer_binpac::InstantiateAnalyzer, FLAGS_use_binpac, false); - // DEFINE_ANALYZER("HTTP_BINPAC", HTTP_Analyzer_binpac::InstantiateAnalyzer, FLAGS_use_binpac, false); - // DEFINE_ANALYZER("SSL", SSL_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("SYSLOG_BINPAC", Syslog_Analyzer_binpac::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("MODBUS", ModbusTCP_Analyzer::InstantiateAnalyzer, true, false); + DEFINE_ANALYZER("DHCP_BINPAC", DHCP_Analyzer_binpac::InstantiateAnalyzer); + DEFINE_ANALYZER_VERSION_BINPAC("DNS_TCP_BINPAC", DNS_TCP_Analyzer_binpac::InstantiateAnalyzer); + DEFINE_ANALYZER_VERSION_BINPAC("DNS_UDP_BINPAC", DNS_UDP_Analyzer_binpac::InstantiateAnalyzer); + DEFINE_ANALYZER("SYSLOG_BINPAC", Syslog_Analyzer_binpac::InstantiateAnalyzer); + DEFINE_ANALYZER("MODBUS", ModbusTCP_Analyzer::InstantiateAnalyzer); - DEFINE_ANALYZER("AYIYA", AYIYA_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("SOCKS", SOCKS_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("TEREDO", Teredo_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("GTPV1", GTPv1_Analyzer::InstantiateAnalyzer, true, false); + DEFINE_ANALYZER("AYIYA", AYIYA_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("SOCKS", SOCKS_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("TEREDO", Teredo_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("GTPV1", GTPv1_Analyzer::InstantiateAnalyzer); - DEFINE_ANALYZER("FILE", File_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("BACKDOOR", BackDoor_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("INTERCONN", InterConn_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("STEPPINGSTONE", SteppingStone_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("TCPSTATS", TCPStats_Analyzer::InstantiateAnalyzer, true, false); - DEFINE_ANALYZER("CONNSIZE", ConnSize_Analyzer::InstantiateAnalyzer, true, false); + DEFINE_ANALYZER("FILE", File_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("BACKDOOR", BackDoor_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("INTERCONN", InterConn_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("STEPPINGSTONE", SteppingStone_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("TCPSTATS", TCPStats_Analyzer::InstantiateAnalyzer); + DEFINE_ANALYZER("CONNSIZE", ConnSize_Analyzer::InstantiateAnalyzer); - DEFINE_ANALYZER("CONTENTS", 0, true, false); - DEFINE_ANALYZER("CONTENTLINE", 0, true, false); - DEFINE_ANALYZER("NVT", 0, true, false); - DEFINE_ANALYZER("ZIP", 0, true, false); - DEFINE_ANALYZER("CONTENTS_DNS", 0, true, false); - DEFINE_ANALYZER("CONTENTS_NETBIOSSSN", 0, true, false); - DEFINE_ANALYZER("CONTENTS_NCP", 0, true, false); - DEFINE_ANALYZER("CONTENTS_RLOGIN", 0, true, false); - DEFINE_ANALYZER("CONTENTS_RSH", 0, true, false); - DEFINE_ANALYZER("CONTENTS_DCE_RPC", 0, true, false); - DEFINE_ANALYZER("CONTENTS_SMB", 0, true, false); - DEFINE_ANALYZER("CONTENTS_RPC", 0, true, false); - DEFINE_ANALYZER("CONTENTS_NFS", 0, true, false); - DEFINE_ANALYZER("FTP_ADAT", 0, true, false); + DEFINE_ANALYZER("CONTENTS", 0); + DEFINE_ANALYZER("CONTENTLINE", 0); + DEFINE_ANALYZER("NVT", 0); + DEFINE_ANALYZER("ZIP", 0); + DEFINE_ANALYZER("CONTENTS_DNS", 0); + DEFINE_ANALYZER("CONTENTS_NETBIOSSSN", 0); + DEFINE_ANALYZER("CONTENTS_NCP", 0); + DEFINE_ANALYZER("CONTENTS_RLOGIN", 0); + DEFINE_ANALYZER("CONTENTS_RSH", 0); + DEFINE_ANALYZER("CONTENTS_DCE_RPC", 0); + DEFINE_ANALYZER("CONTENTS_SMB", 0); + DEFINE_ANALYZER("CONTENTS_RPC", 0); + DEFINE_ANALYZER("CONTENTS_NFS", 0); + DEFINE_ANALYZER("FTP_ADAT", 0); } diff --git a/src/protocols/http/HTTP.cc b/src/protocols/http/HTTP.cc index 2812f3662b..d5d911bbc6 100644 --- a/src/protocols/http/HTTP.cc +++ b/src/protocols/http/HTTP.cc @@ -17,7 +17,7 @@ BRO_PLUGIN_BEGIN(HTTP) 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(functions); BRO_PLUGIN_END diff --git a/src/protocols/ssl/Plugin.cc b/src/protocols/ssl/Plugin.cc index 3e42ae0c32..fb47c9b946 100644 --- a/src/protocols/ssl/Plugin.cc +++ b/src/protocols/ssl/Plugin.cc @@ -5,6 +5,6 @@ BRO_PLUGIN_BEGIN(SSL) 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_END diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index b476306ae6..0482b574f8 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,19 +3,19 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2013-03-26-20-58-03 +#open 2013-04-01-19-44-31 #fields name #types string scripts/base/init-bare.bro - build/src/base/const.bif.bro - build/src/base/types.bif.bro - build/src/base/strings.bif.bro - build/src/base/bro.bif.bro - build/src/base/reporter.bif.bro - build/src/base/event.bif.bro + build/scripts/base/bif/const.bif.bro + build/scripts/base/bif/types.bif.bro + build/scripts/base/bif/strings.bif.bro + build/scripts/base/bif/bro.bif.bro + build/scripts/base/bif/reporter.bif.bro + build/scripts/base/bif/event.bif.bro scripts/base/frameworks/logging/__load__.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/./scp.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/input/__load__.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/raw.bro scripts/base/frameworks/input/./readers/benchmark.bro scripts/base/frameworks/analyzer/__load__.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 -#close 2013-03-26-20-58-03 +#close 2013-04-01-19-44-31 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index ddcae1d0eb..390040ab4a 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,19 +3,19 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2013-03-26-20-58-16 +#open 2013-04-01-19-44-38 #fields name #types string scripts/base/init-bare.bro - build/src/base/const.bif.bro - build/src/base/types.bif.bro - build/src/base/strings.bif.bro - build/src/base/bro.bif.bro - build/src/base/reporter.bif.bro - build/src/base/event.bif.bro + build/scripts/base/bif/const.bif.bro + build/scripts/base/bif/types.bif.bro + build/scripts/base/bif/strings.bif.bro + build/scripts/base/bif/bro.bif.bro + build/scripts/base/bif/reporter.bif.bro + build/scripts/base/bif/event.bif.bro scripts/base/frameworks/logging/__load__.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/./scp.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/input/__load__.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/raw.bro scripts/base/frameworks/input/./readers/benchmark.bro scripts/base/frameworks/analyzer/__load__.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/utils/site.bro scripts/base/utils/./patterns.bro @@ -122,4 +126,4 @@ scripts/base/init-default.bro scripts/base/protocols/syslog/./main.bro scripts/base/misc/find-checksum-offloading.bro scripts/policy/misc/loaded-scripts.bro -#close 2013-03-26-20-58-16 +#close 2013-04-01-19-44-38 diff --git a/testing/btest/Baseline/scripts.base.frameworks.analyzer.schedule-analyzer/output b/testing/btest/Baseline/scripts.base.frameworks.analyzer.schedule-analyzer/output new file mode 100644 index 0000000000..69285a4dbe --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.analyzer.schedule-analyzer/output @@ -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 diff --git a/testing/btest/scripts/base/frameworks/analyzer/schedule-analyzer.bro b/testing/btest/scripts/base/frameworks/analyzer/schedule-analyzer.bro new file mode 100644 index 0000000000..e67a4fa82b --- /dev/null +++ b/testing/btest/scripts/base/frameworks/analyzer/schedule-analyzer.bro @@ -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; + } + + + + +