diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index 8e2cbdbbbf..ecd3c9f686 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #include diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 5769a6c58a..2d905867eb 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -1,4 +1,4 @@ -// Main analyzer interface. +// See the file "COPYING" in the main distribution directory for copyright. #ifndef ANALYZER_ANALYZER_H #define ANALYZER_ANALYZER_H diff --git a/src/analyzer/Component.cc b/src/analyzer/Component.cc index 78705643e9..5844da848f 100644 --- a/src/analyzer/Component.cc +++ b/src/analyzer/Component.cc @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #include "Component.h" #include "Manager.h" diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h index 6e72f87155..79d4c12fe5 100644 --- a/src/analyzer/Component.h +++ b/src/analyzer/Component.h @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #ifndef ANALYZER_PLUGIN_COMPONENT_H #define ANALYZER_PLUGIN_COMPONENT_H diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 22912ad19d..5695dec625 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #include "Manager.h" @@ -85,9 +86,9 @@ Manager::~Manager() } } -void Manager::Init() +void Manager::InitPreScript() { - std::list analyzers = plugin_mgr->Components(plugin::component::ANALYZER); + std::list analyzers = plugin_mgr->Components(); for ( std::list::const_iterator i = analyzers.begin(); i != analyzers.end(); i++ ) RegisterAnalyzerComponent(*i); @@ -98,10 +99,9 @@ void Manager::Init() analyzer_interconn = GetAnalyzerTag("INTERCONN"); analyzer_stepping = GetAnalyzerTag("STEPPINGSTONE"); analyzer_tcpstats = GetAnalyzerTag("TCPSTATS"); - } -void Manager::InitBifs() +void Manager::InitPostScript() { #include "analyzer.bif.init.cc" } diff --git a/src/analyzer/Manager.h b/src/analyzer/Manager.h index 371cad956d..c66fd9eafb 100644 --- a/src/analyzer/Manager.h +++ b/src/analyzer/Manager.h @@ -1,3 +1,5 @@ +// See the file "COPYING" in the main distribution directory for copyright. + /** * The central management unit for registering and instantiating analyzers. * @@ -60,16 +62,16 @@ public: ~Manager(); /** - * Initializes the manager's operation. Must be called before scripts - * are parsed. + * First-stage initializion of the manager. This is called early on + * during Bro's initialization, before any scripts are processed. */ - void Init(); + void InitPreScript(); /** - * Initializes the analyze-related BiFs. Must be called after scripts - * are parsed. + * Second-stage initialization of the manager. This is called late + * during Bro's initialization after any scripts are processed. */ - void InitBifs(); + void InitPostScript(); /** * Finished the manager's operations. diff --git a/src/analyzer/Tag.cc b/src/analyzer/Tag.cc index 0459a91a32..469b61a6c5 100644 --- a/src/analyzer/Tag.cc +++ b/src/analyzer/Tag.cc @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #include "Tag.h" #include "Manager.h" diff --git a/src/analyzer/Tag.h b/src/analyzer/Tag.h index 4d91e19641..3465ddd008 100644 --- a/src/analyzer/Tag.h +++ b/src/analyzer/Tag.h @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #ifndef ANALYZER_TAG_H #define ANALYZER_TAG_H diff --git a/src/analyzer/protocol/TODO b/src/analyzer/protocol/TODO deleted file mode 100644 index d1888a18f1..0000000000 --- a/src/analyzer/protocol/TODO +++ /dev/null @@ -1,2 +0,0 @@ -- cmake dependencies don't work right yet - diff --git a/src/main.cc b/src/main.cc index 60c548ba9f..79c895e7af 100644 --- a/src/main.cc +++ b/src/main.cc @@ -826,15 +826,14 @@ int main(int argc, char** argv) persistence_serializer = new PersistenceSerializer(); remote_serializer = new RemoteSerializer(); event_registry = new EventRegistry(); - analyzer_mgr = new analyzer::Manager(); log_mgr = new logging::Manager(); input_mgr = new input::Manager(); plugin_mgr = new plugin::Manager(); file_mgr = new file_analysis::Manager(); - plugin_mgr->InitPlugins(); - analyzer_mgr->Init(); + plugin_mgr->InitPreScript(); + analyzer_mgr->InitPreScript(); if ( events_file ) event_player = new EventPlayer(events_file); @@ -854,8 +853,8 @@ int main(int argc, char** argv) yyparse(); - analyzer_mgr->InitBifs(); - plugin_mgr->InitPluginsBif(); + analyzer_mgr->InitPostScript(); + plugin_mgr->InitPostScript(); if ( print_plugins ) { diff --git a/src/plugin/Component.cc b/src/plugin/Component.cc index ddedf7abbb..7d2e69eb86 100644 --- a/src/plugin/Component.cc +++ b/src/plugin/Component.cc @@ -1,3 +1,5 @@ +// See the file "COPYING" in the main distribution directory for copyright. + #include "Component.h" #include "../Desc.h" diff --git a/src/plugin/Component.h b/src/plugin/Component.h index 09357effd2..fbeb70ebed 100644 --- a/src/plugin/Component.h +++ b/src/plugin/Component.h @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #ifndef PLUGIN_COMPONENT_H #define PLUGIN_COMPONENT_H @@ -7,25 +8,55 @@ class ODesc; namespace plugin { namespace component { - enum Type { - READER, - WRITER, - ANALYZER + +/** + * Component types. + */ +enum Type { + READER, /// An input reader (not currently used). + WRITER, /// An logging writer (not currenly used). + ANALYZER /// A protocol analyzer. }; } +#if 0 namespace input { class PluginComponent; } namespace logging { class PluginComponent; } namespace analyzer { class PluginComponent; } +#endif +/** + * Base class for plugin components. A component is a specific piece of + * functionality that a plugin provides, such as a protocol analyzer or a log + * writer. + */ class Component { public: + /** + * Constructor. + * + * @param type The type of the compoment. + */ Component(component::Type type); + + /** + * Destructor. + */ virtual ~Component(); + /** + * Returns the compoment's type. + */ component::Type Type() const; + /** + * Returns a textual representation of the component. The default + * version just output the type. Derived version should call the + * parent's implementation and that add further information. + * + * @param d The description object to use. + */ virtual void Describe(ODesc* d); private: diff --git a/src/plugin/DummyPlugin.cc b/src/plugin/DummyPlugin.cc deleted file mode 100644 index 8a7889c682..0000000000 --- a/src/plugin/DummyPlugin.cc +++ /dev/null @@ -1,28 +0,0 @@ - -#include "Plugin.h" - -class DummyPlugin { -public: - virtual void Init() - { - plugin::Description desc; - desc.name = "Dummy"; - desc.description = "My little dummy plugin"; - desc.version = 2; - desc.url = "http://dummy.bro.org"; - SetDescription(desc); - - analyzer::PluginComponent dummy("DUMMY", "Analyzer::DUMMY", dummy::Instantiate, dummy::Available, 0, false); - AddComponent(dummy); - } - -Plugin* bro_plugin() - { - return new DummyPlugin(); - } - - - - - - diff --git a/src/plugin/Macros.h b/src/plugin/Macros.h index 2288af0d79..b8e2a42fdb 100644 --- a/src/plugin/Macros.h +++ b/src/plugin/Macros.h @@ -1,14 +1,38 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +/** + * A set of macros wrapping internal logic for defining plugins and + * components. + */ #ifndef PLUGIN_MACROS_H #define PLUGIN_MACROS_H #include "analyzer/Component.h" +/** + * Place-holder API version for plugins compiled in statically. + */ #define BRO_PLUGIN_VERSION_BUILTIN -1 + +/** + * The current plugin API version. Plugins that won't match this versions + * will be rejected. + */ #define BRO_PLUGIN_API_VERSION 1 #define _BRO_PLUGIN_VERSION_DEFAULT -1 +/** + * Starts the definition of a new plugin. + * + * @param _ns: A namespace for the plugin. All plugins compiled in statically + * must use the reserved "Bro" namespace. External plugins should define + * their own namespace to avoid collisions. + * + * @param _name: The plugin's name. The combiniation of namespace and name + * must be unique across all loaded plugins. + */ #define BRO_PLUGIN_BEGIN(_ns, _name) \ namespace plugin { namespace _ns ## _ ## _name {\ class Plugin : public plugin::Plugin { \ @@ -19,6 +43,9 @@ SetVersion(_BRO_PLUGIN_VERSION_DEFAULT);\ SetAPIVersion(BRO_PLUGIN_API_VERSION); +/** + * Ends the definition of a plugin. + */ #define BRO_PLUGIN_END \ } \ }; \ @@ -26,19 +53,69 @@ static Plugin __plugin; \ } } -#define BRO_PLUGIN_DESCRIPTION(x) SetDescription(x) -#define BRO_PLUGIN_VERSION(x) SetVersion(x) +/** + * Provides a textual description for a plugin. + * + * @param d A string with the description. + */ +#define BRO_PLUGIN_DESCRIPTION(d) SetDescription(d) +/** + * Defines a version of the plugin. The version is mostly informational for + * the user; if a plugin's functionality changes, the version should be + * increased. + * + * @param v An integer version. + */ +#define BRO_PLUGIN_VERSION(v) SetVersion(v) + +/** + * Adds scrip-level items defined in a \c *.bif file to what the plugin + * provides. + * + * @param file A string with the name of \c *.bif file. When loaded, the the + * plugin will make all items defined in the file available to Bro's script + * interpreter. + */ #define BRO_PLUGIN_BIF_FILE(file) \ extern std::list > __bif_##file##_init(); \ AddBifInitFunction(&__bif_##file##_init); +/** + * Defines a component implementating a protocol analyzer. + * + * @param tag A string with the analyzer's tag. This must be unique across + * all loaded analyzers and will translate into a corresponding \c ANALYZER_* + * constant at the script-layer. + * + * @param cls The class that implements the analyzer. It must be derived + * (directly or indirectly) from analyzer::Analyzer. + */ #define BRO_PLUGIN_ANALYZER(tag, cls) \ AddComponent(new ::analyzer::Component(tag, ::analyzer::cls::InstantiateAnalyzer)); +/** + * Defines a component implementating an protocol analyzer class that will + * not be instantiated dynamically. This is for two use-cases: (1) abstract + * analyzer base classes that aren't instantiated directly; and (2) analyzers + * that are only instantiated explicitly by other Bro components, but not + * dynmically by the manager based on their tag (e.g., the ZIP analyzer is + * attached by the HTTP analyzer when corresponding content is found). + * + * @param tag A string with the analyzer's tag. This must be unique across + * all loaded analyzers and will translate into a corresponding \c ANALYZER_* + * constant at the script-layer. + */ #define BRO_PLUGIN_ANALYZER_BARE(tag) \ AddComponent(new ::analyzer::Component(tag, 0)); +/** + * Defines a component implementating a support analyzer. + * + * @param tag A string with the analyzer's tag. This must be unique across + * all loaded analyzers and will translate into a corresponding \c ANALYZER_* + * constant at the script-layer. + */ #define BRO_PLUGIN_SUPPORT_ANALYZER(tag) \ AddComponent(new ::analyzer::Component(tag, 0)); diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index b969e581c7..ed6b43d2c4 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #include "Manager.h" @@ -35,22 +36,22 @@ bool Manager::RegisterPlugin(Plugin *plugin) return true; } -void Manager::InitPlugins() +void Manager::InitPreScript() { assert(! init); for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ ) - (*i)->Init(); + (*i)->InitPreScript(); init = true; } -void Manager::InitPluginsBif() +void Manager::InitPostScript() { assert(init); for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ ) - (*i)->InitBif(); + (*i)->InitPostScript(); init = true; } diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h index 44ec8913c6..2bbcaeb0f1 100644 --- a/src/plugin/Manager.h +++ b/src/plugin/Manager.h @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #ifndef PLUGIN_MANAGER_H #define PLUGIN_MANAGER_H @@ -9,57 +10,88 @@ namespace plugin { +/** + * A singleton object managing all plugins. + */ class Manager { public: typedef std::list plugin_list; typedef Plugin::component_list component_list; + /** + * Constructor. + */ Manager(); + + /** + * Destructor. + */ ~Manager(); /** + * Loads a plugin dynamically from a file. This must be called only + * before InitPluginsPreScript() + * + * This is not currently implemented. + * + * @param file The path to the plugin to load. */ bool LoadPlugin(const std::string& file); /** + * Loads plugins dynamically found in a directory. This must be + * called only before InitPluginsPreScript(). * + * This is not currently implemented. + * + * @param dir The directory to search for plugins. */ bool LoadPluginsFrom(const std::string& dir); /** - * - * @param plugin: The plugin to register. The method does not take - * ownershop but assume the pointer will leave at least until the - * Manager is destroyed. + * First-stage initializion of the manager. This is called early on + * during Bro's initialization, before any scripts are processed, and + * forwards to the corresponding Plugin methods. */ - static bool RegisterPlugin(Plugin *plugin); + void InitPreScript(); /** - * + * Second-stage initialization of the manager. This is called late + * during Bro's initialization after any scripts are processed, and + * forwards to the corresponding Plugin methods. */ - void InitPlugins(); + void InitPostScript(); /** - * - */ - void InitPluginsBif(); - - /** - * + * Finalizes all plugins at termination time. This forwards to the + * corresponding Plugin methods. */ void FinishPlugins(); /** - * + * Returns a list of all available plugins. This includes all that + * are compiled in statically, as well as those loaded dynamically so + * far. */ plugin_list Plugins() const; /** - * + * Returns a list of all available components, in any plugin, that + * are derived from a specific class. The class is given as the + * template parameter \c T. */ - template - std::list Components(component::Type type) const; + template std::list Components() const; + + /** + * Internal method that registers a freshly instantiated plugin with + * the manager. + * + * @param plugin The plugin to register. The method does not take + * ownership, yet assumes the pointer will stay valid at least until + * the Manager is destroyed. + */ + static bool RegisterPlugin(Plugin *plugin); private: static plugin_list* PluginsInternal(); @@ -68,7 +100,7 @@ private: }; template -std::list Manager::Components(component::Type type) const +std::list Manager::Components() const { std::list result; @@ -90,6 +122,9 @@ std::list Manager::Components(component::Type type) const } +/** + * The global plugin manager singleton. + */ extern plugin::Manager* plugin_mgr; #endif diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 99c73339b3..093a4fad62 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #include @@ -9,6 +10,12 @@ using namespace plugin; +BifItem::BifItem(const std::string& arg_id, Type arg_type) + { + id = copy_string(arg_id.c_str()); + type = arg_type; + } + BifItem::BifItem(const BifItem& other) { id = copy_string(other.id); @@ -91,11 +98,11 @@ void Plugin::SetAPIVersion(int arg_version) api_version = arg_version; } -void Plugin::Init() +void Plugin::InitPreScript() { } -void Plugin::InitBif() +void Plugin::InitPostScript() { for ( bif_init_func_list::const_iterator f = bif_inits.begin(); f != bif_inits.end(); f++ ) { diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index c5753767db..189fdf5c52 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -1,3 +1,4 @@ +// See the file "COPYING" in the main distribution directory for copyright. #ifndef PLUGIN_PLUGIN_H #define PLUGIN_PLUGIN_H @@ -14,17 +15,51 @@ namespace plugin { class Manager; class Component; +/** + * A class describing an item defined in \c *.bif file. + */ class BifItem { public: - // Values must match the integers bifcl generates. + /** + * Type of the item. + * + * The values here must match the integers that \c bifcl generated. + */ enum Type { FUNCTION = 1, EVENT = 2, CONSTANT = 3, GLOBAL = 4, TYPE = 5 }; + /** + * Constructor. + * + * @param id The script-level name of the item. This should be fully + * qualified. + * + * @param type The type of the item. + */ BifItem(const std::string& id, Type type); + + /** + * Copy constructor. + */ BifItem(const BifItem& other); + + /** + * Assigment operator. + */ BifItem& operator=(const BifItem& other); + + /** + * Destructor. + */ ~BifItem(); + /** + * Returns the script-level ID as passed into the constructor. + */ const char* GetID() const { return id; } + + /** + * Returns the type as passed into the constructor. + */ Type GetType() const { return type; } private: @@ -32,44 +67,136 @@ private: Type type; }; -inline BifItem::BifItem(const std::string& arg_id, Type arg_type) - { - id = copy_string(arg_id.c_str()); - type = arg_type; - } - +/** + * Base class for all plugins. + * + * Plugins encapsulate functionality that extends one of Bro's major + * subsystems, such as analysis of a specific protocol, or logging output in + * a particular format. A plugin is a logical container that can provide one + * or more \a components implementing functionality. For example, a RPC + * plugin could provide analyzer for set of related protocols (RPC, NFS, + * etc.), each of which would be a separate component. Likewise, a SQLite + * plugin could provide both a writer and reader component. In addition to + * components, a plugin can also provide of script-level elements defined in + * *.bif files. + * + * Currently, all plugins ard compiled statically into the final Bro binary. + * Later, we will extend the infrastructure to also support plugins loaded + * dynamically as shared libraries. + */ class Plugin { public: typedef std::list component_list; typedef std::list bif_item_list; + /** + * Constructor. + */ Plugin(); + + /** + * Destructor. + */ virtual ~Plugin(); + /** + * Returns the name of the plugin. + */ const char* Name(); + + /** + * Returns a short textual description of the plugin, if provided. + */ const char* Description(); + + /** + * Returns the version of the plugin. + */ int Version(); + + /** + * Returns the internal API version that this plugin relies on. Only + * plugins that match Bro's BRO_PLUGIN_API_VERSION may be used. For + * statically compiled plugins this is automatically the case, but + * dynamically loaded plugins could later cause a mismatch. + */ int APIVersion(); + /** + * Returns a list of all components the plugin provides. + * BRO_PLUGIN_VERSION_BUILTIN indiciates that it's a plugin compiled + * in statically. + */ component_list Components(); - void InitBif(); - - // Must be called after InitBif() only. + /** + * Returns a list of all BiF items that the plugin provides. This + * must be called only after InitBif() has been executed. + */ bif_item_list BifItems(); - virtual void Init(); + /** + * First-stage initialization of the plugin called early during Bro's + * startup, before scripts are parsed. This can be overridden by + * derived classes; they must however call the parent's + * implementation. + */ + virtual void InitPreScript(); + + /** + * Second-stage initialization of the plugin called late during Bro's + * startup, after scripts are parsed. This can be overridden by + * derived classes; they must however call the parent's + * implementation. + */ + virtual void InitPostScript(); + + /** + * Finalizer method that derived classes can override for performing + * custom tasks at shutdown. Implementation must call the parent's + * version. + */ virtual void Done(); + /** + * Returns a textual description of the plugin. + * + * @param d Description object to use for rendering. If "short mode" + * is disabled, the rendering will include a list of all components + * and BiF items. + */ void Describe(ODesc* d); protected: typedef std::list > bif_init_func_result; typedef bif_init_func_result (*bif_init_func)(); + /** + * Sets the plugins name. + * + * @param name The name. Makes a copy internally. + */ void SetName(const char* name); + + /** + * Sets the plugin's textual description. + * + * @param name The description. Makes a copy internally. + */ void SetDescription(const char* descr); + + /** + * Sets the plugin's version. + * + * @param version The version. + */ void SetVersion(int version); + + /** + * Sets the API version the plugin requires. + * BRO_PLUGIN_VERSION_BUILTIN indicates that it's a plugin linked in + * statically. + */ void SetAPIVersion(int version); /** @@ -78,11 +205,12 @@ protected: void AddComponent(Component* c); /** - * 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 method that can be overriden by derived class to provide + * information about further script-level elements that the plugins + * provides on its own, i.e., outside of the standard mechanism + * processing *.bif files automatically. The returned information is + * for informational purpuses only and will show up in the result of + * BifItems() as well as in the Describe() output. */ virtual bif_item_list CustomBifItems() ;