diff --git a/cmake b/cmake index 39c1516be5..8cc03d64d0 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 39c1516be5e630bd5d78082e974fae708faa4e8c +Subproject commit 8cc03d64d00676cb75a38543800ac0de192557dd diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c54abea7a6..aa51e68e91 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,7 +117,7 @@ foreach (bift ${BIF_SRCS}) bif_target(${bift}) endforeach () -add_custom_target(generate_standard_bifs DEPENDS ${ALL_BIF_OUTPUTS}) +add_custom_target(generate_bifs DEPENDS ${ALL_BIF_OUTPUTS}) ######################################################################## ## BinPAC-dependent targets @@ -159,20 +159,16 @@ binpac_target(modbus.pac ## Including subdirectories. ######################################################################## +set(bro_PLUGIN_OBJECT_LIBS CACHE INTERNAL "plugin object libraries" FORCE) + add_subdirectory(analyzer) +add_subdirectory(protocols) set(bro_SUBDIRS $ + ${bro_PLUGIN_OBJECT_LIBS} ) - -######################################################################## -## Including plug-ins that are compiled in statically. -######################################################################## - -set(bro_PLUGIN_OBJECT_LIBS CACHE INTERNAL "plugin object libraries" FORCE) -add_subdirectory(protocols) - ######################################################################## ## bro target @@ -403,8 +399,7 @@ set(bro_SRCS ) collect_headers(bro_HEADERS ${bro_SRCS}) - -add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_PLUGIN_OBJECT_LIBS} ${bro_SUBDIRS}) +add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_SUBDIRS}) target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/src/Conn.cc b/src/Conn.cc index e7687c5464..e476dd674b 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -413,7 +413,7 @@ analyzer::Analyzer* Connection::FindAnalyzer(analyzer::Tag tag) return root_analyzer ? root_analyzer->FindChild(tag) : 0; } -analyzer::Analyzer* Connection::FindAnalyzer(const string& name) +analyzer::Analyzer* Connection::FindAnalyzer(const char* name) { return root_analyzer->FindChild(name); } diff --git a/src/Conn.h b/src/Conn.h index 1989ce0b43..1b13500fad 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -107,7 +107,7 @@ public: analyzer::Analyzer* FindAnalyzer(analyzer::ID id); analyzer::Analyzer* FindAnalyzer(analyzer::Tag tag); // find first in tree. - analyzer::Analyzer* FindAnalyzer(const string& name); // find first in tree. + analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree. TransportProto ConnTransport() const { return proto; } diff --git a/src/EventRegistry.cc b/src/EventRegistry.cc index cf8aa6802e..2da16de51d 100644 --- a/src/EventRegistry.cc +++ b/src/EventRegistry.cc @@ -80,8 +80,10 @@ void EventRegistry::PrintDebug() while ( (v = handlers.NextEntry(k, c)) ) { delete k; - fprintf(stderr, "Registered event %s (%s handler)\n", v->Name(), - v->LocalHandler()? "local" : "no"); + fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(), + v->LocalHandler()? "local" : "no", + *v ? "active" : "not active" + ); } } diff --git a/src/ID.h b/src/ID.h index 9c1f56e80f..57e1222511 100644 --- a/src/ID.h +++ b/src/ID.h @@ -26,6 +26,7 @@ public: bool IsGlobal() const { return scope != SCOPE_FUNCTION; } bool IsExport() const { return is_export; } + void SetExport() { is_export = true; } string ModuleName() const; diff --git a/src/RuleAction.cc b/src/RuleAction.cc index 7d594e695f..6bbd7243cd 100644 --- a/src/RuleAction.cc +++ b/src/RuleAction.cc @@ -40,7 +40,7 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer) string str(arg_analyzer); string::size_type pos = str.find(':'); string arg = str.substr(0, pos); - analyzer = analyzer_mgr->GetAnalyzerTag(arg); + analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str()); if ( ! analyzer ) reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str()); @@ -48,7 +48,7 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer) if ( pos != string::npos ) { arg = str.substr(pos + 1); - child_analyzer = analyzer_mgr->GetAnalyzerTag(arg); + child_analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str()); if ( ! child_analyzer ) reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str()); @@ -60,11 +60,11 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer) void RuleActionAnalyzer::PrintDebug() { if ( ! child_analyzer ) - fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer).c_str()); + fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer)); else fprintf(stderr, "|%s:%s|\n", - analyzer_mgr->GetAnalyzerName(analyzer).c_str(), - analyzer_mgr->GetAnalyzerName(child_analyzer).c_str()); + analyzer_mgr->GetAnalyzerName(analyzer), + analyzer_mgr->GetAnalyzerName(child_analyzer)); } diff --git a/src/TCP.h b/src/TCP.h index 61bcd7ef7c..be91d473c2 100644 --- a/src/TCP.h +++ b/src/TCP.h @@ -267,6 +267,10 @@ public: : Analyzer(name, conn) { tcp = 0; } + TCP_ApplicationAnalyzer(Connection* conn) + : Analyzer(conn) + { tcp = 0; } + virtual ~TCP_ApplicationAnalyzer() { } // This may be nil if we are not directly associated with a TCP diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index 0bc8d28c8f..c482ddd792 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -72,28 +72,56 @@ void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer, analyzer::ID Analyzer::id_counter = 0;; -const string& Analyzer::GetAnalyzerName() const +const char* Analyzer::GetAnalyzerName() const { + assert(tag); return analyzer_mgr->GetAnalyzerName(tag); } +void Analyzer::SetAnalyzerTag(const Tag& arg_tag) + { + assert(! tag || tag == arg_tag); + tag = arg_tag; + } + bool Analyzer::IsAnalyzer(const char* name) { - return analyzer_mgr->GetAnalyzerName(tag) == name; + assert(tag); + return strcmp(analyzer_mgr->GetAnalyzerName(tag), name) == 0; } // Used in debugging output. static string fmt_analyzer(Analyzer* a) { - return a->GetAnalyzerName() + fmt("[%d]", a->GetID()); + return string(a->GetAnalyzerName()) + fmt("[%d]", a->GetID()); } -Analyzer::Analyzer(const char* name, Connection* arg_conn) +Analyzer::Analyzer(const char* name, Connection* conn) + { + Tag tag = analyzer_mgr->GetAnalyzerTag(name); + + if ( ! tag ) + reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name); + + CtorInit(tag, conn); + } + +Analyzer::Analyzer(const Tag& tag, Connection* conn) + { + CtorInit(tag, conn); + } + +Analyzer::Analyzer(Connection* conn) + { + CtorInit(Tag(), conn); + } + +void Analyzer::CtorInit(const Tag& arg_tag, Connection* arg_conn) { // Don't Ref conn here to avoid circular ref'ing. It can't be deleted // before us. conn = arg_conn; - tag = analyzer_mgr->GetAnalyzerTag(name); + tag = arg_tag; id = ++id_counter; protocol_confirmed = false; skip = false; @@ -104,10 +132,6 @@ Analyzer::Analyzer(const char* name, Connection* arg_conn) resp_supporters = 0; signature = 0; output_handler = 0; - - if ( ! tag ) - reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name); - } Analyzer::~Analyzer() @@ -417,7 +441,7 @@ void Analyzer::RemoveChildAnalyzer(ID id) LOOP_OVER_CHILDREN(i) if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) ) { - DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName().c_str(), id, + DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName(), id, fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str()); // See comment above. (*i)->removing = true; @@ -468,7 +492,7 @@ Analyzer* Analyzer::FindChild(Tag arg_tag) return 0; } -Analyzer* Analyzer::FindChild(const string& name) +Analyzer* Analyzer::FindChild(const char* name) { Tag tag = analyzer_mgr->GetAnalyzerTag(name); return tag ? FindChild(tag) : 0; @@ -625,9 +649,12 @@ void Analyzer::ProtocolConfirmation() if ( protocol_confirmed ) return; + EnumVal* tval = tag.AsEnumVal(); + Ref(tval); + val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(tag.AsEnumVal()); + vl->append(tval); vl->append(new Val(id, TYPE_COUNT)); // We immediately raise the event so that the analyzer can quickly @@ -653,9 +680,12 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len) else r = new StringVal(reason); + EnumVal* tval = tag.AsEnumVal(); + Ref(tval); + val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(tag.AsEnumVal()); + vl->append(tval); vl->append(new Val(id, TYPE_COUNT)); vl->append(r); diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 07e5d5acf4..f509f79941 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -61,13 +61,32 @@ public: /** * Constructor. * - * @param name A name for the protocol the analyzer is parsing. The - * name must match the one the corresponding Component registers. + * @param name The name for the type of analyzer. The name must match + * the one the corresponding Component registers. * * @param conn The connection the analyzer is associated with. */ Analyzer(const char* name, Connection* conn); + /** + * Constructor. + * + * @param tag The tag for the type of analyzer. The tag must map to + * the name the corresponding Component registers. + * + * @param conn The connection the analyzer is associated with. + */ + Analyzer(const Tag& tag, Connection* conn); + + /** + * Constructor. As this version of the constructor does not receive a + * name or tag, setTag() must be called before the instance can be + * used. + * + * @param conn The connection the analyzer is associated with. + */ + Analyzer(Connection* conn); + /** * Destructor. */ @@ -285,14 +304,22 @@ public: /** * Returns the tag associated with the analyzer's type. */ - Tag GetAnalyzerTag() const { return tag; } + Tag GetAnalyzerTag() const { assert(tag); return tag; } + + /** + * Sets the tag associated with the analyzer's type. Note that this + * can be called only right after construction, if the constructor + * did not receive a name or tag. The method cannot be used to change + * an existing tag. + */ + void SetAnalyzerTag(const Tag& tag); /** * Returns a textual description of the analyzer's type. This is * what's passed to the constructor and usally corresponds to the * protocol name, e.g., "HTTP". */ - const string& GetAnalyzerName() const; + const char* GetAnalyzerName() const; /** * Returns true if this analyzer's type matches the name passes in. @@ -377,7 +404,7 @@ public: * @return The first analyzer of the given type found, or null if * none. */ - Analyzer* FindChild(const string& name); + Analyzer* FindChild(const char* name); /** * Returns a list of all direct child analyzers. @@ -574,6 +601,9 @@ private: // already Done(). void DeleteChild(analyzer_list::iterator i); + // Helper for the ctors. + void CtorInit(const Tag& tag, Connection* conn); + Tag tag; ID id; diff --git a/src/analyzer/Component.cc b/src/analyzer/Component.cc index 9640d6d8ac..6ce433a594 100644 --- a/src/analyzer/Component.cc +++ b/src/analyzer/Component.cc @@ -7,10 +7,10 @@ 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) +Component::Component(const char* 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; + name = copy_string(arg_name); factory = arg_factory; enabled = arg_enabled; partial = arg_partial; @@ -18,6 +18,26 @@ Component::Component(std::string arg_name, factory_callback arg_factory, Tag::su tag = analyzer::Tag(++type_counter, arg_subtype); } +Component::Component(const Component& other) + : plugin::Component(Type()) + { + name = copy_string(other.name); + factory = other.factory; + enabled = other.enabled; + partial = other.partial; + tag = other.tag; + } + +Component::~Component() + { + delete [] name; + } + +analyzer::Tag Component::Tag() const + { + return tag; + } + void Component::Describe(ODesc* d) { plugin::Component::Describe(d); @@ -27,3 +47,16 @@ void Component::Describe(ODesc* d) d->Add(")"); } +Component& Component::operator=(const Component& other) + { + if ( &other != this ) + { + name = copy_string(other.name); + factory = other.factory; + enabled = other.enabled; + partial = other.partial; + tag = other.tag; + } + + return *this; + } diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h index 0a48c0546f..67751e1b35 100644 --- a/src/analyzer/Component.h +++ b/src/analyzer/Component.h @@ -2,8 +2,6 @@ #ifndef ANALYZER_PLUGIN_COMPONENT_H #define ANALYZER_PLUGIN_COMPONENT_H -#include - #include "Tag.h" #include "plugin/Component.h" @@ -21,8 +19,6 @@ class Analyzer; * * 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: @@ -58,13 +54,23 @@ public: * 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); + Component(const char* name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true, bool partial = false); + + /** + * Copy constructor. + */ + Component(const Component& other); + + /** + * Destructor. + */ + ~Component(); /** * 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; } + const char* Name() const { return name; } /** * Returns the analyzer's factory function. @@ -74,7 +80,7 @@ public: /** * Returns whether the analyzer supports partial connections. Partial * connections are those where Bro starts processing payload - * mid-stream, after missing the beginning. + * mid-stream, after missing the beginning. */ bool Partial() const { return partial; } @@ -89,7 +95,7 @@ public: * generated for each new Components, and hence unique across all of * them. */ - analyzer::Tag Tag() const { return tag; } + analyzer::Tag Tag() const; /** * Enables or disables this analyzer. @@ -105,15 +111,17 @@ public: */ virtual void Describe(ODesc* d); + Component& operator=(const Component& other); + private: - std::string name; // The analyzer's name. + const char* 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; + static analyzer::Tag::type_t type_counter; }; } diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 68869b3799..056c3c2b7d 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -108,7 +108,7 @@ void Manager::DumpDebug() #ifdef DEBUG 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_ANALYZER, " %s (%s)", i->second->Name().c_str(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled"); + DBG_LOG(DBG_ANALYZER, " %s (%s)", i->second->Name(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled"); DBG_LOG(DBG_ANALYZER, ""); DBG_LOG(DBG_ANALYZER, "Analyzers by port:"); @@ -118,7 +118,7 @@ void Manager::DumpDebug() string s; for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ ) - s += GetAnalyzerName(*j) + " "; + s += string(GetAnalyzerName(*j)) + " "; DBG_LOG(DBG_ANALYZER, " %d/tcp: %s", i->first, s.c_str()); } @@ -128,7 +128,7 @@ void Manager::DumpDebug() string s; for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ ) - s += GetAnalyzerName(*j) + " "; + s += string(GetAnalyzerName(*j)) + " "; DBG_LOG(DBG_ANALYZER, " %d/udp: %s", i->first, s.c_str()); } @@ -151,10 +151,10 @@ void Manager::Done() void Manager::RegisterAnalyzerComponent(Component* component) { if ( Lookup(component->Name()) ) - reporter->FatalError("Analyzer %s defined more than once", component->Name().c_str()); + reporter->FatalError("Analyzer %s defined more than once", component->Name()); DBG_LOG(DBG_ANALYZER, "Registering analyzer %s (tag %s)", - component->Name().c_str(), component->Tag().AsString().c_str()); + component->Name(), 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)); @@ -173,7 +173,7 @@ bool Manager::EnableAnalyzer(Tag tag) if ( ! p ) return false; - DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name().c_str()); + DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name()); p->SetEnabled(true); return true; @@ -186,7 +186,7 @@ bool Manager::EnableAnalyzer(EnumVal* val) if ( ! p ) return false; - DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name().c_str()); + DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name()); p->SetEnabled(true); return true; @@ -199,7 +199,7 @@ bool Manager::DisableAnalyzer(Tag tag) if ( ! p ) return false; - DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name().c_str()); + DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name()); p->SetEnabled(false); return true; @@ -212,7 +212,7 @@ bool Manager::DisableAnalyzer(EnumVal* val) if ( ! p ) return false; - DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name().c_str()); + DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name()); p->SetEnabled(false); return true; @@ -256,7 +256,7 @@ bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port) if ( ! p ) return false; - + return RegisterAnalyzerForPort(p->Tag(), port->PortType(), port->Port()); } @@ -275,8 +275,8 @@ bool Manager::RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port tag_set* l = LookupPort(proto, port, true); #ifdef DEBUG - std::string name = GetAnalyzerName(tag); - DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto); + const char* name = GetAnalyzerName(tag); + DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name, port, proto); #endif l->insert(tag); @@ -288,8 +288,8 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po tag_set* l = LookupPort(proto, port, true); #ifdef DEBUG - std::string name = GetAnalyzerName(tag); - DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto); + const char* name = GetAnalyzerName(tag); + DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name, port, proto); #endif l->erase(tag); @@ -312,6 +312,8 @@ Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn) if ( ! a ) reporter->InternalError("analyzer instantiation failed"); + a->SetAnalyzerTag(tag); + return a; } @@ -321,9 +323,9 @@ Analyzer* Manager::InstantiateAnalyzer(const char* name, Connection* conn) return tag ? InstantiateAnalyzer(tag, conn) : 0; } -const string& Manager::GetAnalyzerName(Tag tag) +const char* Manager::GetAnalyzerName(Tag tag) { - static string error = ""; + static const char* error = ""; if ( ! tag ) return error; @@ -336,17 +338,11 @@ const string& Manager::GetAnalyzerName(Tag tag) return c->Name(); } -const string& Manager::GetAnalyzerName(Val* val) +const char* Manager::GetAnalyzerName(Val* val) { return GetAnalyzerName(Tag(val->AsEnumVal())); } -Tag Manager::GetAnalyzerTag(const string& name) - { - Component* c = Lookup(name); - return c ? c->Tag() : Tag(); - } - Tag Manager::GetAnalyzerTag(const char* name) { Component* c = Lookup(name); @@ -358,12 +354,6 @@ EnumType* Manager::GetTagEnumType() return tag_enum_type; } -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; - } - Component* Manager::Lookup(const char* name) { analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name)); @@ -474,7 +464,7 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn) root->AddChildAnalyzer(analyzer, false); DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled", - analyzer_mgr->GetAnalyzerName(*i).c_str()); + analyzer_mgr->GetAnalyzerName(*i)); } } @@ -500,7 +490,7 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn) root->AddChildAnalyzer(analyzer, false); DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d", - analyzer_mgr->GetAnalyzerName(*j).c_str(), resp_port); + analyzer_mgr->GetAnalyzerName(*j), resp_port); } } } @@ -622,7 +612,7 @@ void Manager::ExpireScheduledAnalyzers() conns.erase(i); DBG_LOG(DBG_ANALYZER, "Expiring expected analyzer %s for connection %s", - analyzer_mgr->GetAnalyzerName(a->analyzer).c_str(), + analyzer_mgr->GetAnalyzerName(a->analyzer), fmt_conn_id(a->conn.orig, 0, a->conn.resp, a->conn.resp_p)); delete a; @@ -661,7 +651,7 @@ void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, - TransportProto proto, const string& analyzer, + TransportProto proto, const char* analyzer, double timeout) { Tag tag = GetAnalyzerTag(analyzer); diff --git a/src/analyzer/Manager.h b/src/analyzer/Manager.h index 750ac986fb..371cad956d 100644 --- a/src/analyzer/Manager.h +++ b/src/analyzer/Manager.h @@ -42,6 +42,10 @@ namespace analyzer { * 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. + * + * Note that we keep the public interface of this class free of std::* + * classes. This allows to external analyzer code to potentially use a + * different C++ standard library. */ class Manager { public: @@ -232,7 +236,7 @@ public: * * @return The name, or an empty string if the tag is invalid. */ - const string& GetAnalyzerName(Tag tag); + const char* GetAnalyzerName(Tag tag); /** * Translates an script-level analyzer tag into corresponding @@ -243,17 +247,7 @@ public: * * @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); + const char* GetAnalyzerName(Val* val); /** * Translates an analyzer name into the corresponding tag. @@ -327,7 +321,7 @@ public: * schedule this analyzer. Must be non-zero. */ void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p, - TransportProto proto, const string& analyzer, + TransportProto proto, const char* analyzer, double timeout); /** diff --git a/src/analyzer/Tag.cc b/src/analyzer/Tag.cc index 0b765742dc..09c3c26caf 100644 --- a/src/analyzer/Tag.cc +++ b/src/analyzer/Tag.cc @@ -31,7 +31,7 @@ Tag::Tag(EnumVal* arg_val) subtype = (i >> 31) & 0xffffffff; } -Tag::Tag(const Tag& other) : type(other.type), subtype(other.subtype) +Tag::Tag(const Tag& other) { type = other.type; subtype = other.subtype; @@ -48,6 +48,27 @@ Tag::Tag() val = 0; } +Tag::~Tag() + { + Unref(val); + val = 0; + } + +Tag& Tag::operator=(const Tag& other) + { + if ( this != &other ) + { + type = other.type; + subtype = other.subtype; + val = other.val; + + if ( val ) + Ref(val); + } + + return *this; + } + EnumVal* Tag::AsEnumVal() const { if ( ! val ) diff --git a/src/analyzer/Tag.h b/src/analyzer/Tag.h index 90a6804dc4..ca3bc8b02f 100644 --- a/src/analyzer/Tag.h +++ b/src/analyzer/Tag.h @@ -53,6 +53,11 @@ public: */ Tag(); + /** + * Destructor. + */ + ~Tag(); + /** * Returns the tag's main type. */ @@ -81,6 +86,11 @@ public: */ operator bool() const { return *this != Tag(); } + /** + * Assignment operator. + */ + Tag& operator=(const Tag& other); + /** * Compares two tags for equality. */ diff --git a/src/builtin-func.l b/src/builtin-func.l index 2128c21f6b..b23ef43e22 100644 --- a/src/builtin-func.l +++ b/src/builtin-func.l @@ -235,9 +235,9 @@ void init_alternative_mode() fprintf(fp_func_init, "\n"); fprintf(fp_func_init, "namespace plugin { namespace %s {\n", plugin); fprintf(fp_func_init, "\n"); - fprintf(fp_func_init, "std::list > __bif_%s_init()\n", name); + fprintf(fp_func_init, "std::list > __bif_%s_init()\n", name); fprintf(fp_func_init, "\t{\n"); - fprintf(fp_func_init, "\tstd::list > bifs;\n"); + fprintf(fp_func_init, "\tstd::list > bifs;\n"); fprintf(fp_func_init, "\n"); } } diff --git a/src/main.cc b/src/main.cc index 59a383543c..b3747226b3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -814,8 +814,8 @@ int main(int argc, char** argv) log_mgr = new logging::Manager(); input_mgr = new input::Manager(); plugin_mgr = new plugin::Manager(); - plugin_mgr->InitPlugins(); + plugin_mgr->InitPlugins(); analyzer_mgr->Init(); if ( events_file ) diff --git a/src/plugin/Macros.h b/src/plugin/Macros.h index f132927560..1ddcb1afc8 100644 --- a/src/plugin/Macros.h +++ b/src/plugin/Macros.h @@ -15,25 +15,22 @@ protected: \ void Init() \ { \ - plugin::Description _desc; \ - _desc.name = #_name; \ - _desc.version = _BRO_PLUGIN_VERSION_DEFAULT; \ - _desc.api_version = BRO_PLUGIN_API_VERSION; + SetName(#_name); \ + SetVersion(_BRO_PLUGIN_VERSION_DEFAULT); \ + SetAPIVersion(BRO_PLUGIN_API_VERSION); #define BRO_PLUGIN_END \ - SetDescription(_desc); \ } \ }; \ \ static Plugin __plugin; \ } } -#define BRO_PLUGIN_DESCRIPTION _desc.description -#define BRO_PLUGIN_URL _desc.url -#define BRO_PLUGIN_VERSION _desc.version +#define BRO_PLUGIN_DESCRIPTION(x) SetDescription(x) +#define BRO_PLUGIN_VERSION(x) SetVersion(x) #define BRO_PLUGIN_BIF_FILE(file) \ - std::list > __bif_##file##_init(); \ + std::list > __bif_##file##_init(); \ AddBifInitFunction(&__bif_##file##_init); #define BRO_PLUGIN_ANALYZER(tag, factory) \ diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 69377fd97a..99c73339b3 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -9,33 +9,86 @@ using namespace plugin; -Description::Description() +BifItem::BifItem(const BifItem& other) { - name = ""; + id = copy_string(other.id); + type = other.type; + } - // These will be reset by the BRO_PLUGIN_* macros. - version = -9999; - api_version = -9999; +BifItem& BifItem::operator=(const BifItem& other) + { + if ( this != &other ) + { + id = copy_string(other.id); + type = other.type; + } + + return *this; + } + +BifItem::~BifItem() + { + delete [] id; } Plugin::Plugin() { + name = copy_string(""); + description = copy_string(""); + + // These will be reset by the BRO_PLUGIN_* macros. + version = -9999; + api_version = -9999; + Manager::RegisterPlugin(this); } -Description Plugin::GetDescription() const - { - return description; - } - -void Plugin::SetDescription(Description& desc) - { - description = desc; - } - Plugin::~Plugin() { Done(); + + delete [] name; + delete [] description; + } + +const char* Plugin::Name() + { + return name; + } + +void Plugin::SetName(const char* arg_name) + { + name = copy_string(arg_name); + } + +const char* Plugin::Description() + { + return description; + } + +void Plugin::SetDescription(const char* arg_description) + { + description = copy_string(arg_description); + } + +int Plugin::Version() + { + return version; + } + +void Plugin::SetVersion(int arg_version) + { + version = arg_version; + } + +int Plugin::APIVersion() + { + return api_version; + } + +void Plugin::SetAPIVersion(int arg_version) + { + api_version = arg_version; } void Plugin::Init() @@ -50,17 +103,26 @@ void Plugin::InitBif() for ( bif_init_func_result::const_iterator i = items.begin(); i != items.end(); i++ ) { - BifItem bi; - bi.id = (*i).first; - bi.type = (BifItem::Type)(*i).second; + BifItem bi((*i).first, (BifItem::Type)(*i).second); bif_items.push_back(bi); } } } -const Plugin::bif_item_list& Plugin::BifItems() +Plugin::bif_item_list Plugin::BifItems() { - return bif_items; + bif_item_list l1 = bif_items; + bif_item_list l2 = CustomBifItems(); + + for ( bif_item_list::const_iterator i = l2.begin(); i != l2.end(); i++ ) + l1.push_back(*i); + + return l1; + } + +Plugin::bif_item_list Plugin::CustomBifItems() + { + return bif_item_list(); } void Plugin::Done() @@ -89,24 +151,18 @@ void Plugin::AddBifInitFunction(bif_init_func c) void Plugin::Describe(ODesc* d) { d->Add("Plugin: "); - d->Add(description.name); + d->Add(name); - if ( description.description.size() ) + if ( description && *description ) { d->Add(" - "); - d->Add(description.description); + d->Add(description); } - if ( description.version != BRO_PLUGIN_VERSION_BUILTIN ) + if ( version != BRO_PLUGIN_VERSION_BUILTIN ) { d->Add(" (version "); - d->Add(description.version); - - if ( description.url.size() ) - { - d->Add(", from "); - d->Add(description.url); - } + d->Add(version); d->Add(")"); } @@ -125,11 +181,13 @@ void Plugin::Describe(ODesc* d) d->Add("\n"); } - for ( bif_item_list::const_iterator i = bif_items.begin(); i != bif_items.end(); i++ ) + bif_item_list items = BifItems(); + + for ( bif_item_list::const_iterator i = items.begin(); i != items.end(); i++ ) { const char* type = 0; - switch ( (*i).type ) { + switch ( (*i).GetType() ) { case BifItem::FUNCTION: type = "Function"; break; @@ -158,7 +216,7 @@ void Plugin::Describe(ODesc* d) d->Add("["); d->Add(type); d->Add("] "); - d->Add((*i).id); + d->Add((*i).GetID()); d->Add("\n"); } } diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 314de47083..c5753767db 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -14,25 +14,30 @@ namespace plugin { class Manager; class Component; -struct Description { - std::string name; - std::string description; - std::string url; - int version; - int api_version; - - Description(); - void Describe(ODesc* d); - }; - -struct BifItem { +class BifItem { +public: // Values must match the integers bifcl generates. enum Type { FUNCTION = 1, EVENT = 2, CONSTANT = 3, GLOBAL = 4, TYPE = 5 }; - std::string id; + BifItem(const std::string& id, Type type); + BifItem(const BifItem& other); + BifItem& operator=(const BifItem& other); + ~BifItem(); + + const char* GetID() const { return id; } + Type GetType() const { return type; } + +private: + const char* id; Type type; }; +inline BifItem::BifItem(const std::string& arg_id, Type arg_type) + { + id = copy_string(arg_id.c_str()); + type = arg_type; + } + class Plugin { public: typedef std::list component_list; @@ -41,15 +46,17 @@ public: Plugin(); virtual ~Plugin(); - Description GetDescription() const; - void SetDescription(Description& desc); + const char* Name(); + const char* Description(); + int Version(); + int APIVersion(); component_list Components(); void InitBif(); // Must be called after InitBif() only. - const bif_item_list& BifItems(); + bif_item_list BifItems(); virtual void Init(); virtual void Done(); @@ -57,19 +64,42 @@ public: void Describe(ODesc* d); protected: + typedef std::list > bif_init_func_result; + typedef bif_init_func_result (*bif_init_func)(); + + void SetName(const char* name); + void SetDescription(const char* descr); + void SetVersion(int version); + void SetAPIVersion(int version); + /** * Takes ownership. */ void AddComponent(Component* c); - typedef std::list > bif_init_func_result; - typedef bif_init_func_result (*bif_init_func)(); + /** + * Can be overriden by derived class to inform the plugin about + * further BiF items they provide on their own (i.e., outside of the + * standard mechanism processing *.bif files automatically.). This + * information is for information purpuses only and will show up in + * the result of BifItem() as well as in the Describe() output. + */ + virtual bif_item_list CustomBifItems() ; + + /** + * Internal function adding an entry point for registering + * auto-generated BiFs. + */ void AddBifInitFunction(bif_init_func c); private: typedef std::list bif_init_func_list; - plugin::Description description; + const char* name; + const char* description; + int version; + int api_version; + component_list components; bif_item_list bif_items; bif_init_func_list bif_inits; diff --git a/src/protocols/BuiltInAnalyzers.cc b/src/protocols/BuiltInAnalyzers.cc index 3bc15621fd..b3597c63df 100644 --- a/src/protocols/BuiltInAnalyzers.cc +++ b/src/protocols/BuiltInAnalyzers.cc @@ -50,11 +50,9 @@ BuiltinAnalyzers builtin_analyzers; void BuiltinAnalyzers::Init() { - plugin::Description desc; - desc.name = "Core-Analyzers"; - desc.description = "Built-in protocol analyzers"; - desc.version = BRO_PLUGIN_VERSION_BUILTIN; - SetDescription(desc); + SetName("Core-Analyzers"); + SetDescription("Built-in protocol analyzers"); + SetVersion(BRO_PLUGIN_VERSION_BUILTIN); DEFINE_ANALYZER("PIA_TCP", PIA_TCP::InstantiateAnalyzer); DEFINE_ANALYZER("PIA_UDP", PIA_UDP::InstantiateAnalyzer); diff --git a/src/protocols/http/HTTP.cc b/src/protocols/http/HTTP.cc index a58d5a6bf3..61ce2e0833 100644 --- a/src/protocols/http/HTTP.cc +++ b/src/protocols/http/HTTP.cc @@ -16,7 +16,7 @@ #include "plugin/Plugin.h" BRO_PLUGIN_BEGIN(HTTP) - BRO_PLUGIN_DESCRIPTION = "HTTP Analyzer"; + BRO_PLUGIN_DESCRIPTION("HTTP Analyzer"); BRO_PLUGIN_ANALYZER("HTTP", HTTP_Analyzer::InstantiateAnalyzer); BRO_PLUGIN_BIF_FILE(events); BRO_PLUGIN_BIF_FILE(functions); diff --git a/src/protocols/ssl/Plugin.cc b/src/protocols/ssl/Plugin.cc index fb47c9b946..743401896d 100644 --- a/src/protocols/ssl/Plugin.cc +++ b/src/protocols/ssl/Plugin.cc @@ -4,7 +4,7 @@ #include "SSL.h" BRO_PLUGIN_BEGIN(SSL) - BRO_PLUGIN_DESCRIPTION = "SSL Analyzer"; + BRO_PLUGIN_DESCRIPTION("SSL Analyzer"); BRO_PLUGIN_ANALYZER("SSL", SSL_Analyzer::InstantiateAnalyzer); BRO_PLUGIN_BIF_FILE(events); BRO_PLUGIN_END diff --git a/src/protocols/syslog/Plugin.cc b/src/protocols/syslog/Plugin.cc index a0a2934411..8560ee7c48 100644 --- a/src/protocols/syslog/Plugin.cc +++ b/src/protocols/syslog/Plugin.cc @@ -4,7 +4,7 @@ #include "Syslog.h" BRO_PLUGIN_BEGIN(Syslog) - BRO_PLUGIN_DESCRIPTION = "Syslog Analyzer (UDP-only currently)"; + BRO_PLUGIN_DESCRIPTION("Syslog Analyzer (UDP-only currently)"); BRO_PLUGIN_ANALYZER("SYSLOG", Syslog_Analyzer::InstantiateAnalyzer); BRO_PLUGIN_BIF_FILE(events); BRO_PLUGIN_END diff --git a/src/scan.l b/src/scan.l index a4d80c88ed..babe036027 100644 --- a/src/scan.l +++ b/src/scan.l @@ -1042,6 +1042,7 @@ static void check_dpd_config_changes() valdesc.PushIndent(); v->Describe(&valdesc); +#if 0 if ( tag < AnalyzerTag::Error || tag > AnalyzerTag::LastAnalyzer ) { fprintf(stderr, "Warning: skipped bad analyzer tag: %i\n", tag); @@ -1049,8 +1050,9 @@ static void check_dpd_config_changes() } last_reST_doc->AddPortAnalysis( - Analyzer::GetTagName((AnalyzerTag::Tag)tag), + Analyzer::GetTagName((AnalyzerTag)tag), valdesc.Description()); +#endif } dpd_table->RemoveAll(); diff --git a/src/util.h b/src/util.h index 7e0c1ba085..a07d83f761 100644 --- a/src/util.h +++ b/src/util.h @@ -5,8 +5,14 @@ // Expose C99 functionality from inttypes.h, which would otherwise not be // available in C++. +#ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS +#endif + +#ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS +#endif + #include #include