mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 23:28:20 +00:00
Adding meta hooks.
This is mainly an experiment to see if this makes sense. I'm not very fond of the arguments being wrapped into a discriminating union, but I like it better than other alternatives at least. The new code is untested.
This commit is contained in:
parent
b7dd8e4a78
commit
ee75958951
5 changed files with 274 additions and 26 deletions
|
@ -14,7 +14,7 @@ public:
|
||||||
{
|
{
|
||||||
AddComponent(new ::analyzer::Component("TCP", ::analyzer::tcp::TCP_Analyzer::Instantiate));
|
AddComponent(new ::analyzer::Component("TCP", ::analyzer::tcp::TCP_Analyzer::Instantiate));
|
||||||
AddComponent(new ::analyzer::Component("TCPStats", ::analyzer::tcp::TCPStats_Analyzer::Instantiate));
|
AddComponent(new ::analyzer::Component("TCPStats", ::analyzer::tcp::TCPStats_Analyzer::Instantiate));
|
||||||
AddComponent(new ::analyzer::Component("ContentsLine", 0));
|
AddComponent(new ::analyzer::Component("CONTENTLINE", 0));
|
||||||
AddComponent(new ::analyzer::Component("Contents", 0));
|
AddComponent(new ::analyzer::Component("Contents", 0));
|
||||||
|
|
||||||
plugin::Configuration config;
|
plugin::Configuration config;
|
||||||
|
|
|
@ -445,8 +445,18 @@ void Manager::DisableHook(HookType hook, Plugin* plugin)
|
||||||
|
|
||||||
int Manager::HookLoadFile(const string& file)
|
int Manager::HookLoadFile(const string& file)
|
||||||
{
|
{
|
||||||
|
HookArgumentList args;
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||||
|
{
|
||||||
|
args.push_back(HookArgument(file));
|
||||||
|
MetaHookPre(HOOK_LOAD_FILE, args);
|
||||||
|
}
|
||||||
|
|
||||||
hook_list* l = hooks[HOOK_LOAD_FILE];
|
hook_list* l = hooks[HOOK_LOAD_FILE];
|
||||||
|
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||||
{
|
{
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
|
@ -454,46 +464,84 @@ int Manager::HookLoadFile(const string& file)
|
||||||
int rc = p->HookLoadFile(file);
|
int rc = p->HookLoadFile(file);
|
||||||
|
|
||||||
if ( rc >= 0 )
|
if ( rc >= 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_POST) )
|
||||||
|
MetaHookPost(HOOK_LOAD_FILE, args, HookArgument(rc));
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
Val* Manager::HookCallFunction(const Func* func, val_list* vargs) const
|
||||||
|
{
|
||||||
|
HookArgumentList args;
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||||
|
{
|
||||||
|
args.push_back(HookArgument(func));
|
||||||
|
args.push_back(HookArgument(vargs));
|
||||||
|
MetaHookPre(HOOK_CALL_FUNCTION, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* Manager::HookCallFunction(const Func* func, val_list* args) const
|
|
||||||
{
|
|
||||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
||||||
|
|
||||||
|
Val* v = 0;
|
||||||
|
|
||||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||||
{
|
{
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
|
|
||||||
Val* v = p->HookCallFunction(func, args);
|
v = p->HookCallFunction(func, vargs);
|
||||||
|
|
||||||
if ( v )
|
if ( v )
|
||||||
return v;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if ( HavePluginForHook(META_HOOK_POST) )
|
||||||
|
MetaHookPost(HOOK_CALL_FUNCTION, args, HookArgument(v));
|
||||||
|
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::HookQueueEvent(Event* event) const
|
bool Manager::HookQueueEvent(Event* event) const
|
||||||
{
|
{
|
||||||
|
HookArgumentList args;
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||||
|
{
|
||||||
|
args.push_back(HookArgument(event));
|
||||||
|
MetaHookPre(HOOK_QUEUE_EVENT, args);
|
||||||
|
}
|
||||||
|
|
||||||
hook_list* l = hooks[HOOK_QUEUE_EVENT];
|
hook_list* l = hooks[HOOK_QUEUE_EVENT];
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||||
{
|
{
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
|
|
||||||
if ( p->HookQueueEvent(event) )
|
if ( p->HookQueueEvent(event) )
|
||||||
return true;
|
{
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if ( HavePluginForHook(META_HOOK_POST) )
|
||||||
|
MetaHookPost(HOOK_QUEUE_EVENT, args, HookArgument(result));
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::HookDrainEvents() const
|
void Manager::HookDrainEvents() const
|
||||||
{
|
{
|
||||||
|
HookArgumentList args;
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||||
|
MetaHookPre(HOOK_DRAIN_EVENTS, args);
|
||||||
|
|
||||||
hook_list* l = hooks[HOOK_DRAIN_EVENTS];
|
hook_list* l = hooks[HOOK_DRAIN_EVENTS];
|
||||||
|
|
||||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||||
|
@ -501,10 +549,22 @@ void Manager::HookDrainEvents() const
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
p->HookDrainEvents();
|
p->HookDrainEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_POST) )
|
||||||
|
MetaHookPost(HOOK_DRAIN_EVENTS, args, HookArgument());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::HookUpdateNetworkTime(double network_time) const
|
void Manager::HookUpdateNetworkTime(double network_time) const
|
||||||
{
|
{
|
||||||
|
HookArgumentList args;
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||||
|
{
|
||||||
|
args.push_back(network_time);
|
||||||
|
MetaHookPre(HOOK_UPDATE_NETWORK_TIME, args);
|
||||||
|
}
|
||||||
|
|
||||||
hook_list* l = hooks[HOOK_UPDATE_NETWORK_TIME];
|
hook_list* l = hooks[HOOK_UPDATE_NETWORK_TIME];
|
||||||
|
|
||||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||||
|
@ -512,4 +572,29 @@ void Manager::HookUpdateNetworkTime(double network_time) const
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
p->HookUpdateNetworkTime(network_time);
|
p->HookUpdateNetworkTime(network_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( HavePluginForHook(META_HOOK_POST) )
|
||||||
|
MetaHookPost(HOOK_UPDATE_NETWORK_TIME, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,8 @@ public:
|
||||||
private:
|
private:
|
||||||
bool ActivateDynamicPluginInternal(const std::string& name);
|
bool ActivateDynamicPluginInternal(const std::string& name);
|
||||||
void UpdateInputFiles();
|
void UpdateInputFiles();
|
||||||
|
void MetaHookPre(HookType hook, const HookArgumentList& args) const;
|
||||||
|
void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) const;
|
||||||
|
|
||||||
// All found dynamic plugins, mapping their names to base directory.
|
// All found dynamic plugins, mapping their names to base directory.
|
||||||
typedef std::map<std::string, std::string> dynamic_plugin_map;
|
typedef std::map<std::string, std::string> dynamic_plugin_map;
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
|
|
||||||
#include "../Desc.h"
|
#include "../Desc.h"
|
||||||
|
#include "../Event.h"
|
||||||
|
|
||||||
using namespace plugin;
|
using namespace plugin;
|
||||||
|
|
||||||
const char* hook_name(HookType h)
|
const char* plugin::hook_name(HookType h)
|
||||||
{
|
{
|
||||||
static const char* hook_names[int(NUM_HOOKS) + 1] = {
|
static const char* hook_names[int(NUM_HOOKS) + 1] = {
|
||||||
// Order must match that of HookType.
|
// Order must match that of HookType.
|
||||||
"LoadFile",
|
"LoadFile",
|
||||||
|
@ -21,6 +22,9 @@ const char* hook_name(HookType h)
|
||||||
"QueueEvent",
|
"QueueEvent",
|
||||||
"DrainEvents",
|
"DrainEvents",
|
||||||
"UpdateNetworkTime",
|
"UpdateNetworkTime",
|
||||||
|
// MetaHooks
|
||||||
|
"MetaHookPre",
|
||||||
|
"MetaHookPost",
|
||||||
// End marker.
|
// End marker.
|
||||||
"<end>",
|
"<end>",
|
||||||
};
|
};
|
||||||
|
@ -55,6 +59,69 @@ BifItem::~BifItem()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HookArgument::Describe(ODesc* d) const
|
||||||
|
{
|
||||||
|
switch ( type ) {
|
||||||
|
case BOOL:
|
||||||
|
d->Add(arg.bool_ ? "true" : "false");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOUBLE:
|
||||||
|
d->Add(arg.double_);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT:
|
||||||
|
if ( arg.event )
|
||||||
|
{
|
||||||
|
d->Add(arg.event->Handler()->Name());
|
||||||
|
d->Add("(");
|
||||||
|
describe_vals(arg.event->Args(), d);
|
||||||
|
d->Add(")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d->Add("<null>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FUNC:
|
||||||
|
if ( arg.func )
|
||||||
|
d->Add(arg.func->Name());
|
||||||
|
else
|
||||||
|
d->Add("<null>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INT:
|
||||||
|
d->Add(arg.int_);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRING:
|
||||||
|
d->Add(arg_string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VAL:
|
||||||
|
if ( arg.val )
|
||||||
|
arg.val->Describe(d);
|
||||||
|
|
||||||
|
else
|
||||||
|
d->Add("<null>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VAL_LIST:
|
||||||
|
if ( arg.vals )
|
||||||
|
{
|
||||||
|
d->Add("(");
|
||||||
|
describe_vals(arg.vals, d);
|
||||||
|
d->Add(")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d->Add("<null>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VOID:
|
||||||
|
d->Add("<void>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Plugin::Plugin()
|
Plugin::Plugin()
|
||||||
{
|
{
|
||||||
dynamic = false;
|
dynamic = false;
|
||||||
|
@ -218,6 +285,14 @@ void Plugin::HookUpdateNetworkTime(double network_time)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Plugin::Describe(ODesc* d) const
|
void Plugin::Describe(ODesc* d) const
|
||||||
{
|
{
|
||||||
d->Add("Plugin: ");
|
d->Add("Plugin: ");
|
||||||
|
|
|
@ -10,14 +10,14 @@
|
||||||
#include "analyzer/Component.h"
|
#include "analyzer/Component.h"
|
||||||
#include "file_analysis/Component.h"
|
#include "file_analysis/Component.h"
|
||||||
|
|
||||||
|
#define BRO_PLUGIN_API_VERSION 2
|
||||||
|
|
||||||
class ODesc;
|
class ODesc;
|
||||||
class Func;
|
class Func;
|
||||||
class Event;
|
class Event;
|
||||||
|
|
||||||
namespace plugin {
|
namespace plugin {
|
||||||
|
|
||||||
#define BRO_PLUGIN_API_VERSION 2
|
|
||||||
|
|
||||||
class Manager;
|
class Manager;
|
||||||
class Component;
|
class Component;
|
||||||
class Plugin;
|
class Plugin;
|
||||||
|
@ -33,10 +33,20 @@ enum HookType {
|
||||||
HOOK_QUEUE_EVENT,
|
HOOK_QUEUE_EVENT,
|
||||||
HOOK_DRAIN_EVENTS,
|
HOOK_DRAIN_EVENTS,
|
||||||
HOOK_UPDATE_NETWORK_TIME,
|
HOOK_UPDATE_NETWORK_TIME,
|
||||||
|
|
||||||
|
// Meta hooks.
|
||||||
|
META_HOOK_PRE,
|
||||||
|
META_HOOK_POST,
|
||||||
|
|
||||||
// End marker.
|
// End marker.
|
||||||
NUM_HOOKS,
|
NUM_HOOKS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a hook type into a readable hook name.
|
||||||
|
*/
|
||||||
|
extern const char* hook_name(HookType h);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to capture a plugin's version. A boolean operator evaluates
|
* Helper class to capture a plugin's version. A boolean operator evaluates
|
||||||
* to true if the version has been set.
|
* to true if the version has been set.
|
||||||
|
@ -59,7 +69,14 @@ public:
|
||||||
std::string description; //< A short textual description of the plugin. Mandatory.
|
std::string description; //< A short textual description of the plugin. Mandatory.
|
||||||
VersionNumber version; //< THe plugin's version. Optional.
|
VersionNumber version; //< THe plugin's version. Optional.
|
||||||
|
|
||||||
Configuration();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Plugin;
|
friend class Plugin;
|
||||||
|
@ -67,15 +84,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note we inline this method here so that when plugins create an instance,
|
|
||||||
// *their* defaults will be used for the internal fields.
|
|
||||||
inline Configuration::Configuration()
|
|
||||||
{
|
|
||||||
name = "";
|
|
||||||
description = "";
|
|
||||||
api_version = BRO_PLUGIN_API_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing an item defined in \c *.bif file.
|
* A class describing an item defined in \c *.bif file.
|
||||||
*/
|
*/
|
||||||
|
@ -126,6 +134,55 @@ private:
|
||||||
Type type;
|
Type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class encapsulating an event argument to then pass along with a meta hook.
|
||||||
|
*/
|
||||||
|
class HookArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, VAL_LIST, VOID
|
||||||
|
};
|
||||||
|
|
||||||
|
HookArgument() { type = VOID; }
|
||||||
|
HookArgument(bool a) { type = BOOL; arg.bool_ = a; }
|
||||||
|
HookArgument(double a) { type = DOUBLE; arg.double_ = a; }
|
||||||
|
HookArgument(const Event* a) { type = EVENT; arg.event = a; }
|
||||||
|
HookArgument(const Func* a) { type = FUNC; arg.func = a; }
|
||||||
|
HookArgument(int a) { type = INT; arg.int_ = a; }
|
||||||
|
HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
||||||
|
HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
||||||
|
HookArgument(const val_list* a) { type = VAL_LIST; arg.vals = a; }
|
||||||
|
|
||||||
|
bool AsBool() const { assert(type == BOOL); return arg.bool_; }
|
||||||
|
double AsDouble() const { assert(type == DOUBLE); return arg.double_; }
|
||||||
|
const Event* AsEvent() const { assert(type == EVENT); return arg.event; }
|
||||||
|
const Func* AsFunc() const { assert(type == FUNC); return arg.func; }
|
||||||
|
double AsInt() const { assert(type == INT); return arg.int_; }
|
||||||
|
const std::string& AsString() const { assert(type == STRING); return arg_string; }
|
||||||
|
const Val* AsVal() const { assert(type == VAL); return arg.val; }
|
||||||
|
const val_list* AsValList() const { assert(type == VAL_LIST); return arg.vals; }
|
||||||
|
|
||||||
|
Type GetType() const { return type; }
|
||||||
|
void Describe(ODesc* d) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type type;
|
||||||
|
union {
|
||||||
|
bool bool_;
|
||||||
|
double double_;
|
||||||
|
const Event* event;
|
||||||
|
const Func* func;
|
||||||
|
int int_;
|
||||||
|
const Val* val;
|
||||||
|
const val_list* vals;
|
||||||
|
} arg;
|
||||||
|
|
||||||
|
std::string arg_string; // Outside union because it has dtor.
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::list<HookArgument> HookArgumentList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all plugins.
|
* Base class for all plugins.
|
||||||
*
|
*
|
||||||
|
@ -439,6 +496,35 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void HookUpdateNetworkTime(double network_time);
|
virtual void HookUpdateNetworkTime(double network_time);
|
||||||
|
|
||||||
|
// Meta hooks.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A meta hook called just before another hook gets to execute.
|
||||||
|
*
|
||||||
|
* hook: The name of the hook about the execute. This will be the
|
||||||
|
* same as the corresponding method name (e.g., \c HookQueueEvent).
|
||||||
|
*
|
||||||
|
* hook: The type of the hook about to execute.
|
||||||
|
*
|
||||||
|
* args: A list of the hooks arguments.
|
||||||
|
*/
|
||||||
|
virtual void MetaHookPre(HookType hook, const HookArgumentList& args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A meta hook called just after another hook gets to execute. This
|
||||||
|
* will be called independent of whether there's an implementation
|
||||||
|
* for the hook.
|
||||||
|
*
|
||||||
|
* hook: The type of the hook that finished executing.
|
||||||
|
*
|
||||||
|
* args: A list of the hooks arguments.
|
||||||
|
*
|
||||||
|
* result: The result that executing the hook returned. If there's no
|
||||||
|
* implementation for the hook, this will be the default result. If
|
||||||
|
* the hook doesn't yield a result, this will be of type VOID.
|
||||||
|
*/
|
||||||
|
virtual void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result);
|
||||||
|
|
||||||
// Methods that are used internally primarily.
|
// Methods that are used internally primarily.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue