diff --git a/CHANGES b/CHANGES
index 0227e96b36..ff97b9c2a1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,16 @@
+2.4-84 | 2015-08-10 14:44:39 -0700
+
+ * Add hook 'HookSetupAnalyzerTree' to allow plugins access to a
+ connection's initial analyzer tree for customization. (James
+ Swaro)
+
+ * Plugins now look for a file "__preload__.bro" in the top-level
+ script directory. If found, they load it first, before any scripts
+ defining BiF elements. This can be used to define types that the
+ BiFs already depend on (like a custom type for an event argument).
+ (Robin Sommer)
+
2.4-81 | 2015-08-08 07:38:42 -0700
* Fix a test that is failing very frequently. (Daniel Thayer)
diff --git a/VERSION b/VERSION
index 72a6e1ac62..b8af263b9a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.4-81
+2.4-84
diff --git a/aux/bro-aux b/aux/bro-aux
index 1a525eef91..2470f64b58 160000
--- a/aux/bro-aux
+++ b/aux/bro-aux
@@ -1 +1 @@
-Subproject commit 1a525eef9132855c2dfaf5ba62fcc572d97873d5
+Subproject commit 2470f64b58d875f9491e251b866a15a2ec4c05da
diff --git a/aux/plugins b/aux/plugins
index bb86ad945c..09cd828ba8 160000
--- a/aux/plugins
+++ b/aux/plugins
@@ -1 +1 @@
-Subproject commit bb86ad945c823c94ea8385ec4ebb9546ba5198af
+Subproject commit 09cd828ba80a0df69a78e64743aedf23a29e6bdc
diff --git a/doc/devel/plugins.rst b/doc/devel/plugins.rst
index 091a0090d1..0ed22a0cb9 100644
--- a/doc/devel/plugins.rst
+++ b/doc/devel/plugins.rst
@@ -209,8 +209,15 @@ directory. With the skeleton, ```` corresponds to ``build/``.
"@load"ed.
``scripts``/__load__.bro
- A Bro script that will be loaded immediately when the plugin gets
- activated. See below for more information on activating plugins.
+ A Bro script that will be loaded when the plugin gets activated.
+ When this script executes, any BiF elements that the plugin
+ defines will already be available. See below for more information
+ on activating plugins.
+
+``scripts``/__preload__.bro
+ A Bro script that will be loaded when the plugin gets activated,
+ but before any BiF elements become available. See below for more
+ information on activating plugins.
``lib/bif/``
Directory with auto-generated Bro scripts that declare the plugin's
@@ -279,7 +286,9 @@ Activating a plugin will:
1. Load the dynamic module
2. Make any bif items available
3. Add the ``scripts/`` directory to ``BROPATH``
- 4. Load ``scripts/__load__.bro``
+ 5. Load ``scripts/__preload__.bro``
+ 6. Make BiF elements available to scripts.
+ 7. Load ``scripts/__load__.bro``
By default, Bro will automatically activate all dynamic plugins found
in its search path ``BRO_PLUGIN_PATH``. However, in bare mode (``bro
diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc
index bc8fceaf39..67aa6a0d33 100644
--- a/src/analyzer/Manager.cc
+++ b/src/analyzer/Manager.cc
@@ -505,6 +505,8 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
if ( ! analyzed )
conn->SetLifetime(non_analyzed_lifetime);
+ PLUGIN_HOOK_VOID(HOOK_SETUP_ANALYZER_TREE, HookSetupAnalyzerTree(conn));
+
return true;
}
diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc
index 8e58c1296b..a449fb34e4 100644
--- a/src/plugin/Manager.cc
+++ b/src/plugin/Manager.cc
@@ -182,9 +182,17 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_
add_to_bro_path(scripts);
}
- // Load {bif,scripts}/__load__.bro automatically.
+ // First load {scripts}/__preload__.bro automatically.
+ string init = dir + "scripts/__preload__.bro";
- string init = dir + "lib/bif/__load__.bro";
+ if ( is_file(init) )
+ {
+ DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
+ scripts_to_load.push_back(init);
+ }
+
+ // Load {bif,scripts}/__load__.bro automatically.
+ init = dir + "lib/bif/__load__.bro";
if ( is_file(init) )
{
@@ -660,6 +668,33 @@ void Manager::HookDrainEvents() const
}
+void Manager::HookSetupAnalyzerTree(Connection *conn) const
+ {
+ HookArgumentList args;
+
+ if ( HavePluginForHook(META_HOOK_PRE) )
+ {
+ args.push_back(conn);
+ MetaHookPre(HOOK_SETUP_ANALYZER_TREE, args);
+ }
+
+ hook_list *l = hooks[HOOK_SETUP_ANALYZER_TREE];
+
+ if ( l )
+ {
+ for (hook_list::iterator i = l->begin() ; i != l->end(); ++i)
+ {
+ Plugin *p = (*i).second;
+ p->HookSetupAnalyzerTree(conn);
+ }
+ }
+
+ if ( HavePluginForHook(META_HOOK_POST) )
+ {
+ MetaHookPost(HOOK_SETUP_ANALYZER_TREE, args, HookArgument());
+ }
+ }
+
void Manager::HookUpdateNetworkTime(double network_time) const
{
HookArgumentList args;
diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h
index db812b6a8c..04c632d61a 100644
--- a/src/plugin/Manager.h
+++ b/src/plugin/Manager.h
@@ -264,6 +264,15 @@ public:
*/
void HookUpdateNetworkTime(double network_time) const;
+ /**
+ * 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.
+ */
+ void HookSetupAnalyzerTree(Connection *conn) const;
+
/**
* Hook that informs plugins that the event queue is being drained.
*/
diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc
index f05378eb84..190ae02cde 100644
--- a/src/plugin/Plugin.cc
+++ b/src/plugin/Plugin.cc
@@ -23,6 +23,7 @@ const char* plugin::hook_name(HookType h)
"DrainEvents",
"UpdateNetworkTime",
"BroObjDtor",
+ "SetupAnalyzerTree",
// MetaHooks
"MetaHookPre",
"MetaHookPost",
@@ -310,6 +311,10 @@ void Plugin::HookUpdateNetworkTime(double network_time)
{
}
+void Plugin::HookSetupAnalyzerTree(Connection *conn)
+ {
+ }
+
void Plugin::HookBroObjDtor(void* obj)
{
}
diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h
index ce3d53d44e..e23173f726 100644
--- a/src/plugin/Plugin.h
+++ b/src/plugin/Plugin.h
@@ -14,7 +14,7 @@
// We allow to override this externally for testing purposes.
#ifndef BRO_PLUGIN_API_VERSION
-#define BRO_PLUGIN_API_VERSION 3
+#define BRO_PLUGIN_API_VERSION 4
#endif
class ODesc;
@@ -39,6 +39,7 @@ enum HookType {
HOOK_DRAIN_EVENTS, //< Activates Plugin::HookDrainEvents()
HOOK_UPDATE_NETWORK_TIME, //< Activates Plugin::HookUpdateNetworkTime.
HOOK_BRO_OBJ_DTOR, //< Activates Plugin::HookBroObjDtor.
+ HOOK_SETUP_ANALYZER_TREE, //< Activates Plugin::HookAddToAnalyzerTree
// Meta hooks.
META_HOOK_PRE, //< Activates Plugin::MetaHookPre().
@@ -636,6 +637,8 @@ protected:
*/
virtual void HookUpdateNetworkTime(double network_time);
+ virtual void HookSetupAnalyzerTree(Connection *conn);
+
/**
* Hook for destruction of objects registered with
* RequestBroObjDtor(). When Bro's reference counting triggers the
diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output
index 9239f2d40d..feb78d8c56 100644
--- a/testing/btest/Baseline/plugins.hooks/output
+++ b/testing/btest/Baseline/plugins.hooks/output
@@ -220,7 +220,7 @@
0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) ->
0.000000 MetaHookPost CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) ->
0.000000 MetaHookPost CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) ->
-0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1429655378.868621, node=bro, filter=ip or not ip, init=T, success=T])) ->
+0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1439244305.210087, node=bro, filter=ip or not ip, init=T, success=T])) ->
0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Cluster::LOG)) ->
0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Communication::LOG)) ->
0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Conn::LOG)) ->
@@ -326,7 +326,7 @@
0.000000 MetaHookPost CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) ->
0.000000 MetaHookPost CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) ->
0.000000 MetaHookPost CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) ->
-0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1429655378.868621, node=bro, filter=ip or not ip, init=T, success=T])) ->
+0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1439244305.210087, node=bro, filter=ip or not ip, init=T, success=T])) ->
0.000000 MetaHookPost CallFunction(Notice::want_pp, , ()) ->
0.000000 MetaHookPost CallFunction(PacketFilter::build, , ()) ->
0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, , (ip or not ip, and, )) ->
@@ -490,6 +490,7 @@
0.000000 MetaHookPost LoadFile(./top-k.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./topk) -> -1
0.000000 MetaHookPost LoadFile(./types.bif.bro) -> -1
+0.000000 MetaHookPost LoadFile(./types.bro) -> -1
0.000000 MetaHookPost LoadFile(./unique) -> -1
0.000000 MetaHookPost LoadFile(./utils) -> -1
0.000000 MetaHookPost LoadFile(./utils-commands) -> -1
@@ -509,6 +510,7 @@
0.000000 MetaHookPost LoadFile(.<...>/raw) -> -1
0.000000 MetaHookPost LoadFile(.<...>/sqlite) -> -1
0.000000 MetaHookPost LoadFile(<...>/__load__.bro) -> -1
+0.000000 MetaHookPost LoadFile(<...>/__preload__.bro) -> -1
0.000000 MetaHookPost LoadFile(<...>/hooks.bro) -> -1
0.000000 MetaHookPost LoadFile(base/bif) -> -1
0.000000 MetaHookPost LoadFile(base/init-default.bro) -> -1
@@ -810,7 +812,7 @@
0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]))
-0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1429655378.868621, node=bro, filter=ip or not ip, init=T, success=T]))
+0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1439244305.210087, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Cluster::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Communication::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Conn::LOG))
@@ -916,7 +918,7 @@
0.000000 MetaHookPre CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]))
-0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1429655378.868621, node=bro, filter=ip or not ip, init=T, success=T]))
+0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1439244305.210087, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(Notice::want_pp, , ())
0.000000 MetaHookPre CallFunction(PacketFilter::build, , ())
0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, , (ip or not ip, and, ))
@@ -1080,6 +1082,7 @@
0.000000 MetaHookPre LoadFile(./top-k.bif.bro)
0.000000 MetaHookPre LoadFile(./topk)
0.000000 MetaHookPre LoadFile(./types.bif.bro)
+0.000000 MetaHookPre LoadFile(./types.bro)
0.000000 MetaHookPre LoadFile(./unique)
0.000000 MetaHookPre LoadFile(./utils)
0.000000 MetaHookPre LoadFile(./utils-commands)
@@ -1099,6 +1102,7 @@
0.000000 MetaHookPre LoadFile(.<...>/raw)
0.000000 MetaHookPre LoadFile(.<...>/sqlite)
0.000000 MetaHookPre LoadFile(<...>/__load__.bro)
+0.000000 MetaHookPre LoadFile(<...>/__preload__.bro)
0.000000 MetaHookPre LoadFile(<...>/hooks.bro)
0.000000 MetaHookPre LoadFile(base/bif)
0.000000 MetaHookPre LoadFile(base/init-default.bro)
@@ -1399,7 +1403,7 @@
0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])
-0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1429655378.868621, node=bro, filter=ip or not ip, init=T, success=T])
+0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1439244305.210087, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG)
@@ -1505,7 +1509,7 @@
0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])
-0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1429655378.868621, node=bro, filter=ip or not ip, init=T, success=T])
+0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1439244305.210087, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction Notice::want_pp()
0.000000 | HookCallFunction PacketFilter::build()
0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, )