Checkpointing the dynamic plugin code.

This is essentially the code from the dynamic-plugin branch except for
some pieces that I have split out into separate, earlier commits.

I'm going to updatre things in this branch going forward.
This commit is contained in:
Robin Sommer 2013-11-26 11:23:25 -08:00
parent 7412470d66
commit 555df1e7ea
43 changed files with 1306 additions and 110 deletions

View file

@ -0,0 +1,6 @@
Plugin: Demo::Foo - A Foo test analyzer (dynamic, version 1)
[Analyzer] Foo (ANALYZER_FOO, enabled)
[Event] foo_message
===
foo_message, [orig_h=::1, orig_p=37927/tcp, resp_h=::1, resp_p=4242/tcp], Hello, Foo!^J

View file

@ -0,0 +1,11 @@
Plugin: Demo::Foo - <Insert brief description of plugin> (dynamic, version 1)
[Event] plugin_event
[Function] hello_plugin_world
===
plugin: automatically loaded at startup
calling bif, Hello from the plugin!
===
plugin: automatically loaded at startup
calling bif, Hello from the plugin!
plugin: manually loaded

Binary file not shown.

View file

@ -0,0 +1,20 @@
project(Bro-Plugin-Demo-Foo)
cmake_minimum_required(VERSION 2.6.3)
if ( NOT BRO_DIST )
message(FATAL_ERROR "BRO_DIST not set")
endif ()
set(CMAKE_MODULE_PATH ${BRO_DIST}/cmake)
include(BroPlugin)
bro_plugin_begin(Demo Foo)
bro_plugin_cc(src/Plugin.cc)
bro_plugin_cc(src/Foo.cc)
bro_plugin_bif(src/events.bif)
bro_plugin_bif(src/functions.bif)
bro_plugin_pac(src/foo.pac src/foo-protocol.pac src/foo-analyzer.pac)
bro_plugin_end()

View file

@ -0,0 +1,2 @@
A place-holder file that marks a directory as holding a Bro plugin.
Content is ignored.

View file

@ -0,0 +1,7 @@
const ports = { 4242/tcp };
event bro_init() &priority=5
{
Analyzer::register_for_ports(Analyzer::ANALYZER_FOO, ports);
}

View file

@ -0,0 +1 @@
@load Demo/Foo/base/main

View file

@ -0,0 +1,59 @@
#include "Foo.h"
#include "foo_pac.h"
#include "events.bif.h"
#include <analyzer/protocol/tcp/TCP_Reassembler.h>
using namespace analyzer::Foo;
Foo_Analyzer::Foo_Analyzer(Connection* conn)
: tcp::TCP_ApplicationAnalyzer("Foo", conn)
{
interp = new binpac::Foo::Foo_Conn(this);
}
Foo_Analyzer::~Foo_Analyzer()
{
delete interp;
}
void Foo_Analyzer::Done()
{
tcp::TCP_ApplicationAnalyzer::Done();
interp->FlowEOF(true);
interp->FlowEOF(false);
}
void Foo_Analyzer::EndpointEOF(bool is_orig)
{
tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
interp->FlowEOF(is_orig);
}
void Foo_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
{
tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
assert(TCP());
if ( TCP()->IsPartial() )
// punt on partial.
return;
try
{
interp->NewData(orig, data, data + len);
}
catch ( const binpac::Exception& e )
{
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
}
}
void Foo_Analyzer::Undelivered(int seq, int len, bool orig)
{
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
interp->NewGap(orig, len);
}

View file

@ -0,0 +1,31 @@
#ifndef BRO_PLUGIN_DEMO_FOO_H
#define BRO_PLUGIN_DEMO_FOO_H
#include "analyzer/protocol/tcp/TCP.h"
#include "analyzer/protocol/pia/PIA.h"
namespace binpac { namespace Foo { class Foo_Conn; } }
namespace analyzer { namespace Foo {
class Foo_Analyzer : public tcp::TCP_ApplicationAnalyzer {
public:
Foo_Analyzer(Connection* conn);
~Foo_Analyzer();
virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new Foo_Analyzer(conn); }
protected:
binpac::Foo::Foo_Conn* interp;
};
} } // namespace analyzer::*
#endif

View file

@ -0,0 +1,12 @@
#include <plugin/Plugin.h>
#include "Foo.h"
BRO_PLUGIN_BEGIN(Demo, Foo)
BRO_PLUGIN_VERSION(1);
BRO_PLUGIN_DESCRIPTION("A Foo test analyzer");
BRO_PLUGIN_ANALYZER("Foo", Foo::Foo_Analyzer);
BRO_PLUGIN_BIF_FILE(events);
BRO_PLUGIN_BIF_FILE(functions);
BRO_PLUGIN_END

View file

@ -0,0 +1,2 @@
event foo_message%(c: connection, data: string%);

View file

@ -0,0 +1,15 @@
refine connection Foo_Conn += {
function Foo_data(msg: Foo_Message): bool
%{
StringVal* data = new StringVal(${msg.data}.length(), (const char*) ${msg.data}.data());
BifEvent::generate_foo_message(bro_analyzer(), bro_analyzer()->Conn(), data);
return true;
%}
};
refine typeattr Foo_Message += &let {
proc: bool = $context.connection.Foo_data(this);
};

View file

@ -0,0 +1,4 @@
type Foo_Message(is_orig: bool) = record {
data: bytestring &restofdata;
};

View file

@ -0,0 +1,26 @@
%include binpac.pac
%include bro.pac
%extern{
#include "Foo.h"
#include "events.bif.h"
%}
analyzer Foo withcontext {
connection: Foo_Conn;
flow: Foo_Flow;
};
connection Foo_Conn(bro_analyzer: BroAnalyzer) {
upflow = Foo_Flow(true);
downflow = Foo_Flow(false);
};
%include foo-protocol.pac
flow Foo_Flow(is_orig: bool) {
datagram = Foo_Message(is_orig) withcontext(connection, this);
};
%include foo-analyzer.pac

View file

@ -0,0 +1,13 @@
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
# @TEST-EXEC: cp -r %DIR/analyzer-plugin/* .
# @TEST-EXEC: make BRO=${DIST}
# @TEST-EXEC: BROPLUGINS=`pwd` bro -NN | awk '/^Plugin:.*Demo/ {p=1; print; next} /^Plugin:/{p=0} p==1{print}' >>output
# @TEST-EXEC: echo === >>output
# @TEST-EXEC: BROPLUGINS=`pwd` bro -r $TRACES/port4242.trace %INPUT >>output
# @TEST-EXEC: btest-diff output
event foo_message(c: connection, data: string)
{
print "foo_message", c$id, data;
}

View file

@ -0,0 +1,45 @@
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
# @TEST-EXEC: bash %INPUT
# @TEST-EXEC: make BRO=${DIST}
# @TEST-EXEC: BROPLUGINS=`pwd` bro -NN | awk '/^Plugin:.*Demo/ {p=1; print; next} /^Plugin:/{p=0} p==1{print}' >>output
# @TEST-EXEC: echo === >>output
# @TEST-EXEC: BROPLUGINS=`pwd` bro -r $TRACES/empty.trace >>output
# @TEST-EXEC: echo === >>output
# @TEST-EXEC: BROPLUGINS=`pwd` bro demo/foo -r $TRACES/empty.trace >>output
# @TEST-EXEC: btest-diff output
cat >scripts/__load__.bro <<EOF
@load ./demo/foo/base/at-startup.bro
EOF
cat >scripts/demo/foo/__load__.bro <<EOF
@load ./manually.bro
EOF
cat >scripts/demo/foo/manually.bro <<EOF
event bro_init()
{
print "plugin: manually loaded";
}
EOF
mkdir -p scripts/demo/foo/base/
cat >scripts/demo/foo/base/at-startup.bro <<EOF
event bro_init()
{
print "plugin: automatically loaded at startup";
print "calling bif", hello_plugin_world();
}
EOF
cat >src/functions.bif <<EOF
function hello_plugin_world%(%): string
%{
return new StringVal("Hello from the plugin!");
%}
EOF
cat >src/events.bif <<EOF
event plugin_event%(foo: count%);
EOF