mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 08:38:20 +00:00
Merge remote-tracking branch 'origin/master' into topic/robin/pktsrc
Conflicts: configure src/CMakeLists.txt src/Net.cc src/PacketSort.cc src/PacketSort.h src/RemoteSerializer.cc src/Sessions.cc src/Sessions.h
This commit is contained in:
commit
bf6dd2e9ca
794 changed files with 119018 additions and 91558 deletions
|
@ -11,6 +11,7 @@ Component::Component(component::Type arg_type, const std::string& arg_name)
|
|||
{
|
||||
type = arg_type;
|
||||
name = arg_name;
|
||||
canon_name = canonify_name(name);
|
||||
}
|
||||
|
||||
Component::~Component()
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace component {
|
|||
*/
|
||||
enum Type {
|
||||
READER, /// An input reader (not currently used).
|
||||
WRITER, /// An logging writer (not currenly used).
|
||||
WRITER, /// A logging writer (not currenly used).
|
||||
ANALYZER, /// A protocol analyzer.
|
||||
FILE_ANALYZER, /// A file analyzer.
|
||||
IOSOURCE, /// An I/O source, excluding packet sources.
|
||||
|
@ -58,21 +58,30 @@ public:
|
|||
*/
|
||||
const std::string& Name() const;
|
||||
|
||||
/**
|
||||
* Returns a canonocalized version of the components's name. The
|
||||
* returned name is derived from what's passed to the constructor but
|
||||
* upper-cased and transformed to allow being part of a script-level
|
||||
* ID.
|
||||
*/
|
||||
const std::string& CanonicalName() const { return canon_name; }
|
||||
|
||||
/**
|
||||
* Returns a textual representation of the component. This goes into
|
||||
* the output of "bro -NN".
|
||||
*
|
||||
* By default version, this just outputs the type and the name.
|
||||
* Derived versions should override DoDescribe() to add type specific
|
||||
* details.
|
||||
* By default, this just outputs the type and the name. Derived
|
||||
* versions can override DoDescribe() to add type specific details.
|
||||
*
|
||||
* @param d The description object to use.
|
||||
*/
|
||||
virtual void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Adds type specific information to the outout of Describe().
|
||||
* Adds type specific information to the output of Describe().
|
||||
*
|
||||
* The default version does nothing.
|
||||
*
|
||||
* @param d The description object to use.
|
||||
*/
|
||||
|
@ -85,6 +94,7 @@ private:
|
|||
|
||||
component::Type type;
|
||||
std::string name;
|
||||
std::string canon_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -27,13 +27,16 @@ class ComponentManager {
|
|||
public:
|
||||
|
||||
/**
|
||||
* Constructor creates a new enum type called a "Tag" to associate with
|
||||
* Constructor creates a new enum type to associate with
|
||||
* a component.
|
||||
*
|
||||
* @param module The script-layer module in which to install the "Tag" ID
|
||||
* @param module The script-layer module in which to install the ID
|
||||
* representing an enum type.
|
||||
*
|
||||
* @param local_id The local part of the ID of the new enum type
|
||||
* (e.g., "Tag").
|
||||
*/
|
||||
ComponentManager(const string& module);
|
||||
ComponentManager(const string& module, const string& local_id);
|
||||
|
||||
/**
|
||||
* @return The script-layer module in which the component's "Tag" ID lives.
|
||||
|
@ -117,7 +120,6 @@ public:
|
|||
C* Lookup(EnumVal* val) const;
|
||||
|
||||
private:
|
||||
|
||||
string module; /**< Script layer module in which component tags live. */
|
||||
EnumType* tag_enum_type; /**< Enum type of component tags. */
|
||||
map<string, C*> components_by_name;
|
||||
|
@ -126,11 +128,11 @@ private:
|
|||
};
|
||||
|
||||
template <class T, class C>
|
||||
ComponentManager<T, C>::ComponentManager(const string& arg_module)
|
||||
ComponentManager<T, C>::ComponentManager(const string& arg_module, const string& local_id)
|
||||
: module(arg_module)
|
||||
{
|
||||
tag_enum_type = new EnumType();
|
||||
::ID* id = install_ID("Tag", module.c_str(), true, true);
|
||||
tag_enum_type = new EnumType(module + "::" + local_id);
|
||||
::ID* id = install_ID(local_id.c_str(), module.c_str(), true, true);
|
||||
add_type(id, tag_enum_type, 0);
|
||||
broxygen_mgr->Identifier(id);
|
||||
}
|
||||
|
@ -162,7 +164,7 @@ EnumType* ComponentManager<T, C>::GetTagEnumType() const
|
|||
template <class T, class C>
|
||||
const std::string& ComponentManager<T, C>::GetComponentName(T tag) const
|
||||
{
|
||||
static const std::string& error = "<error>";
|
||||
static const std::string error = "<error>";
|
||||
|
||||
if ( ! tag )
|
||||
return error;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
using namespace plugin;
|
||||
|
||||
Plugin* Manager::current_plugin = 0;
|
||||
string Manager::current_dir;
|
||||
string Manager::current_sopath;
|
||||
const char* Manager::current_dir = 0;
|
||||
const char* Manager::current_sopath = 0;
|
||||
|
||||
Manager::Manager()
|
||||
{
|
||||
|
@ -133,16 +133,23 @@ void Manager::SearchDynamicPlugins(const std::string& dir)
|
|||
closedir(d);
|
||||
}
|
||||
|
||||
bool Manager::ActivateDynamicPluginInternal(const std::string& name)
|
||||
bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found)
|
||||
{
|
||||
dynamic_plugin_map::iterator m = dynamic_plugins.find(name);
|
||||
|
||||
if ( m == dynamic_plugins.end() )
|
||||
{
|
||||
if ( ok_if_not_found )
|
||||
return true;
|
||||
|
||||
reporter->Error("plugin %s is not available", name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( m->second == "" )
|
||||
// Already activated.
|
||||
return true;
|
||||
|
||||
std::string dir = m->second + "/";
|
||||
|
||||
if ( dir.empty() )
|
||||
|
@ -196,7 +203,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name)
|
|||
const char* path = gl.gl_pathv[i];
|
||||
|
||||
current_plugin = 0;
|
||||
current_dir = dir;
|
||||
current_dir = dir.c_str();
|
||||
current_sopath = path;
|
||||
void* hdl = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
|
||||
|
||||
|
@ -212,6 +219,10 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name)
|
|||
current_plugin->SetDynamic(true);
|
||||
current_plugin->DoConfigure();
|
||||
|
||||
if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION )
|
||||
reporter->FatalError("plugin's API version does not match Bro (expected %d, got %d in %s)",
|
||||
BRO_PLUGIN_API_VERSION, current_plugin->APIVersion(), path);
|
||||
|
||||
// We execute the pre-script initialization here; this in
|
||||
// fact could be *during* script initialization if we got
|
||||
// triggered via @load-plugin.
|
||||
|
@ -223,8 +234,8 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name)
|
|||
reporter->FatalError("inconsistent plugin name: %s vs %s",
|
||||
current_plugin->Name().c_str(), name.c_str());
|
||||
|
||||
current_dir.clear();
|
||||
current_sopath.clear();
|
||||
current_dir = 0;
|
||||
current_sopath = 0;
|
||||
current_plugin = 0;
|
||||
|
||||
DBG_LOG(DBG_PLUGINS, " Loaded %s", path);
|
||||
|
@ -251,13 +262,23 @@ bool Manager::ActivateDynamicPlugin(const std::string& name)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Manager::ActivateAllDynamicPlugins()
|
||||
bool Manager::ActivateDynamicPlugins(bool all)
|
||||
{
|
||||
for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin();
|
||||
i != dynamic_plugins.end(); i++ )
|
||||
// Activate plugins that our environment tells us to.
|
||||
vector<string> p;
|
||||
tokenize_string(bro_plugin_activate(), ",", &p);
|
||||
|
||||
for ( size_t n = 0; n < p.size(); ++n )
|
||||
ActivateDynamicPluginInternal(p[n], true);
|
||||
|
||||
if ( all )
|
||||
{
|
||||
if ( ! ActivateDynamicPluginInternal(i->first) )
|
||||
return false;
|
||||
for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin();
|
||||
i != dynamic_plugins.end(); i++ )
|
||||
{
|
||||
if ( ! ActivateDynamicPluginInternal(i->first) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateInputFiles();
|
||||
|
@ -270,6 +291,8 @@ void Manager::UpdateInputFiles()
|
|||
for ( file_list::const_reverse_iterator i = scripts_to_load.rbegin();
|
||||
i != scripts_to_load.rend(); i++ )
|
||||
add_input_file_at_front((*i).c_str());
|
||||
|
||||
scripts_to_load.clear();
|
||||
}
|
||||
|
||||
static bool plugin_cmp(const Plugin* a, const Plugin* b)
|
||||
|
@ -279,14 +302,14 @@ static bool plugin_cmp(const Plugin* a, const Plugin* b)
|
|||
|
||||
void Manager::RegisterPlugin(Plugin *plugin)
|
||||
{
|
||||
Manager::PluginsInternal()->push_back(plugin);
|
||||
Manager::ActivePluginsInternal()->push_back(plugin);
|
||||
|
||||
if ( current_dir.size() && current_sopath.size() )
|
||||
if ( current_dir && current_sopath )
|
||||
// A dynamic plugin, record its location.
|
||||
plugin->SetPluginLocation(current_dir.c_str(), current_sopath.c_str());
|
||||
plugin->SetPluginLocation(current_dir, current_sopath);
|
||||
|
||||
// Sort plugins by name to make sure we have a deterministic order.
|
||||
PluginsInternal()->sort(plugin_cmp);
|
||||
ActivePluginsInternal()->sort(plugin_cmp);
|
||||
|
||||
current_plugin = plugin;
|
||||
}
|
||||
|
@ -307,7 +330,8 @@ void Manager::InitPreScript()
|
|||
{
|
||||
assert(! init);
|
||||
|
||||
for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ )
|
||||
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
|
||||
i != Manager::ActivePluginsInternal()->end(); i++ )
|
||||
{
|
||||
Plugin* plugin = *i;
|
||||
plugin->DoConfigure();
|
||||
|
@ -321,7 +345,8 @@ void Manager::InitBifs()
|
|||
{
|
||||
bif_init_func_map* bifs = BifFilesInternal();
|
||||
|
||||
for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ )
|
||||
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
|
||||
i != Manager::ActivePluginsInternal()->end(); i++ )
|
||||
{
|
||||
bif_init_func_map::const_iterator b = bifs->find((*i)->Name());
|
||||
|
||||
|
@ -337,7 +362,8 @@ void Manager::InitPostScript()
|
|||
{
|
||||
assert(init);
|
||||
|
||||
for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ )
|
||||
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
|
||||
i != Manager::ActivePluginsInternal()->end(); i++ )
|
||||
(*i)->InitPostScript();
|
||||
}
|
||||
|
||||
|
@ -345,23 +371,47 @@ void Manager::FinishPlugins()
|
|||
{
|
||||
assert(init);
|
||||
|
||||
for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ )
|
||||
{
|
||||
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
|
||||
i != Manager::ActivePluginsInternal()->end(); i++ )
|
||||
(*i)->Done();
|
||||
// delete *i;
|
||||
}
|
||||
|
||||
Manager::PluginsInternal()->clear();
|
||||
Manager::ActivePluginsInternal()->clear();
|
||||
|
||||
init = false;
|
||||
}
|
||||
|
||||
Manager::plugin_list Manager::Plugins() const
|
||||
Manager::plugin_list Manager::ActivePlugins() const
|
||||
{
|
||||
return *Manager::PluginsInternal();
|
||||
return *Manager::ActivePluginsInternal();
|
||||
}
|
||||
|
||||
Manager::plugin_list* Manager::PluginsInternal()
|
||||
Manager::inactive_plugin_list Manager::InactivePlugins() const
|
||||
{
|
||||
plugin_list* all = ActivePluginsInternal();
|
||||
|
||||
inactive_plugin_list inactives;
|
||||
|
||||
for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin(); i != dynamic_plugins.end(); i++ )
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
for ( plugin_list::const_iterator j = all->begin(); j != all->end(); j++ )
|
||||
{
|
||||
if ( (*i).first == (*j)->Name() )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! found )
|
||||
inactives.push_back(*i);
|
||||
}
|
||||
|
||||
return inactives;
|
||||
}
|
||||
|
||||
Manager::plugin_list* Manager::ActivePluginsInternal()
|
||||
{
|
||||
static plugin_list* plugins = 0;
|
||||
|
||||
|
@ -416,8 +466,17 @@ void Manager::EnableHook(HookType hook, Plugin* plugin, int prio)
|
|||
if ( ! hooks[hook] )
|
||||
hooks[hook] = new hook_list;
|
||||
|
||||
hooks[hook]->push_back(std::make_pair(prio, plugin));
|
||||
hooks[hook]->sort(hook_cmp);
|
||||
hook_list* l = hooks[hook];
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); i++ )
|
||||
{
|
||||
// Already enabled for this plugin.
|
||||
if ( (*i).second == plugin )
|
||||
return;
|
||||
}
|
||||
|
||||
l->push_back(std::make_pair(prio, plugin));
|
||||
l->sort(hook_cmp);
|
||||
}
|
||||
|
||||
void Manager::DisableHook(HookType hook, Plugin* plugin)
|
||||
|
@ -443,6 +502,18 @@ void Manager::DisableHook(HookType hook, Plugin* plugin)
|
|||
}
|
||||
}
|
||||
|
||||
void Manager::RequestEvent(EventHandlerPtr handler, Plugin* plugin)
|
||||
{
|
||||
DBG_LOG(DBG_PLUGINS, "Plugin %s requested event %s",
|
||||
plugin->Name().c_str(), handler->Name());
|
||||
handler->SetGenerateAlways();
|
||||
}
|
||||
|
||||
void Manager::RequestBroObjDtor(BroObj* obj, Plugin* plugin)
|
||||
{
|
||||
obj->NotifyPluginsOnDtor();
|
||||
}
|
||||
|
||||
int Manager::HookLoadFile(const string& file)
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
@ -455,17 +526,32 @@ int Manager::HookLoadFile(const string& file)
|
|||
|
||||
hook_list* l = hooks[HOOK_LOAD_FILE];
|
||||
|
||||
size_t i = file.find_last_of("./");
|
||||
|
||||
string ext;
|
||||
string normalized_file = file;
|
||||
|
||||
if ( i != string::npos && file[i] == '.' )
|
||||
ext = file.substr(i + 1);
|
||||
else
|
||||
{
|
||||
// Add .bro as default extension.
|
||||
normalized_file = file + ".bro";
|
||||
ext = "bro";
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
int rc = p->HookLoadFile(file);
|
||||
rc = p->HookLoadFile(normalized_file, ext);
|
||||
|
||||
if ( rc >= 0 )
|
||||
break;
|
||||
}
|
||||
if ( rc >= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_LOAD_FILE, args, HookArgument(rc));
|
||||
|
@ -488,15 +574,16 @@ Val* Manager::HookCallFunction(const Func* func, val_list* vargs) const
|
|||
|
||||
Val* v = 0;
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
v = p->HookCallFunction(func, vargs);
|
||||
v = p->HookCallFunction(func, vargs);
|
||||
|
||||
if ( v )
|
||||
break;
|
||||
}
|
||||
if ( v )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_CALL_FUNCTION, args, HookArgument(v));
|
||||
|
@ -518,16 +605,17 @@ bool Manager::HookQueueEvent(Event* event) const
|
|||
|
||||
bool result = false;
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
if ( p->HookQueueEvent(event) )
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
if ( p->HookQueueEvent(event) )
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_QUEUE_EVENT, args, HookArgument(result));
|
||||
|
@ -544,11 +632,12 @@ void Manager::HookDrainEvents() const
|
|||
|
||||
hook_list* l = hooks[HOOK_DRAIN_EVENTS];
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookDrainEvents();
|
||||
}
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookDrainEvents();
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_DRAIN_EVENTS, args, HookArgument());
|
||||
|
@ -567,34 +656,60 @@ void Manager::HookUpdateNetworkTime(double network_time) const
|
|||
|
||||
hook_list* l = hooks[HOOK_UPDATE_NETWORK_TIME];
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookUpdateNetworkTime(network_time);
|
||||
}
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookUpdateNetworkTime(network_time);
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_UPDATE_NETWORK_TIME, args, HookArgument());
|
||||
}
|
||||
|
||||
void Manager::HookBroObjDtor(void* obj) const
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(obj);
|
||||
MetaHookPre(HOOK_BRO_OBJ_DTOR, args);
|
||||
}
|
||||
|
||||
hook_list* l = hooks[HOOK_BRO_OBJ_DTOR];
|
||||
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookBroObjDtor(obj);
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_BRO_OBJ_DTOR, args, HookArgument());
|
||||
}
|
||||
|
||||
void Manager::MetaHookPre(HookType hook, const HookArgumentList& args) const
|
||||
{
|
||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->MetaHookPre(hook, args);
|
||||
}
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->MetaHookPre(hook, args);
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) const
|
||||
{
|
||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->MetaHookPost(hook, args, result);
|
||||
}
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->MetaHookPost(hook, args, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,14 +12,31 @@
|
|||
|
||||
namespace plugin {
|
||||
|
||||
// Macros that trigger a plugin hook. We put this into macros to short-cut
|
||||
// the code for the most common case that no plugin defines the hook.
|
||||
#define PLUGIN_HOOK_WITH_RESULT(hook, method_call, default_result) \
|
||||
(plugin_mgr->HavePluginForHook(plugin::hook) ? plugin_mgr->method_call : (default_result))
|
||||
// Macros that trigger plugin hooks. We put this into macros to short-cut the
|
||||
// code for the most common case that no plugin defines the hook.
|
||||
|
||||
/**
|
||||
* Macro to trigger hooks without result.
|
||||
*
|
||||
* @param hook The \a plugin::HookType constant corresponding to the hook to trigger.
|
||||
*
|
||||
* @param method_call The \a Manager method corresponding to the hook.
|
||||
*/
|
||||
#define PLUGIN_HOOK_VOID(hook, method_call) \
|
||||
if ( plugin_mgr->HavePluginForHook(plugin::hook) ) plugin_mgr->method_call;
|
||||
{ if ( plugin_mgr->HavePluginForHook(plugin::hook) ) plugin_mgr->method_call; }
|
||||
|
||||
/**
|
||||
* Macro to trigger hooks that return a result.
|
||||
*
|
||||
* @param hook The \a plugin::HookType constant corresponding to the hook to trigger.
|
||||
*
|
||||
* @param method_call The \a Manager method corresponding to the hook.
|
||||
*
|
||||
* @param default_result: The result to use if there's no plugin implementing
|
||||
* the hook.
|
||||
*/
|
||||
#define PLUGIN_HOOK_WITH_RESULT(hook, method_call, default_result) \
|
||||
(plugin_mgr->HavePluginForHook(::plugin::hook) ? plugin_mgr->method_call : (default_result))
|
||||
|
||||
/**
|
||||
* A singleton object managing all plugins.
|
||||
|
@ -30,6 +47,7 @@ public:
|
|||
typedef void (*bif_init_func)(Plugin *);
|
||||
typedef std::list<Plugin*> plugin_list;
|
||||
typedef Plugin::component_list component_list;
|
||||
typedef std::list<std::pair<std::string, std::string> > inactive_plugin_list;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -42,24 +60,24 @@ public:
|
|||
virtual ~Manager();
|
||||
|
||||
/**
|
||||
* Searches a set of directories for plugins. If a specificed
|
||||
* directory does not contain a plugin itself, the method searches
|
||||
* for plugins recursively. For plugins found, the method makes them
|
||||
* available for later activation via ActivatePlugin().
|
||||
* Searches a set of directories for plugins. If a specified directory
|
||||
* does not contain a plugin itself, the method searches for plugins
|
||||
* recursively. For plugins found, the method makes them available for
|
||||
* later activation via ActivatePlugin().
|
||||
*
|
||||
* This must be called only before InitPluginsPreScript().
|
||||
*
|
||||
* @param dir The directory to search for plugins. Multiple
|
||||
* directories are split by ':'.
|
||||
* @param dir The directory to search for plugins. Multiple directories
|
||||
* can be given by splitting them with ':'.
|
||||
*/
|
||||
void SearchDynamicPlugins(const std::string& dir);
|
||||
|
||||
/**
|
||||
* Activates a plugin that SearchPlugins() has previously discovered.
|
||||
* Activing a plugin involved loading its dynamic module, making its
|
||||
* Activates a plugin that SearchDynamicPlugins() has previously discovered.
|
||||
* Activating a plugin involves loading its dynamic module, making its
|
||||
* bifs available, and adding its script paths to BROPATH.
|
||||
*
|
||||
* @param name The name of the plugin, as determined previously by
|
||||
* @param name The name of the plugin, as found previously by
|
||||
* SearchPlugin().
|
||||
*
|
||||
* @return True if the plugin has been loaded successfully.
|
||||
|
@ -68,15 +86,19 @@ public:
|
|||
bool ActivateDynamicPlugin(const std::string& name);
|
||||
|
||||
/**
|
||||
* Activates all plugins that SearchPlugins() has previously
|
||||
* discovered. The effect is the same all calling \a
|
||||
* ActivePlugin(name) for every plugin.
|
||||
* Activates plugins that SearchDynamicPlugins() has previously discovered.
|
||||
* The effect is the same all calling \a ActivePlugin(name) for each plugin.
|
||||
*
|
||||
* @param all If true, activates all plugins that are found. If false,
|
||||
* activates only those that should always be activated unconditionally,
|
||||
* as specified via the BRO_PLUGIN_ACTIVATE enviroment variable. In other
|
||||
* words, it's \c true in standard mode and \c false in bare mode.
|
||||
*
|
||||
* @return True if all plugins have been loaded successfully. If one
|
||||
* fail to load, the method stops there without loading any furthers
|
||||
* fails to load, the method stops there without loading any further ones
|
||||
* and returns false.
|
||||
*/
|
||||
bool ActivateAllDynamicPlugins();
|
||||
bool ActivateDynamicPlugins(bool all);
|
||||
|
||||
/**
|
||||
* First-stage initializion of the manager. This is called early on
|
||||
|
@ -86,30 +108,38 @@ public:
|
|||
void InitPreScript();
|
||||
|
||||
/**
|
||||
* Second-stage initialization of the manager. This is called in
|
||||
* between pre- and post-script to make BiFs available.
|
||||
* Second-stage initialization of the manager. This is called in between
|
||||
* pre- and post-script to make BiFs available.
|
||||
*/
|
||||
void InitBifs();
|
||||
|
||||
/**
|
||||
* Third-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.
|
||||
* Third-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 InitPostScript();
|
||||
|
||||
/**
|
||||
* Finalizes all plugins at termination time. This forwards to the
|
||||
* corresponding Plugin methods.
|
||||
* corresponding Plugin \a Done() 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.
|
||||
* Returns a list of all available activated plugins. This includes all
|
||||
* that are compiled in statically, as well as those loaded dynamically
|
||||
* so far.
|
||||
*/
|
||||
plugin_list Plugins() const;
|
||||
plugin_list ActivePlugins() const;
|
||||
|
||||
/**
|
||||
* Returns a list of all dynamic plugins that have been found, yet not
|
||||
* activated. The returned list contains pairs of plugin name and base
|
||||
* directory. Note that because they aren't activated, that's all
|
||||
* information we have access to.
|
||||
*/
|
||||
inactive_plugin_list InactivePlugins() const;
|
||||
|
||||
/**
|
||||
* Returns a list of all available components, in any plugin, that
|
||||
|
@ -128,7 +158,7 @@ public:
|
|||
*/
|
||||
bool HavePluginForHook(HookType hook) const
|
||||
{
|
||||
// Inline to make avoid the function call.
|
||||
// Inline to avoid the function call.
|
||||
return hooks[hook] != 0;
|
||||
}
|
||||
|
||||
|
@ -160,19 +190,44 @@ public:
|
|||
*/
|
||||
void DisableHook(HookType hook, Plugin* plugin);
|
||||
|
||||
/**
|
||||
* Registers interest in an event by a plugin, even if there's no handler
|
||||
* for it. Normally a plugin receives events through HookQueueEvent()
|
||||
* only if Bro actually has code to execute for it. By calling this
|
||||
* method, the plugin tells Bro to raise the event even if there's no
|
||||
* correspondong handler; it will then go into HookQueueEvent() just as
|
||||
* any other.
|
||||
*
|
||||
* @param handler The event being interested in.
|
||||
*
|
||||
* @param plugin The plugin expressing interest.
|
||||
*/
|
||||
void RequestEvent(EventHandlerPtr handler, Plugin* plugin);
|
||||
|
||||
/**
|
||||
* Register interest in the destruction of a BroObj instance. When Bro's
|
||||
* reference counting triggers the objects destructor to run, the \a
|
||||
* HookBroObjDtor will be called.
|
||||
*
|
||||
* @param handler The object being interested in.
|
||||
*
|
||||
* @param plugin The plugin expressing interest.
|
||||
*/
|
||||
void RequestBroObjDtor(BroObj* obj, Plugin* plugin);
|
||||
|
||||
// Hook entry functions.
|
||||
|
||||
/**
|
||||
* Hook that gives plugins a chance to take over loading an input
|
||||
* input file. This method must be called between InitPreScript() and
|
||||
* file. This method must be called between InitPreScript() and
|
||||
* InitPostScript() for each input file Bro 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 Bro must not further process
|
||||
* it otherwise.
|
||||
* given on the command line or via @load script directives. The hook can
|
||||
* take over the file, in which case Bro must not further process it
|
||||
* otherwise.
|
||||
*
|
||||
* @return 1 if a plugin took over the file and loaded it
|
||||
* successfully; 0 if a plugin took over the file but had trouble
|
||||
* loading it; and -1 if no plugin was interested in the file at all.
|
||||
* @return 1 if a plugin took over the file and loaded it successfully; 0
|
||||
* if a plugin took over the file but had trouble loading it; and -1 if
|
||||
* no plugin was interested in the file at all.
|
||||
*/
|
||||
virtual int HookLoadFile(const string& file);
|
||||
|
||||
|
@ -181,12 +236,13 @@ public:
|
|||
*
|
||||
* @param func The function to be called.
|
||||
*
|
||||
* @param args The function call's arguments; they may be modified.
|
||||
* @param args The function call's arguments; they may be modified by the
|
||||
* method.
|
||||
*
|
||||
* @return If a plugin handled the call, a +1 Val with the result
|
||||
* value to pass back to the interpreter (for void functions and
|
||||
* events, it may be any Val and must be ignored). If no plugin
|
||||
* handled the call, the method returns null.
|
||||
* @return If a plugin handled the call, a Val with a +1 reference count
|
||||
* containing the result value to pass back to the interpreter (for void
|
||||
* functions and events, it may be any Val and must be ignored). If no
|
||||
* plugin handled the call, the method returns null.
|
||||
*/
|
||||
Val* HookCallFunction(const Func* func, val_list* args) const;
|
||||
|
||||
|
@ -208,10 +264,16 @@ public:
|
|||
void HookUpdateNetworkTime(double network_time) const;
|
||||
|
||||
/**
|
||||
* Hooks that informs plugins that the event queue is being drained.
|
||||
* Hook that informs plugins that the event queue is being drained.
|
||||
*/
|
||||
void HookDrainEvents() const;
|
||||
|
||||
/**
|
||||
* Hook that informs plugins that an BroObj is being destroyed. Will be
|
||||
* called only for objects that a plugin has expressed interest in.
|
||||
*/
|
||||
void HookBroObjDtor(void* obj) const;
|
||||
|
||||
/**
|
||||
* Internal method that registers a freshly instantiated plugin with
|
||||
* the manager.
|
||||
|
@ -223,12 +285,17 @@ public:
|
|||
static void RegisterPlugin(Plugin* plugin);
|
||||
|
||||
/**
|
||||
* Internal method that registers a bif file's init function for a plugin.
|
||||
* Internal method that registers a bif file's init function for a
|
||||
* plugin.
|
||||
*
|
||||
* @param plugin The plugin to register the function for.
|
||||
*
|
||||
* @param c The init function to register.
|
||||
*/
|
||||
static void RegisterBifFile(const char* plugin, bif_init_func c);
|
||||
|
||||
private:
|
||||
bool ActivateDynamicPluginInternal(const std::string& name);
|
||||
bool ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found = false);
|
||||
void UpdateInputFiles();
|
||||
void MetaHookPre(HookType hook, const HookArgumentList& args) const;
|
||||
void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) const;
|
||||
|
@ -237,12 +304,12 @@ private:
|
|||
typedef std::map<std::string, std::string> dynamic_plugin_map;
|
||||
dynamic_plugin_map dynamic_plugins;
|
||||
|
||||
// We buffer scripts to load temporarliy to get them to load in the
|
||||
// We temporarliy buffer scripts to load to get them to load in the
|
||||
// right order.
|
||||
typedef std::list<std::string> file_list;
|
||||
file_list scripts_to_load;
|
||||
|
||||
bool init;
|
||||
bool init; // Flag indicating whether InitPreScript() has run yet.
|
||||
|
||||
// A hook list keeps pairs of plugin and priority interested in a
|
||||
// given hook.
|
||||
|
@ -252,14 +319,15 @@ private:
|
|||
// of that type enabled.
|
||||
hook_list** hooks;
|
||||
|
||||
// Helpers providing access to current state during dlopen().
|
||||
static Plugin* current_plugin;
|
||||
static string current_dir;
|
||||
static string current_sopath;
|
||||
static const char* current_dir;
|
||||
static const char* current_sopath;
|
||||
|
||||
// Returns a modifiable list of all plugins, both static and dynamic.
|
||||
// This is a static method so that plugins can register themselves
|
||||
// even before the manager exists.
|
||||
static plugin_list* PluginsInternal();
|
||||
static plugin_list* ActivePluginsInternal();
|
||||
|
||||
typedef std::list<bif_init_func> bif_init_func_list;
|
||||
typedef std::map<std::string, bif_init_func_list*> bif_init_func_map;
|
||||
|
@ -275,7 +343,7 @@ std::list<T *> Manager::Components() const
|
|||
{
|
||||
std::list<T *> result;
|
||||
|
||||
for ( plugin_list::const_iterator p = PluginsInternal()->begin(); p != PluginsInternal()->end(); p++ )
|
||||
for ( plugin_list::const_iterator p = ActivePluginsInternal()->begin(); p != ActivePluginsInternal()->end(); p++ )
|
||||
{
|
||||
component_list components = (*p)->Components();
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ const char* plugin::hook_name(HookType h)
|
|||
"QueueEvent",
|
||||
"DrainEvents",
|
||||
"UpdateNetworkTime",
|
||||
"BroObjDtor",
|
||||
// MetaHooks
|
||||
"MetaHookPre",
|
||||
"MetaHookPost",
|
||||
|
@ -71,7 +72,7 @@ void HookArgument::Describe(ODesc* d) const
|
|||
break;
|
||||
|
||||
case EVENT:
|
||||
if ( arg.event )
|
||||
if ( arg.event )
|
||||
{
|
||||
d->Add(arg.event->Handler()->Name());
|
||||
d->Add("(");
|
||||
|
@ -98,7 +99,7 @@ void HookArgument::Describe(ODesc* d) const
|
|||
break;
|
||||
|
||||
case VAL:
|
||||
if ( arg.val )
|
||||
if ( arg.val )
|
||||
arg.val->Describe(d);
|
||||
|
||||
else
|
||||
|
@ -119,6 +120,10 @@ void HookArgument::Describe(ODesc* d) const
|
|||
case VOID:
|
||||
d->Add("<void>");
|
||||
break;
|
||||
|
||||
case VOIDP:
|
||||
d->Add("<void ptr>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,18 +199,7 @@ void Plugin::InitPostScript()
|
|||
|
||||
Plugin::bif_item_list Plugin::BifItems() const
|
||||
{
|
||||
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() const
|
||||
{
|
||||
return bif_item_list();
|
||||
return bif_items;
|
||||
}
|
||||
|
||||
void Plugin::Done()
|
||||
|
@ -262,7 +256,17 @@ void Plugin::DisableHook(HookType hook)
|
|||
plugin_mgr->DisableHook(hook, this);
|
||||
}
|
||||
|
||||
int Plugin::HookLoadFile(const std::string& file)
|
||||
void Plugin::RequestEvent(EventHandlerPtr handler)
|
||||
{
|
||||
plugin_mgr->RequestEvent(handler, this);
|
||||
}
|
||||
|
||||
void Plugin::RequestBroObjDtor(BroObj* obj)
|
||||
{
|
||||
plugin_mgr->RequestBroObjDtor(obj, this);
|
||||
}
|
||||
|
||||
int Plugin::HookLoadFile(const std::string& file, const std::string& ext)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -285,6 +289,10 @@ void Plugin::HookUpdateNetworkTime(double network_time)
|
|||
{
|
||||
}
|
||||
|
||||
void Plugin::HookBroObjDtor(void* obj)
|
||||
{
|
||||
}
|
||||
|
||||
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||
{
|
||||
}
|
||||
|
@ -295,7 +303,6 @@ void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgum
|
|||
|
||||
void Plugin::Describe(ODesc* d) const
|
||||
{
|
||||
d->Add("Plugin: ");
|
||||
d->Add(config.name);
|
||||
|
||||
if ( config.description.size() )
|
||||
|
@ -384,7 +391,7 @@ void Plugin::Describe(ODesc* d) const
|
|||
d->Add(hook_name(hook));
|
||||
d->Add(" (priority ");
|
||||
d->Add(prio);
|
||||
d->Add("]\n");
|
||||
d->Add(")\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
#include "iosource/Component.h"
|
||||
#include "iosource/pktsrc/Component.h"
|
||||
|
||||
// We allow to override this externally for testing purposes.
|
||||
#ifndef BRO_PLUGIN_API_VERSION
|
||||
#define BRO_PLUGIN_API_VERSION 2
|
||||
#endif
|
||||
|
||||
class ODesc;
|
||||
class Func;
|
||||
|
@ -30,15 +33,16 @@ class Plugin;
|
|||
*/
|
||||
enum HookType {
|
||||
// Note: when changing this table, update hook_name() in Plugin.cc.
|
||||
HOOK_LOAD_FILE,
|
||||
HOOK_CALL_FUNCTION,
|
||||
HOOK_QUEUE_EVENT,
|
||||
HOOK_DRAIN_EVENTS,
|
||||
HOOK_UPDATE_NETWORK_TIME,
|
||||
HOOK_LOAD_FILE, //< Activates Plugin::HookLoadFile().
|
||||
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_BRO_OBJ_DTOR, //< Activates Plugin::HookBroObjDtor.
|
||||
|
||||
// Meta hooks.
|
||||
META_HOOK_PRE,
|
||||
META_HOOK_POST,
|
||||
META_HOOK_PRE, //< Activates Plugin::MetaHookPre().
|
||||
META_HOOK_POST, //< Activates Plugin::MetaHookPost().
|
||||
|
||||
// End marker.
|
||||
NUM_HOOKS,
|
||||
|
@ -50,15 +54,20 @@ enum HookType {
|
|||
extern const char* hook_name(HookType h);
|
||||
|
||||
/**
|
||||
* Helper class to capture a plugin's version. A boolean operator evaluates
|
||||
* to true if the version has been set.
|
||||
*/
|
||||
* Helper class to capture a plugin's version.
|
||||
* */
|
||||
struct VersionNumber {
|
||||
int major; //< Major version number;
|
||||
int minor; //< Minor version number;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
VersionNumber() { major = minor = -1; }
|
||||
|
||||
/**
|
||||
* Returns true if the version is set to a non-negative value.
|
||||
*/
|
||||
operator bool() const { return major >= 0 && minor >= 0; }
|
||||
};
|
||||
|
||||
|
@ -71,21 +80,23 @@ public:
|
|||
std::string description; //< A short textual description of the plugin. Mandatory.
|
||||
VersionNumber version; //< THe plugin's version. Optional.
|
||||
|
||||
Configuration()
|
||||
{
|
||||
// Note we inline this method here so that when plugins create an instance,
|
||||
// *their* defaults will be used for the internal fields.
|
||||
name = "";
|
||||
description = "";
|
||||
api_version = BRO_PLUGIN_API_VERSION;
|
||||
}
|
||||
// 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));
|
||||
|
||||
private:
|
||||
friend class Plugin;
|
||||
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
|
||||
|
||||
};
|
||||
|
||||
inline Configuration::Configuration()
|
||||
{
|
||||
name = "";
|
||||
description = "";
|
||||
api_version = BRO_PLUGIN_API_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* A class describing an item defined in \c *.bif file.
|
||||
*/
|
||||
|
@ -142,30 +153,127 @@ private:
|
|||
class HookArgument
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of the argument.
|
||||
*/
|
||||
enum Type {
|
||||
BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, VAL_LIST, VOID
|
||||
BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, VAL_LIST, VOID, VOIDP,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default constructor initialized the argument with type VOID.
|
||||
*/
|
||||
HookArgument() { type = VOID; }
|
||||
|
||||
/**
|
||||
* Constructor with a boolean argument.
|
||||
*/
|
||||
HookArgument(bool a) { type = BOOL; arg.bool_ = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a double argument.
|
||||
*/
|
||||
HookArgument(double a) { type = DOUBLE; arg.double_ = a; }
|
||||
|
||||
/**
|
||||
* Constructor with an event argument.
|
||||
*/
|
||||
HookArgument(const Event* a) { type = EVENT; arg.event = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a function argument.
|
||||
*/
|
||||
HookArgument(const Func* a) { type = FUNC; arg.func = a; }
|
||||
|
||||
/**
|
||||
* Constructor with an integer argument.
|
||||
*/
|
||||
HookArgument(int a) { type = INT; arg.int_ = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a string argument.
|
||||
*/
|
||||
HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a Bro value argument.
|
||||
*/
|
||||
HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a list of Bro values argument.
|
||||
*/
|
||||
HookArgument(const val_list* a) { type = VAL_LIST; arg.vals = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a void pointer argument.
|
||||
*/
|
||||
HookArgument(void* p) { type = VOIDP; arg.voidp = p; }
|
||||
|
||||
/**
|
||||
* Returns the value for a boolen 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 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 Bro value argument. The argument's type must
|
||||
* match accordingly.
|
||||
*/
|
||||
const Val* AsVal() const { assert(type == VAL); return arg.val; }
|
||||
|
||||
/**
|
||||
* Returns the value for a list of Bro values argument. The argument's type must
|
||||
* match accordingly.
|
||||
*/
|
||||
const val_list* AsValList() const { assert(type == VAL_LIST); return arg.vals; }
|
||||
|
||||
/**
|
||||
* Returns the value for a vod pointer argument. The argument's type
|
||||
* must match accordingly.
|
||||
*/
|
||||
const void* AsVoidPtr() const { assert(type == VOIDP); return arg.voidp; }
|
||||
|
||||
/**
|
||||
* 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:
|
||||
|
@ -178,6 +286,7 @@ private:
|
|||
int int_;
|
||||
const Val* val;
|
||||
const val_list* vals;
|
||||
const void* voidp;
|
||||
} arg;
|
||||
|
||||
std::string arg_string; // Outside union because it has dtor.
|
||||
|
@ -191,24 +300,25 @@ typedef std::list<HookArgument> HookArgumentList;
|
|||
* Plugins encapsulate functionality that extends one or more of Bro'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 different functionality. Specifically, it may:
|
||||
* 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, 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.
|
||||
* Likewise, an SQLite plugin could provide both a writer and reader
|
||||
* component.
|
||||
*
|
||||
* - Provide BiF elements (functions, events, types, globals).
|
||||
* - 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 Bro's core processing to inject
|
||||
* and/or alter functionality.
|
||||
*
|
||||
* Note that 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 implemennt the
|
||||
* corresponding virtual methods).
|
||||
* 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 {
|
||||
|
@ -238,35 +348,36 @@ public:
|
|||
const std::string& Description() const;
|
||||
|
||||
/**
|
||||
* Returns the version of the plugin. Version are only meaningful for
|
||||
* dynamically compiled plugins; for statically compiled ones, this
|
||||
* will always return 0.
|
||||
* 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 in plugin.
|
||||
* 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 null.
|
||||
* 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 null.
|
||||
* from which it was loaded. For static plugins, returns an empty
|
||||
* string.
|
||||
**/
|
||||
const std::string& PluginPath() const;
|
||||
|
||||
/**
|
||||
* Returns the internal API version that this plugin relies on. Only
|
||||
* plugins that match Bro's current API version may be used. For
|
||||
* statically compiled plugins this is automatically the case, but
|
||||
* dynamically loaded plugins may cause a mismatch if they were
|
||||
* compiled for a different Bro version.
|
||||
* Returns the internal version of the Bro API that this plugin
|
||||
* relies on. Only plugins that match Bro's current API version can
|
||||
* be used. For statically compiled plugins this is automatically the
|
||||
* case, but dynamically loaded plugins may cause a mismatch if they
|
||||
* were compiled for a different Bro version.
|
||||
*/
|
||||
int APIVersion() const;
|
||||
|
||||
|
@ -282,15 +393,54 @@ public:
|
|||
bif_item_list BifItems() const;
|
||||
|
||||
/**
|
||||
* A function called when the plugin is instantiated to query basic
|
||||
* configuration parameters.
|
||||
* Returns a textual description of the plugin.
|
||||
*
|
||||
* The plugin must override this method and return a suitably
|
||||
* initialized configuration object.
|
||||
*
|
||||
* @return A configuration describing 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.
|
||||
*/
|
||||
virtual Configuration Configure() { return Configuration(); } // TODO: Change to abstract method.
|
||||
void Describe(ODesc* d) const;
|
||||
|
||||
/**
|
||||
* Registers an individual BiF that the plugin defines. The
|
||||
* information is for informational purpuses 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 Bro parts. Doing
|
||||
* so can be tricky, and it's recommned 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 Bro loads at startup. This
|
||||
* will normally be a Bro 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 LoadBroFile(const std::string& file);
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
/**
|
||||
* First-stage initialization of the plugin called early during Bro's
|
||||
|
@ -315,56 +465,6 @@ public:
|
|||
*/
|
||||
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) const;
|
||||
|
||||
/**
|
||||
* Registers an individual BiF that the plugin defines. The
|
||||
* information is for informational purpuses 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().
|
||||
*
|
||||
* \todo Do we need both this an CustomBifItems()?
|
||||
*
|
||||
* @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 Bro loads at startup. This
|
||||
* will normally be a Bro 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 given 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 LoadBroFile(const std::string& file);
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
/**
|
||||
* Intializes the plugin's configutation. Called by the manager
|
||||
* before anything else.
|
||||
*/
|
||||
void DoConfigure();
|
||||
|
||||
/**
|
||||
* Registers and activates a component.
|
||||
*
|
||||
|
@ -375,15 +475,14 @@ protected:
|
|||
/**
|
||||
* Enables a hook. The corresponding virtual method will now be
|
||||
* called as Bro's processing proceeds. Note that enabling hooks can
|
||||
* have performance impaxct as many trigger frequently inside Bro's
|
||||
* have performance impact as many trigger frequently inside Bro's
|
||||
* main processing path.
|
||||
*
|
||||
* Note that hooks may be enabled/disabled dynamically at any time,
|
||||
* the output of Bro's \c -NN option will only reflect that state at
|
||||
* startup time; hence usually one should call this for a plugin's
|
||||
* hooks in either the plugin's ctor or in InitPreScript(). For
|
||||
* consistency with other parts of the API, there's a macro
|
||||
* PLUGIN_ENABLE_HOOK for use inside the ctor.
|
||||
* Note that while hooks may be enabled/disabled dynamically at any
|
||||
* time, the output of Bro'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.
|
||||
*
|
||||
|
@ -409,16 +508,26 @@ protected:
|
|||
hook_list EnabledHooks() const;
|
||||
|
||||
/**
|
||||
* Virtual method that can be overriden by derived class to provide
|
||||
* information about further script-level elements that the plugin
|
||||
* provides on its own, i.e., outside of the standard mechanism
|
||||
* processing *.bif files automatically. The returned information is
|
||||
* for informational purposes only and will show up in the result of
|
||||
* BifItems() as well as in the Describe() output.
|
||||
*
|
||||
* \todo Do we need both this an AddBifItem()?
|
||||
* Registers interest in an event, even if there's no handler for it.
|
||||
* Normally a plugin receives events through HookQueueEvent() only if Bro
|
||||
* actually has code to execute for it. By calling this method, the
|
||||
* plugin tells Bro to raise the event even if there's no correspondong
|
||||
* handler; it will then go into HookQueueEvent() just as any other.
|
||||
*
|
||||
* @param handler The event handler being interested in.
|
||||
*/
|
||||
virtual bif_item_list CustomBifItems() const;
|
||||
void RequestEvent(EventHandlerPtr handler);
|
||||
|
||||
/**
|
||||
* Registers interest in the destruction of a BroObj instance. When
|
||||
* Bro's reference counting triggers the objects destructor to run,
|
||||
* \a HookBroObjDtor will be called.
|
||||
*
|
||||
* Note that his can get expensive if triggered for many objects.
|
||||
*
|
||||
* @param handler The object being interested in.
|
||||
*/
|
||||
void RequestBroObjDtor(BroObj* obj);
|
||||
|
||||
// Hook functions.
|
||||
|
||||
|
@ -428,15 +537,20 @@ protected:
|
|||
* timing guaranteed. It will be called once for each input file Bro
|
||||
* 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
|
||||
* Bro not further process it otherwise.
|
||||
* Bro will not further process it otherwise.
|
||||
*
|
||||
* @param file The filename to be loaded, including extension.
|
||||
*
|
||||
* @param ext The extension of the filename. This is provided
|
||||
* separately just for convenience. The dot is excluded.
|
||||
*
|
||||
* @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 (Bro will abort in this case, the plugin should have
|
||||
* printed an error message); and -1 if the plugin wasn't interested
|
||||
* in the file at all.
|
||||
* loading it (Bro 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 std::string& file);
|
||||
virtual int HookLoadFile(const std::string& file, const std::string& ext);
|
||||
|
||||
/**
|
||||
* Hook into executing a script-level function/event/hook. Whenever
|
||||
|
@ -447,19 +561,19 @@ protected:
|
|||
* from executing it). In the latter case it must provide a matching
|
||||
* return value.
|
||||
*
|
||||
* The default implementation does never handle the call in any way.
|
||||
* 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 long as it ensures matching types and correct reference
|
||||
* in place as long as it ensures matching types and correct reference
|
||||
* counting.
|
||||
*
|
||||
* @return If the plugin handled the call, a +1 Val with the result
|
||||
* value to pass back to the interpreter (for void functions and
|
||||
* events any \a Val is fine; it will be ignored; best to use a \c
|
||||
* TYPE_ANY). If the plugin did not handle the call, it must return
|
||||
* null.
|
||||
* @return If the plugin handled the call, a Val with +1 reference
|
||||
* count containixnmg the result value to pass back to the interpreter
|
||||
* (for void functions and events any \a Val is fine; it will be
|
||||
* ignored; best to use a \c TYPE_ANY). If the plugin did not handle
|
||||
* the call, it must return null.
|
||||
*/
|
||||
virtual Val* HookCallFunction(const Func* func, val_list* args);
|
||||
|
||||
|
@ -469,23 +583,22 @@ protected:
|
|||
* 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 it).
|
||||
* from queuing it itself).
|
||||
*
|
||||
* The default implementation does never handle the queuing in any
|
||||
* way.
|
||||
* The default implementation never handles the queuing in any way.
|
||||
*
|
||||
* @param event The even to be queued. The method can modify it in in
|
||||
* place long as it ensures matching types and correct reference
|
||||
* @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 intpreter will
|
||||
* 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 intp event queue draining. This method will be called
|
||||
* Hook into event queue draining. This method will be called
|
||||
* whenever the event manager is draining its queue.
|
||||
*/
|
||||
virtual void HookDrainEvents();
|
||||
|
@ -498,10 +611,24 @@ protected:
|
|||
*/
|
||||
virtual void HookUpdateNetworkTime(double network_time);
|
||||
|
||||
/**
|
||||
* Hook for destruction of objects registered with
|
||||
* RequestBroObjDtor(). When Bro'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 HookBroObjDtor(void* obj);
|
||||
|
||||
// Meta hooks.
|
||||
|
||||
/**
|
||||
* A meta hook called just before another hook gets to execute.
|
||||
* A meta hook called just before another hook gets to execute. This
|
||||
* will be called independent of whether there's an implementation
|
||||
* for the hook.
|
||||
*
|
||||
* hook: The name of the hook about the execute. This will be the
|
||||
* same as the corresponding method name (e.g., \c HookQueueEvent).
|
||||
|
@ -513,7 +640,7 @@ protected:
|
|||
virtual void MetaHookPre(HookType hook, const HookArgumentList& args);
|
||||
|
||||
/**
|
||||
* A meta hook called just after another hook gets to execute. This
|
||||
* A meta hook called just after another hook got to execute. This
|
||||
* will be called independent of whether there's an implementation
|
||||
* for the hook.
|
||||
*
|
||||
|
@ -527,14 +654,30 @@ protected:
|
|||
*/
|
||||
virtual void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result);
|
||||
|
||||
// Methods that are used internally primarily.
|
||||
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;
|
||||
|
||||
/**
|
||||
* Intializes 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 used primarily internally; plugins will have there
|
||||
* location set automatically.
|
||||
* This is called by the manager.
|
||||
*
|
||||
* @param dir The plugin directory. The functions makes an internal
|
||||
* copy of string.
|
||||
|
@ -547,22 +690,20 @@ protected:
|
|||
/**
|
||||
* Marks the plugin as dynamically loaded.
|
||||
*
|
||||
* This is used primarily internally; plugins will have this called
|
||||
* by the manager.
|
||||
* This is called by the manager.
|
||||
*
|
||||
* @param is_dynamic True if it's a dynamically loaded module.
|
||||
*/
|
||||
void SetDynamic(bool is_dynamic);
|
||||
|
||||
private:
|
||||
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;
|
||||
bif_item_list bif_items;
|
||||
component_list components; // Components the plugin provides.
|
||||
bif_item_list bif_items; // BiF items the plugin provides.
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue