// See the file "COPYING" in the main distribution directory for copyright. #pragma once #include #include #include #include #include #include "zeek/ZeekArgs.h" #include "zeek/logging/WriterBackend.h" // Avoid ccache busting of Plugin.h for internal plugins by // only including zeek/zeek-version.h if we're building an // external plugin. The define gets set in the CMakeLists.txt file // for the Zeek::Internal target, which only exists when // building Zeek itself. #ifndef ZEEK_PLUGIN_SKIP_VERSION_CHECK #include "zeek/zeek-version.h" #define ZEEK_PLUGIN_ZEEK_VERSION ZEEK_VERSION_FUNCTION #endif namespace zeek::threading { struct Field; } namespace zeek { #ifdef _MSC_VER #undef VOID #endif // Increase this when making incompatible changes to the plugin API. Note // that the constant is never used in C code. It's picked up on by CMake. constexpr int PLUGIN_API_VERSION = 7; class ODesc; class Event; class Func; class Obj; class Packet; template class IntrusivePtr; using ValPtr = IntrusivePtr; namespace threading { struct Field; } namespace detail { class Frame; } namespace cluster { class Backend; class Event; } // namespace cluster namespace plugin { class Manager; class Component; class Plugin; /** * Hook types that a plugin may define. Each label maps to the corresponding * virtual method in \a Plugin. */ enum HookType : uint8_t { // Note: when changing this table, update hook_name() in Plugin.cc. HOOK_LOAD_FILE, //< Activates Plugin::HookLoadFile(). HOOK_LOAD_FILE_EXT, //< Activates Plugin::HookLoadFileExtended(). HOOK_CALL_FUNCTION, //< Activates Plugin::HookCallFunction(). HOOK_QUEUE_EVENT, //< Activates Plugin::HookQueueEvent(). HOOK_DRAIN_EVENTS, //< Activates Plugin::HookDrainEvents(). HOOK_UPDATE_NETWORK_TIME, //< Activates Plugin::HookUpdateNetworkTime(). HOOK_SETUP_ANALYZER_TREE, //< Activates Plugin::HookAddToAnalyzerTree(). HOOK_LOG_INIT, //< Activates Plugin::HookLogInit(). HOOK_LOG_WRITE, //< Activates Plugin::HookLogWrite(). HOOK_REPORTER, //< Activates Plugin::HookReporter(). HOOK_UNPROCESSED_PACKET, //= 0 && minor >= 0 && patch >= 0; } }; /** * A class defining a plugin's static configuration parameters. */ class Configuration { public: std::string name = ""; //< The plugin's name, including a namespace. Mandatory. std::string description = ""; //< A short textual description of the plugin. Mandatory. VersionNumber version; //< THe plugin's version. Optional. // We force this to inline so that the API version gets hardcoded // into the external plugin. (Technically, it's not a "force", just a // strong hint.). The attribute seems generally available. inline Configuration() __attribute__((always_inline)) { // Only bake in a ZEEK_PLUGIN_ZEEK_VERSION reference into external plugins. The // internal ones are in the same binary so the runtime link check shouldn't be // needed and we can avoid ccache busting. The define gets set in the // CMakeLists.txt file for the Zeek::Internal target, which only exists when // building Zeek itself. #ifndef ZEEK_PLUGIN_SKIP_VERSION_CHECK zeek_version = ZEEK_PLUGIN_ZEEK_VERSION; #endif } Configuration(Configuration&& c) noexcept { zeek_version = std::move(c.zeek_version); name = std::move(c.name); description = std::move(c.description); version = c.version; } Configuration(const Configuration& c) { zeek_version = c.zeek_version; name = c.name; description = c.description; version = c.version; } Configuration& operator=(Configuration&& c) noexcept { zeek_version = std::move(c.zeek_version); name = std::move(c.name); description = std::move(c.description); version = c.version; return *this; } Configuration& operator=(const Configuration& c) { zeek_version = c.zeek_version; name = c.name; description = c.description; version = c.version; return *this; } ~Configuration() {} /** * One can assign ZEEK_PLUGIN_ZEEK_VERSION to this to catch * version mismatches at link(!) time. */ std::function zeek_version; private: friend class Plugin; }; /** * A class describing an item defined in \c *.bif file. */ class BifItem final { public: /** * Type of the item. */ enum Type : uint8_t { 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); /** * Assignment operator. */ BifItem& operator=(const BifItem& other); /** * Destructor. */ ~BifItem() = default; /** * Returns the script-level ID as passed into the constructor. */ const std::string& GetID() const { return id; } /** * Returns the type as passed into the constructor. */ Type GetType() const { return type; } private: std::string id; Type type; }; /** * A class encapsulating an event argument to then pass along with a meta hook. */ class HookArgument { public: /** * Type of the argument. */ enum Type : uint8_t { BOOL, DOUBLE, EVENT, FRAME, FUNC, FUNC_RESULT, INT, STRING, VAL, VAL_LIST, VOID, VOIDP, WRITER_INFO, CONN, THREAD_FIELDS, LOCATION, ARG_LIST, INPUT_FILE, PACKET, CLUSTER_BACKEND, CLUSTER_EVENT, }; /** * Default constructor initialized the argument with type VOID. */ HookArgument() { type = VOID; } /** * Constructor with a boolean argument. */ explicit HookArgument(bool a) { type = BOOL; arg.bool_ = a; } /** * Constructor with a double argument. */ explicit HookArgument(double a) { type = DOUBLE; arg.double_ = a; } /** * Constructor with an event argument. */ explicit HookArgument(const Event* a) { type = EVENT; arg.event = a; } /** * Constructor with an connection argument. */ explicit HookArgument(const Connection* c) { type = CONN; arg.conn = c; } /** * Constructor with a function argument. */ explicit HookArgument(const Func* a) { type = FUNC; arg.func = a; } /** * Constructor with an integer argument. */ explicit HookArgument(int a) { type = INT; arg.int_ = a; } /** * Constructor with a string argument. */ explicit HookArgument(const std::string& a) { type = STRING; arg_string = a; } /** * Constructor with a Zeek value argument. */ explicit HookArgument(const Val* a) { type = VAL; arg.val = a; } /** * Constructor with a list of Zeek values argument. */ explicit HookArgument(const ValPList* a) { type = VAL_LIST; arg.vals = a; } /** * Constructor with a void pointer argument. */ explicit HookArgument(void* p) { type = VOIDP; arg.voidp = p; } /** * Constructor with a function result argument. */ explicit HookArgument(std::pair fresult) { type = FUNC_RESULT; func_result = fresult; } /** * Constructor with a Frame argument. */ explicit HookArgument(zeek::detail::Frame* f) { type = FRAME; arg.frame = f; } /** * Constructor with a WriterInfo argument. */ explicit HookArgument(const logging::WriterBackend::WriterInfo* i) { type = WRITER_INFO; arg.winfo = i; } /** * Constructor with a threading field argument. */ explicit HookArgument(const std::pair fpair) { type = THREAD_FIELDS; tfields = fpair; } /** * Constructor with a location argument. */ explicit HookArgument(const zeek::detail::Location* location) { type = LOCATION; arg.loc = location; } /** * Constructor with a zeek::Args argument. */ explicit HookArgument(const Args* args) { type = ARG_LIST; arg.args = args; } /** * Constructor with HookLoadFileExtended result describing an input file. */ explicit HookArgument(std::pair> file) { type = INPUT_FILE; input_file = std::move(file); } /** * Returns the value for a zeek::Packet* argument. The argument's type must * Constructor with a zeek::Packet* argument. */ explicit HookArgument(const Packet* packet) { type = PACKET; arg.packet = packet; } /** * Constructor with cluster backend argument. */ explicit HookArgument(zeek::cluster::Backend* backend) { type = CLUSTER_BACKEND; arg.cluster_backend = backend; } /** * Constructor with cluster event argument. */ explicit HookArgument(zeek::cluster::Event* event) { type = CLUSTER_EVENT; arg.cluster_event = event; } /** * Returns the value for a boolean argument. The argument's type must * match accordingly. */ bool AsBool() const { assert(type == BOOL); return arg.bool_; } /** * Returns the value for a double argument. The argument's type must * match accordingly. */ double AsDouble() const { assert(type == DOUBLE); return arg.double_; } /** * Returns the value for an event argument. The argument's type must * match accordingly. */ const Event* AsEvent() const { assert(type == EVENT); return arg.event; } /** * Returns the value for an connection argument. The argument's type must * match accordingly. */ const Connection* AsConnection() const { assert(type == CONN); return arg.conn; } /** * Returns the value for a function argument. The argument's type must * match accordingly. */ const Func* AsFunc() const { assert(type == FUNC); return arg.func; } /** * Returns the value for an integer argument. The argument's type must * match accordingly. */ double AsInt() const { assert(type == INT); return arg.int_; } /** * Returns the value for a string argument. The argument's type must * match accordingly. */ const std::string& AsString() const { assert(type == STRING); return arg_string; } /** * Returns the value for a Zeek value argument. The argument's type must * match accordingly. */ const Val* AsVal() const { assert(type == VAL); return arg.val; } /** * Returns the value for a Zeek wrapped value argument. The argument's type must * match accordingly. */ const std::pair AsFuncResult() const { assert(type == FUNC_RESULT); return func_result; } /** * Returns the value for a Zeek frame argument. The argument's type must * match accordingly. */ const zeek::detail::Frame* AsFrame() const { assert(type == FRAME); return arg.frame; } /** * Returns the value for a logging WriterInfo argument. The argument's type must * match accordingly. */ const logging::WriterBackend::WriterInfo* AsWriterInfo() const { assert(type == WRITER_INFO); return arg.winfo; } /** * Returns the value for a threading fields argument. The argument's type must * match accordingly. */ const std::pair AsThreadFields() const { assert(type == THREAD_FIELDS); return tfields; } /** * Returns the value for a list of Zeek values argument. The argument's type must * match accordingly. */ const ValPList* AsValList() const { assert(type == VAL_LIST); return arg.vals; } /** * Returns the value as a Args. */ const Args* AsArgList() const { assert(type == ARG_LIST); return arg.args; } /** * Returns the value for a void pointer argument. The argument's type * must match accordingly. */ const void* AsVoidPtr() const { assert(type == VOIDP); return arg.voidp; } /** * Returns the value for a Packet pointer argument. The argument's type * must match accordingly. */ const Packet* AsPacket() const { assert(type == PACKET); return arg.packet; } /** * Returns the value for a cluster backend argument. */ const zeek::cluster::Backend* AsClusterBackend() const { assert(type == CLUSTER_EVENT); return arg.cluster_backend; } /** * Returns the value for a cluster event argument. */ const zeek::cluster::Event* AsClusterEvent() const { assert(type == CLUSTER_EVENT); return arg.cluster_event; } /** * Returns the argument's type. */ Type GetType() const { return type; } /** * Returns a textual representation of the argument. * * @param d Description object to use for rendering. */ void Describe(ODesc* d) const; private: Type type; union { bool bool_; double double_; const Event* event; const Connection* conn; const Func* func; const zeek::detail::Frame* frame; int int_; const Val* val; const ValPList* vals; const Args* args; const void* voidp; const logging::WriterBackend::WriterInfo* winfo; const zeek::detail::Location* loc; const Packet* packet; const cluster::Backend* cluster_backend; const cluster::Event* cluster_event; } arg; // Outside union because these have dtors. std::pair func_result; std::pair tfields; std::string arg_string; std::pair> input_file; }; using HookArgumentList = std::list; /** * Base class for all plugins. * * Plugins encapsulate functionality that extends one or more of Zeek's major * subsystems, such as analysis of a specific protocol, or logging output in * a particular format. A plugin acts a logical container that can provide a * set of functionality. Specifically, it may: * * - 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, an SQLite plugin could provide both a writer and reader * component. * * - Provide BiF elements (functions, events, types, globals). Typically * they'll be defined in *.bif files, but a plugin can also create them * internally. * * - Provide hooks (aka callbacks) into Zeek's core processing to inject * and/or alter functionality. * * A plugin needs to explicitly register all the functionality it provides. * For components, it needs to call AddComponent(); for BiFs AddBifItem(); * and for hooks EnableHook() and then also implement the corresponding * virtual methods. * */ class Plugin { public: using component_list = std::list; using bif_item_list = std::list; using hook_list = std::list>; /** * The different types of @loads supported by HookLoadFile. */ enum LoadType : uint8_t { SCRIPT, SIGNATURES, PLUGIN }; /** * Constructor. */ Plugin(); /** * Destructor. */ virtual ~Plugin(); /** * Returns the name of the plugin. */ const std::string& Name() const; /** * Returns a short textual description of the plugin, if provided. */ const std::string& Description() const; /** * Returns the version of the plugin. Versions are only meaningful * for dynamically compiled plugins; for statically compiled ones, * this will always return 0. */ VersionNumber Version() const; /** * Returns true if this is a dynamically linked plugin. */ bool DynamicPlugin() const; /** * For dynamic plugins, returns the base directory from which it was * loaded. For static plugins, returns an empty string. **/ const std::string& PluginDirectory() const; /** * For dynamic plugins, returns the full path to the shared library * from which it was loaded. For static plugins, returns an empty * string. **/ const std::string& PluginPath() const; /** * Returns a list of all components the plugin provides. */ component_list Components() const; /** * 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() const; /** * 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) const; /** * Registers an individual BiF that the plugin defines. The * information is for informational purposes only and will show up in * the result of BifItems() as well as in the Describe() output. * Another way to add this information is via overriding * CustomBifItems(). * * Note that this method is rarely the right one to use. As it's for * informational purposes only, the plugin still needs to register * the BiF items themselves with the corresponding Zeek parts. Doing * so can be tricky, and it's recommend to instead define BiF items * in separate *.bif files that the plugin then pulls in. If defined * there, one does *not* need to call this method. * * @param name The name of the BiF item. * * @param type The item's type. */ void AddBifItem(const std::string& name, BifItem::Type type); /** * Adds a file to the list of files that Zeek loads at startup. This * will normally be a Zeek script, but it passes through the plugin * system as well to load files with other extensions as supported by * any of the current plugins. In other words, calling this method is * similar to giving a file on the command line. Note that the file * may be only queued for now, and actually loaded later. * * This method must not be called after InitPostScript(). * * @param file The file to load. It will be searched along the * standard paths. * * @return True if successful (which however may only mean * "successfully queued"). */ bool LoadZeekFile(const std::string& file); protected: friend class Manager; /** * First-stage initialization of the plugin called early during Zeek'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 Zeek's * startup, after scripts are parsed. This can be overridden by * derived classes; they must however call the parent's * implementation. */ virtual void InitPostScript(); /** * Third-stage initialization of the plugin called just before enqueueing * zeek_init(), after script analysis and optimization completed. * This can be overridden by derived classes; they must however call the * parent's implementation. */ virtual void InitPreExecution(); /** * Finalizer method that derived classes can override for performing * custom tasks at shutdown. This can be overridden by derived * classes; they must however call the parent's implementation. */ virtual void Done(); /** * Registers a component. * * @param c The component. The method takes ownership. */ void AddComponent(Component* c); /** * Calls the Initialize() function of all components. */ void InitializeComponents(); /** * Enables a hook. The corresponding virtual method will now be * called as Zeek's processing proceeds. Note that enabling hooks can * have performance impact as many trigger frequently inside Zeek's * main processing path. * * Note that while hooks may be enabled/disabled dynamically at any * time, the output of Zeek's \c -NN option will only reflect their * state at startup time. Usually one should call this method for a * plugin's hooks in either the plugin's constructor or in * InitPreScript(). * * @param hook The hook to enable. * * @param priority If multiple plugins enable the same hook, their * priorities determine the order in which they'll be executed, from * highest to lowest. If two plugins specify the same priority, order * is undefined. */ void EnableHook(HookType hook, int priority = 0); /** * Disables a hook. Zeek will no longer call the corresponding virtual * method. * * @param hook The hook to disable. */ void DisableHook(HookType hook); /** * Returns a list of hooks that are currently enabled for the plugin, * along with their priorities. */ hook_list EnabledHooks() const; /** * Registers interest in an event, even if there's no handler for it. * Normally a plugin receives events through HookQueueEvent() only if Zeek * actually has code to execute for it. By calling this method, the * plugin tells Zeek to raise the event even if there's no corresponding * handler; it will then go into HookQueueEvent() just as any other. * * @param handler The event handler being interested in. */ void RequestEvent(EventHandlerPtr handler); /** * Registers interest in the destruction of a Obj instance. When * Zeek's reference counting triggers the objects destructor to run, * \a HookObjDtor will be called. * * Note that this can get expensive if triggered for many objects. * * @param obj The object being interested in. */ void RequestObjDtor(Obj* obj); // Hook functions. /** * Hook into loading input files. This method will be called between * InitPreScript() and InitPostScript(), but with no further order or * timing guaranteed. It will be called once for each input file Zeek * is about to load, either given on the command line or via @load * script directives. The hook can take over the file, in which case * Zeek will not further process it otherwise. * * @param type The type of load encountered: script load, signatures load, * or plugin load. * * @param file The filename that was passed to @load. Only includes * an extension if it was given in @load. * * @param resolved The file or directory name Zeek resolved from * the given path and is going to load. Empty string * if Zeek was not able to resolve a path. * * @return 1 if the plugin took over the file and loaded it * successfully; 0 if the plugin took over the file but had trouble * loading it (Zeek will abort in this case, and the plugin should * have printed an error message); and -1 if the plugin wasn't * interested in the file at all. */ virtual int HookLoadFile(const LoadType type, const std::string& file, const std::string& resolved); /** * Hook into loading input files, with extended capabilities. This method * will be called between InitPreScript() and InitPostScript(), but with no * further order or timing guaranteed. It will be called once for each * input file Zeek is about to load, either given on the command line or via * @load script directives. The hook can take over the file, in which case * Zeek will not further process it otherwise. It can, alternatively, also * provide the file content as a string, which Zeek will then process just * as if it had read it from a file. * * @param type The type of load encountered: script load, signatures load, * or plugin load. * * @param file The filename that was passed to @load. Only includes * an extension if it was given in @load. * * @param resolved The file or directory name Zeek resolved from * the given path and is going to load. Empty string * if Zeek was not able to resolve a path. * * @return tuple of an integer and an optional string, where: the integer * must be 1 if the plugin takes over loading the file (see below); 0 if * the plugin wanted to take over the file but had trouble loading it * (processing will abort in this case, and the plugin should have printed * an error message); and -1 if the plugin wants Zeek to proceed processing * the file normally. If the plugins takes over by returning 1, there are * two cases: if the second tuple element remains unset, the plugin handled * the loading completely internally; Zeek will not do anything further with * it. Alternatively, the plugin may optionally return the actual content * to use for the file as a string through the tuple's second element. If * so, Zeek will ignore the file on disk and use that provided content * instead (including when there's actually no physical file in place on * disk at all, and loading would have hence failed otherwise). */ virtual std::pair> HookLoadFileExtended(const LoadType type, const std::string& file, const std::string& resolved); /** * Hook into executing a script-level function/event/hook. Whenever * the script interpreter is about to execution a function, it first * gives all plugins with this hook enabled a chance to handle the * call (in the order of their priorities). A plugin can either just * inspect the call, or replace it (i.e., prevent the interpreter * from executing it). In the latter case it must provide a matching * return value. * * The default implementation never handles the call in any way. * * @param func The function being called. * * @param args The function arguments. The method can modify the list * in place as long as it ensures matching types and correct reference * counting. * * @return If the plugin handled the call, a pair with the first member * set to true, and a Val representing the result value to pass back to the * interpreter. If the plugin did not handle the call, it must return a * pair with the first member set to 'false' and null result value. */ virtual std::pair HookFunctionCall(const Func* func, zeek::detail::Frame* parent, Args* args); /** * Hook into raising events. Whenever the script interpreter is about * to queue an event for later execution, it first gives all plugins * with this hook enabled a chance to handle the queuing otherwise * (in the order of their priorities). A plugin can either just * inspect the event, or take it over (i.e., prevent the interpreter * from queuing it itself). * * The default implementation never handles the queuing in any way. * * @param event The event to be queued. The method can modify it in * place as long as it ensures matching types and correct reference * counting. * * @return True if the plugin took charge of the event; in that case * it must have assumed ownership of the event and the interpreter will * not do anything further with it. False otherwise. */ virtual bool HookQueueEvent(Event* event); /** * Hook into event queue draining. This method will be called * whenever the event manager is draining its queue. */ virtual void HookDrainEvents(); /** * Hook for updates to network time. This method will be called * whenever network time is advanced. * * @param network_time The new network time. */ virtual void HookUpdateNetworkTime(double network_time); /** * Hook that executes when a connection's initial analyzer tree * has been fully set up. The hook can manipulate the tree at this time, * for example by adding further analyzers. * * @param conn The connection. */ virtual void HookSetupAnalyzerTree(Connection* conn); /** * Hook for destruction of objects registered with * RequestObjDtor(). When Zeek's reference counting triggers the * objects destructor to run, this method will be run. It may also * run for other objects that this plugin has not registered for. * * @param obj A pointer to the object being destroyed. Note that the * object is already considered invalid and the pointer must not be * dereferenced. */ virtual void HookObjDtor(void* obj); /** * Hook into log initialization. This method will be called when a * logging writer is created. A writer represents a single logging * filter. The method is called in the main thread, on the node that * causes a log line to be written. It will _not_ be called on the logger * node. The function will be called each for every instantiated writer. * * @param writer The name of the writer being instantiated. * * @param instantiating_filter Name of the filter causing the * writer instantiation. * * @param local True if the filter is logging locally (writer * thread will be located in same process). * * @param remote True if filter is logging remotely (writer thread * will be located in different thread, typically * in manager or logger node). * * @param info WriterBackend::WriterInfo with information about the writer. * * @param num_fields number of fields in the record being written. * * @param fields threading::Field description of the fields being logged. */ virtual void HookLogInit(const std::string& writer, const std::string& instantiating_filter, bool local, bool remote, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields); /** * Hook into log writing. This method will be called for each log line * being written by each writer. Each writer represents a single logging * filter. The method is called in the main thread, on the node that * causes a log line to be written. It will _not_ be called on the logger * node. * This function allows plugins to modify or skip logging of information. * Note - once a log line is skipped (by returning false), it will not * passed on to hooks that have not yet been called. * * @param writer The name of the writer. * * @param filter Name of the filter being written to. * * @param info WriterBackend::WriterInfo with information about the writer. * * @param num_fields number of fields in the record being written. * * @param fields threading::Field description of the fields being logged. * * @param vals threading::Values containing the values being written. Values * can be modified in the Hook. * * @return true if log line should be written, false if log line should be * skipped and not passed on to the writer. */ virtual bool HookLogWrite(const std::string& writer, const std::string& filter, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields, threading::Value** vals); /** * Hook into reporting. This method will be called for each reporter call * made; this includes weirds. The method cannot manipulate the data at * the current time; however it is possible to prevent script-side events * from being called by returning false. * * @param prefix The prefix passed by the reporter framework * * @param event The event to be called * * @param conn The associated connection * * @param addl Additional Zeek values; typically will be passed to the event * by the reporter framework. * * @param location True if event expects location information * * @param location1 First location * * @param location2 Second location * * @param time True if event expects time information * * @param message Message supplied by the reporter framework * * @return true if event should be called by the reporter framework, false * if the event call should be skipped */ virtual bool HookReporter(const std::string& prefix, const EventHandlerPtr event, const Connection* conn, const ValPList* addl, bool location, const zeek::detail::Location* location1, const zeek::detail::Location* location2, bool time, const std::string& message); /** * Hook for packets that are considered unprocessed by an Analyzer. This * typically means that a packet has not had a log entry written for it by * the time analysis finishes. * * @param packet The data for an unprocessed packet */ virtual void HookUnprocessedPacket(const Packet* packet); /** * Hook for intercepting remote event publish operations. * * This hook is invoked when Cluster::publish(), Cluster::publish_hrw() or * Cluster::publish_rr() is used in the scripting layer to publish a remote * event to a topic. It is also invoked when calling PublishEvent() on the * active cluster backend directly from C++ plugins. This hook can be used * for metrics collection, modifying or redirecting events to a different * topic. It's event possible to translate an event to another one. A plugin * should return false if it took responsibility of publishing the event, or * the verdict is to skip the publish operation. * * @param backend The backend publishing this event * @param topic The topic to which to publish this event * @param event The event itself * * @return true if event should be published, false if the publish * operation should be skipped. */ virtual bool HookPublishEvent(zeek::cluster::Backend& backend, const std::string& topic, zeek::cluster::Event& event); // Meta hooks. virtual void MetaHookPre(HookType hook, const HookArgumentList& args); virtual void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result); private: /** * A function called when the plugin is instantiated to query basic * configuration parameters. * * The plugin must override this method and return a suitably * initialized configuration object. * * @return A configuration describing the plugin. */ virtual Configuration Configure() = 0; /** * Initializes the plugin's internal configuration. Called by the * manager before anything else. */ void DoConfigure(); /** * Sets the base directory and shared library path from which the * plugin was loaded. * * This is called by the manager. * * @param dir The plugin directory. The functions makes an internal * copy of string. * * @param sopath The full path the shared library loaded. The * functions makes an internal copy of string. */ void SetPluginLocation(const std::string& dir, const std::string& sopath); /** * Marks the plugin as dynamically loaded. * * This is called by the manager. * * @param is_dynamic True if it's a dynamically loaded module. */ void SetDynamic(bool is_dynamic); Configuration config; std::string base_dir; // The plugin's base directory. std::string sopath; // For dynamic plugins, the full path to the shared library. bool dynamic; // True if a dynamic plugin. component_list components; // Components the plugin provides. bif_item_list bif_items; // BiF items the plugin provides. }; } // namespace plugin } // namespace zeek