A set of interface changes in preparation for merging into BinPAC++

branch.
This commit is contained in:
Robin Sommer 2013-04-09 16:23:20 -07:00
parent 52cd02173d
commit 2002787c6e
27 changed files with 381 additions and 172 deletions

2
cmake

@ -1 +1 @@
Subproject commit 39c1516be5e630bd5d78082e974fae708faa4e8c
Subproject commit 8cc03d64d00676cb75a38543800ac0de192557dd

View file

@ -117,7 +117,7 @@ foreach (bift ${BIF_SRCS})
bif_target(${bift})
endforeach ()
add_custom_target(generate_standard_bifs DEPENDS ${ALL_BIF_OUTPUTS})
add_custom_target(generate_bifs DEPENDS ${ALL_BIF_OUTPUTS})
########################################################################
## BinPAC-dependent targets
@ -159,20 +159,16 @@ binpac_target(modbus.pac
## Including subdirectories.
########################################################################
set(bro_PLUGIN_OBJECT_LIBS CACHE INTERNAL "plugin object libraries" FORCE)
add_subdirectory(analyzer)
add_subdirectory(protocols)
set(bro_SUBDIRS
$<TARGET_OBJECTS:bro_analyzer>
${bro_PLUGIN_OBJECT_LIBS}
)
########################################################################
## Including plug-ins that are compiled in statically.
########################################################################
set(bro_PLUGIN_OBJECT_LIBS CACHE INTERNAL "plugin object libraries" FORCE)
add_subdirectory(protocols)
########################################################################
## bro target
@ -403,8 +399,7 @@ set(bro_SRCS
)
collect_headers(bro_HEADERS ${bro_SRCS})
add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_PLUGIN_OBJECT_LIBS} ${bro_SUBDIRS})
add_executable(bro ${bro_SRCS} ${bro_HEADERS} ${bro_SUBDIRS})
target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT})

View file

@ -413,7 +413,7 @@ analyzer::Analyzer* Connection::FindAnalyzer(analyzer::Tag tag)
return root_analyzer ? root_analyzer->FindChild(tag) : 0;
}
analyzer::Analyzer* Connection::FindAnalyzer(const string& name)
analyzer::Analyzer* Connection::FindAnalyzer(const char* name)
{
return root_analyzer->FindChild(name);
}

View file

@ -107,7 +107,7 @@ public:
analyzer::Analyzer* FindAnalyzer(analyzer::ID id);
analyzer::Analyzer* FindAnalyzer(analyzer::Tag tag); // find first in tree.
analyzer::Analyzer* FindAnalyzer(const string& name); // find first in tree.
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
TransportProto ConnTransport() const { return proto; }

View file

@ -80,8 +80,10 @@ void EventRegistry::PrintDebug()
while ( (v = handlers.NextEntry(k, c)) )
{
delete k;
fprintf(stderr, "Registered event %s (%s handler)\n", v->Name(),
v->LocalHandler()? "local" : "no");
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
v->LocalHandler()? "local" : "no",
*v ? "active" : "not active"
);
}
}

View file

@ -26,6 +26,7 @@ public:
bool IsGlobal() const { return scope != SCOPE_FUNCTION; }
bool IsExport() const { return is_export; }
void SetExport() { is_export = true; }
string ModuleName() const;

View file

@ -40,7 +40,7 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
string str(arg_analyzer);
string::size_type pos = str.find(':');
string arg = str.substr(0, pos);
analyzer = analyzer_mgr->GetAnalyzerTag(arg);
analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str());
if ( ! analyzer )
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
@ -48,7 +48,7 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
if ( pos != string::npos )
{
arg = str.substr(pos + 1);
child_analyzer = analyzer_mgr->GetAnalyzerTag(arg);
child_analyzer = analyzer_mgr->GetAnalyzerTag(arg.c_str());
if ( ! child_analyzer )
reporter->Warning("unknown analyzer '%s' specified in rule", arg.c_str());
@ -60,11 +60,11 @@ RuleActionAnalyzer::RuleActionAnalyzer(const char* arg_analyzer)
void RuleActionAnalyzer::PrintDebug()
{
if ( ! child_analyzer )
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer).c_str());
fprintf(stderr, "|%s|\n", analyzer_mgr->GetAnalyzerName(analyzer));
else
fprintf(stderr, "|%s:%s|\n",
analyzer_mgr->GetAnalyzerName(analyzer).c_str(),
analyzer_mgr->GetAnalyzerName(child_analyzer).c_str());
analyzer_mgr->GetAnalyzerName(analyzer),
analyzer_mgr->GetAnalyzerName(child_analyzer));
}

View file

@ -267,6 +267,10 @@ public:
: Analyzer(name, conn)
{ tcp = 0; }
TCP_ApplicationAnalyzer(Connection* conn)
: Analyzer(conn)
{ tcp = 0; }
virtual ~TCP_ApplicationAnalyzer() { }
// This may be nil if we are not directly associated with a TCP

View file

@ -72,28 +72,56 @@ void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
analyzer::ID Analyzer::id_counter = 0;;
const string& Analyzer::GetAnalyzerName() const
const char* Analyzer::GetAnalyzerName() const
{
assert(tag);
return analyzer_mgr->GetAnalyzerName(tag);
}
void Analyzer::SetAnalyzerTag(const Tag& arg_tag)
{
assert(! tag || tag == arg_tag);
tag = arg_tag;
}
bool Analyzer::IsAnalyzer(const char* name)
{
return analyzer_mgr->GetAnalyzerName(tag) == name;
assert(tag);
return strcmp(analyzer_mgr->GetAnalyzerName(tag), name) == 0;
}
// Used in debugging output.
static string fmt_analyzer(Analyzer* a)
{
return a->GetAnalyzerName() + fmt("[%d]", a->GetID());
return string(a->GetAnalyzerName()) + fmt("[%d]", a->GetID());
}
Analyzer::Analyzer(const char* name, Connection* arg_conn)
Analyzer::Analyzer(const char* name, Connection* conn)
{
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
if ( ! tag )
reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name);
CtorInit(tag, conn);
}
Analyzer::Analyzer(const Tag& tag, Connection* conn)
{
CtorInit(tag, conn);
}
Analyzer::Analyzer(Connection* conn)
{
CtorInit(Tag(), conn);
}
void Analyzer::CtorInit(const Tag& arg_tag, Connection* arg_conn)
{
// Don't Ref conn here to avoid circular ref'ing. It can't be deleted
// before us.
conn = arg_conn;
tag = analyzer_mgr->GetAnalyzerTag(name);
tag = arg_tag;
id = ++id_counter;
protocol_confirmed = false;
skip = false;
@ -104,10 +132,6 @@ Analyzer::Analyzer(const char* name, Connection* arg_conn)
resp_supporters = 0;
signature = 0;
output_handler = 0;
if ( ! tag )
reporter->InternalError("unknown analyzer name %s; mismatch with tag analyzer::Component?", name);
}
Analyzer::~Analyzer()
@ -417,7 +441,7 @@ void Analyzer::RemoveChildAnalyzer(ID id)
LOOP_OVER_CHILDREN(i)
if ( (*i)->id == id && ! ((*i)->finished || (*i)->removing) )
{
DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName().c_str(), id,
DBG_LOG(DBG_ANALYZER, "%s disabling child %s", GetAnalyzerName(), id,
fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
// See comment above.
(*i)->removing = true;
@ -468,7 +492,7 @@ Analyzer* Analyzer::FindChild(Tag arg_tag)
return 0;
}
Analyzer* Analyzer::FindChild(const string& name)
Analyzer* Analyzer::FindChild(const char* name)
{
Tag tag = analyzer_mgr->GetAnalyzerTag(name);
return tag ? FindChild(tag) : 0;
@ -625,9 +649,12 @@ void Analyzer::ProtocolConfirmation()
if ( protocol_confirmed )
return;
EnumVal* tval = tag.AsEnumVal();
Ref(tval);
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(tag.AsEnumVal());
vl->append(tval);
vl->append(new Val(id, TYPE_COUNT));
// We immediately raise the event so that the analyzer can quickly
@ -653,9 +680,12 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
else
r = new StringVal(reason);
EnumVal* tval = tag.AsEnumVal();
Ref(tval);
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(tag.AsEnumVal());
vl->append(tval);
vl->append(new Val(id, TYPE_COUNT));
vl->append(r);

View file

@ -61,13 +61,32 @@ public:
/**
* Constructor.
*
* @param name A name for the protocol the analyzer is parsing. The
* name must match the one the corresponding Component registers.
* @param name The name for the type of analyzer. The name must match
* the one the corresponding Component registers.
*
* @param conn The connection the analyzer is associated with.
*/
Analyzer(const char* name, Connection* conn);
/**
* Constructor.
*
* @param tag The tag for the type of analyzer. The tag must map to
* the name the corresponding Component registers.
*
* @param conn The connection the analyzer is associated with.
*/
Analyzer(const Tag& tag, Connection* conn);
/**
* Constructor. As this version of the constructor does not receive a
* name or tag, setTag() must be called before the instance can be
* used.
*
* @param conn The connection the analyzer is associated with.
*/
Analyzer(Connection* conn);
/**
* Destructor.
*/
@ -285,14 +304,22 @@ public:
/**
* Returns the tag associated with the analyzer's type.
*/
Tag GetAnalyzerTag() const { return tag; }
Tag GetAnalyzerTag() const { assert(tag); return tag; }
/**
* Sets the tag associated with the analyzer's type. Note that this
* can be called only right after construction, if the constructor
* did not receive a name or tag. The method cannot be used to change
* an existing tag.
*/
void SetAnalyzerTag(const Tag& tag);
/**
* Returns a textual description of the analyzer's type. This is
* what's passed to the constructor and usally corresponds to the
* protocol name, e.g., "HTTP".
*/
const string& GetAnalyzerName() const;
const char* GetAnalyzerName() const;
/**
* Returns true if this analyzer's type matches the name passes in.
@ -377,7 +404,7 @@ public:
* @return The first analyzer of the given type found, or null if
* none.
*/
Analyzer* FindChild(const string& name);
Analyzer* FindChild(const char* name);
/**
* Returns a list of all direct child analyzers.
@ -574,6 +601,9 @@ private:
// already Done().
void DeleteChild(analyzer_list::iterator i);
// Helper for the ctors.
void CtorInit(const Tag& tag, Connection* conn);
Tag tag;
ID id;

View file

@ -7,10 +7,10 @@ using namespace analyzer;
Tag::type_t Component::type_counter = 0;
Component::Component(std::string arg_name, factory_callback arg_factory, Tag::subtype_t arg_subtype, bool arg_enabled, bool arg_partial)
Component::Component(const char* arg_name, factory_callback arg_factory, Tag::subtype_t arg_subtype, bool arg_enabled, bool arg_partial)
: plugin::Component(plugin::component::ANALYZER)
{
name = arg_name;
name = copy_string(arg_name);
factory = arg_factory;
enabled = arg_enabled;
partial = arg_partial;
@ -18,6 +18,26 @@ Component::Component(std::string arg_name, factory_callback arg_factory, Tag::su
tag = analyzer::Tag(++type_counter, arg_subtype);
}
Component::Component(const Component& other)
: plugin::Component(Type())
{
name = copy_string(other.name);
factory = other.factory;
enabled = other.enabled;
partial = other.partial;
tag = other.tag;
}
Component::~Component()
{
delete [] name;
}
analyzer::Tag Component::Tag() const
{
return tag;
}
void Component::Describe(ODesc* d)
{
plugin::Component::Describe(d);
@ -27,3 +47,16 @@ void Component::Describe(ODesc* d)
d->Add(")");
}
Component& Component::operator=(const Component& other)
{
if ( &other != this )
{
name = copy_string(other.name);
factory = other.factory;
enabled = other.enabled;
partial = other.partial;
tag = other.tag;
}
return *this;
}

View file

@ -2,8 +2,6 @@
#ifndef ANALYZER_PLUGIN_COMPONENT_H
#define ANALYZER_PLUGIN_COMPONENT_H
#include <string>
#include "Tag.h"
#include "plugin/Component.h"
@ -21,8 +19,6 @@ class Analyzer;
*
* A plugin can provide a specific protocol analyzer by registering this
* analyzer component, describing the analyzer.
*
* This class is safe to copy by value.
*/
class Component : public plugin::Component {
public:
@ -58,13 +54,23 @@ public:
* connections has generally not seen much testing yet as virtually
* no existing analyzer supports it.
*/
Component(std::string name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true, bool partial = false);
Component(const char* name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true, bool partial = false);
/**
* Copy constructor.
*/
Component(const Component& other);
/**
* Destructor.
*/
~Component();
/**
* Returns the name of the analyzer. This name is unique across all
* analyzers and used to identify it.
*/
const std::string& Name() const { return name; }
const char* Name() const { return name; }
/**
* Returns the analyzer's factory function.
@ -74,7 +80,7 @@ public:
/**
* Returns whether the analyzer supports partial connections. Partial
* connections are those where Bro starts processing payload
* mid-stream, after missing the beginning.
* mid-stream, after missing the beginning.
*/
bool Partial() const { return partial; }
@ -89,7 +95,7 @@ public:
* generated for each new Components, and hence unique across all of
* them.
*/
analyzer::Tag Tag() const { return tag; }
analyzer::Tag Tag() const;
/**
* Enables or disables this analyzer.
@ -105,15 +111,17 @@ public:
*/
virtual void Describe(ODesc* d);
Component& operator=(const Component& other);
private:
std::string name; // The analyzer's name.
const char* name; // The analyzer's name.
factory_callback factory; // The analyzer's factory callback.
bool partial; // True if the analyzer supports partial connections.
analyzer::Tag tag; // The automatically assigned analyzer tag.
bool enabled; // True if the analyzer is enabled.
// Global counter used to generate unique tags.
static analyzer::Tag::type_t type_counter;
static analyzer::Tag::type_t type_counter;
};
}

View file

@ -108,7 +108,7 @@ void Manager::DumpDebug()
#ifdef DEBUG
DBG_LOG(DBG_ANALYZER, "Available analyzers after bro_init():");
for ( analyzer_map_by_name::const_iterator i = analyzers_by_name.begin(); i != analyzers_by_name.end(); i++ )
DBG_LOG(DBG_ANALYZER, " %s (%s)", i->second->Name().c_str(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled");
DBG_LOG(DBG_ANALYZER, " %s (%s)", i->second->Name(), IsEnabled(i->second->Tag()) ? "enabled" : "disabled");
DBG_LOG(DBG_ANALYZER, "");
DBG_LOG(DBG_ANALYZER, "Analyzers by port:");
@ -118,7 +118,7 @@ void Manager::DumpDebug()
string s;
for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ )
s += GetAnalyzerName(*j) + " ";
s += string(GetAnalyzerName(*j)) + " ";
DBG_LOG(DBG_ANALYZER, " %d/tcp: %s", i->first, s.c_str());
}
@ -128,7 +128,7 @@ void Manager::DumpDebug()
string s;
for ( tag_set::const_iterator j = i->second->begin(); j != i->second->end(); j++ )
s += GetAnalyzerName(*j) + " ";
s += string(GetAnalyzerName(*j)) + " ";
DBG_LOG(DBG_ANALYZER, " %d/udp: %s", i->first, s.c_str());
}
@ -151,10 +151,10 @@ void Manager::Done()
void Manager::RegisterAnalyzerComponent(Component* component)
{
if ( Lookup(component->Name()) )
reporter->FatalError("Analyzer %s defined more than once", component->Name().c_str());
reporter->FatalError("Analyzer %s defined more than once", component->Name());
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s (tag %s)",
component->Name().c_str(), component->Tag().AsString().c_str());
component->Name(), component->Tag().AsString().c_str());
analyzers_by_name.insert(std::make_pair(component->Name(), component));
analyzers_by_tag.insert(std::make_pair(component->Tag(), component));
@ -173,7 +173,7 @@ bool Manager::EnableAnalyzer(Tag tag)
if ( ! p )
return false;
DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name().c_str());
DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name());
p->SetEnabled(true);
return true;
@ -186,7 +186,7 @@ bool Manager::EnableAnalyzer(EnumVal* val)
if ( ! p )
return false;
DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name().c_str());
DBG_LOG(DBG_ANALYZER, "Enabling analyzer %s", p->Name());
p->SetEnabled(true);
return true;
@ -199,7 +199,7 @@ bool Manager::DisableAnalyzer(Tag tag)
if ( ! p )
return false;
DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name().c_str());
DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name());
p->SetEnabled(false);
return true;
@ -212,7 +212,7 @@ bool Manager::DisableAnalyzer(EnumVal* val)
if ( ! p )
return false;
DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name().c_str());
DBG_LOG(DBG_ANALYZER, "Disabling analyzer %s", p->Name());
p->SetEnabled(false);
return true;
@ -256,7 +256,7 @@ bool Manager::RegisterAnalyzerForPort(EnumVal* val, PortVal* port)
if ( ! p )
return false;
return RegisterAnalyzerForPort(p->Tag(), port->PortType(), port->Port());
}
@ -275,8 +275,8 @@ bool Manager::RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port
tag_set* l = LookupPort(proto, port, true);
#ifdef DEBUG
std::string name = GetAnalyzerName(tag);
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto);
const char* name = GetAnalyzerName(tag);
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name, port, proto);
#endif
l->insert(tag);
@ -288,8 +288,8 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po
tag_set* l = LookupPort(proto, port, true);
#ifdef DEBUG
std::string name = GetAnalyzerName(tag);
DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name.c_str(), port, proto);
const char* name = GetAnalyzerName(tag);
DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name, port, proto);
#endif
l->erase(tag);
@ -312,6 +312,8 @@ Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn)
if ( ! a )
reporter->InternalError("analyzer instantiation failed");
a->SetAnalyzerTag(tag);
return a;
}
@ -321,9 +323,9 @@ Analyzer* Manager::InstantiateAnalyzer(const char* name, Connection* conn)
return tag ? InstantiateAnalyzer(tag, conn) : 0;
}
const string& Manager::GetAnalyzerName(Tag tag)
const char* Manager::GetAnalyzerName(Tag tag)
{
static string error = "<error>";
static const char* error = "<error>";
if ( ! tag )
return error;
@ -336,17 +338,11 @@ const string& Manager::GetAnalyzerName(Tag tag)
return c->Name();
}
const string& Manager::GetAnalyzerName(Val* val)
const char* Manager::GetAnalyzerName(Val* val)
{
return GetAnalyzerName(Tag(val->AsEnumVal()));
}
Tag Manager::GetAnalyzerTag(const string& name)
{
Component* c = Lookup(name);
return c ? c->Tag() : Tag();
}
Tag Manager::GetAnalyzerTag(const char* name)
{
Component* c = Lookup(name);
@ -358,12 +354,6 @@ EnumType* Manager::GetTagEnumType()
return tag_enum_type;
}
Component* Manager::Lookup(const string& name)
{
analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name));
return i != analyzers_by_name.end() ? i->second : 0;
}
Component* Manager::Lookup(const char* name)
{
analyzer_map_by_name::const_iterator i = analyzers_by_name.find(to_upper(name));
@ -474,7 +464,7 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
root->AddChildAnalyzer(analyzer, false);
DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled",
analyzer_mgr->GetAnalyzerName(*i).c_str());
analyzer_mgr->GetAnalyzerName(*i));
}
}
@ -500,7 +490,7 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
root->AddChildAnalyzer(analyzer, false);
DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d",
analyzer_mgr->GetAnalyzerName(*j).c_str(), resp_port);
analyzer_mgr->GetAnalyzerName(*j), resp_port);
}
}
}
@ -622,7 +612,7 @@ void Manager::ExpireScheduledAnalyzers()
conns.erase(i);
DBG_LOG(DBG_ANALYZER, "Expiring expected analyzer %s for connection %s",
analyzer_mgr->GetAnalyzerName(a->analyzer).c_str(),
analyzer_mgr->GetAnalyzerName(a->analyzer),
fmt_conn_id(a->conn.orig, 0, a->conn.resp, a->conn.resp_p));
delete a;
@ -661,7 +651,7 @@ void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp,
void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp,
uint16 resp_p,
TransportProto proto, const string& analyzer,
TransportProto proto, const char* analyzer,
double timeout)
{
Tag tag = GetAnalyzerTag(analyzer);

View file

@ -42,6 +42,10 @@ namespace analyzer {
* sets up their initial analyzer tree, including adding the right \c PIA,
* respecting well-known ports, and tracking any analyzers specifically
* scheduled for individidual connections.
*
* Note that we keep the public interface of this class free of std::*
* classes. This allows to external analyzer code to potentially use a
* different C++ standard library.
*/
class Manager {
public:
@ -232,7 +236,7 @@ public:
*
* @return The name, or an empty string if the tag is invalid.
*/
const string& GetAnalyzerName(Tag tag);
const char* GetAnalyzerName(Tag tag);
/**
* Translates an script-level analyzer tag into corresponding
@ -243,17 +247,7 @@ public:
*
* @return The name, or an empty string if the tag is invalid.
*/
const string& GetAnalyzerName(Val* val);
/**
* Translates an analyzer name into the corresponding tag.
*
* @param name The name.
*
* @return The tag. If the name does not correspond to a valid
* analyzer, the returned tag will evaluate to false.
*/
Tag GetAnalyzerTag(const string& name);
const char* GetAnalyzerName(Val* val);
/**
* Translates an analyzer name into the corresponding tag.
@ -327,7 +321,7 @@ public:
* schedule this analyzer. Must be non-zero.
*/
void ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, uint16 resp_p,
TransportProto proto, const string& analyzer,
TransportProto proto, const char* analyzer,
double timeout);
/**

View file

@ -31,7 +31,7 @@ Tag::Tag(EnumVal* arg_val)
subtype = (i >> 31) & 0xffffffff;
}
Tag::Tag(const Tag& other) : type(other.type), subtype(other.subtype)
Tag::Tag(const Tag& other)
{
type = other.type;
subtype = other.subtype;
@ -48,6 +48,27 @@ Tag::Tag()
val = 0;
}
Tag::~Tag()
{
Unref(val);
val = 0;
}
Tag& Tag::operator=(const Tag& other)
{
if ( this != &other )
{
type = other.type;
subtype = other.subtype;
val = other.val;
if ( val )
Ref(val);
}
return *this;
}
EnumVal* Tag::AsEnumVal() const
{
if ( ! val )

View file

@ -53,6 +53,11 @@ public:
*/
Tag();
/**
* Destructor.
*/
~Tag();
/**
* Returns the tag's main type.
*/
@ -81,6 +86,11 @@ public:
*/
operator bool() const { return *this != Tag(); }
/**
* Assignment operator.
*/
Tag& operator=(const Tag& other);
/**
* Compares two tags for equality.
*/

View file

@ -235,9 +235,9 @@ void init_alternative_mode()
fprintf(fp_func_init, "\n");
fprintf(fp_func_init, "namespace plugin { namespace %s {\n", plugin);
fprintf(fp_func_init, "\n");
fprintf(fp_func_init, "std::list<std::pair<std::string, int> > __bif_%s_init()\n", name);
fprintf(fp_func_init, "std::list<std::pair<const char*, int> > __bif_%s_init()\n", name);
fprintf(fp_func_init, "\t{\n");
fprintf(fp_func_init, "\tstd::list<std::pair<std::string, int> > bifs;\n");
fprintf(fp_func_init, "\tstd::list<std::pair<const char*, int> > bifs;\n");
fprintf(fp_func_init, "\n");
}
}

View file

@ -814,8 +814,8 @@ int main(int argc, char** argv)
log_mgr = new logging::Manager();
input_mgr = new input::Manager();
plugin_mgr = new plugin::Manager();
plugin_mgr->InitPlugins();
plugin_mgr->InitPlugins();
analyzer_mgr->Init();
if ( events_file )

View file

@ -15,25 +15,22 @@
protected: \
void Init() \
{ \
plugin::Description _desc; \
_desc.name = #_name; \
_desc.version = _BRO_PLUGIN_VERSION_DEFAULT; \
_desc.api_version = BRO_PLUGIN_API_VERSION;
SetName(#_name); \
SetVersion(_BRO_PLUGIN_VERSION_DEFAULT); \
SetAPIVersion(BRO_PLUGIN_API_VERSION);
#define BRO_PLUGIN_END \
SetDescription(_desc); \
} \
}; \
\
static Plugin __plugin; \
} }
#define BRO_PLUGIN_DESCRIPTION _desc.description
#define BRO_PLUGIN_URL _desc.url
#define BRO_PLUGIN_VERSION _desc.version
#define BRO_PLUGIN_DESCRIPTION(x) SetDescription(x)
#define BRO_PLUGIN_VERSION(x) SetVersion(x)
#define BRO_PLUGIN_BIF_FILE(file) \
std::list<std::pair<std::string, int> > __bif_##file##_init(); \
std::list<std::pair<const char*, int> > __bif_##file##_init(); \
AddBifInitFunction(&__bif_##file##_init);
#define BRO_PLUGIN_ANALYZER(tag, factory) \

View file

@ -9,33 +9,86 @@
using namespace plugin;
Description::Description()
BifItem::BifItem(const BifItem& other)
{
name = "<NAME-NOT-SET>";
id = copy_string(other.id);
type = other.type;
}
// These will be reset by the BRO_PLUGIN_* macros.
version = -9999;
api_version = -9999;
BifItem& BifItem::operator=(const BifItem& other)
{
if ( this != &other )
{
id = copy_string(other.id);
type = other.type;
}
return *this;
}
BifItem::~BifItem()
{
delete [] id;
}
Plugin::Plugin()
{
name = copy_string("<NAME-NOT-SET>");
description = copy_string("");
// These will be reset by the BRO_PLUGIN_* macros.
version = -9999;
api_version = -9999;
Manager::RegisterPlugin(this);
}
Description Plugin::GetDescription() const
{
return description;
}
void Plugin::SetDescription(Description& desc)
{
description = desc;
}
Plugin::~Plugin()
{
Done();
delete [] name;
delete [] description;
}
const char* Plugin::Name()
{
return name;
}
void Plugin::SetName(const char* arg_name)
{
name = copy_string(arg_name);
}
const char* Plugin::Description()
{
return description;
}
void Plugin::SetDescription(const char* arg_description)
{
description = copy_string(arg_description);
}
int Plugin::Version()
{
return version;
}
void Plugin::SetVersion(int arg_version)
{
version = arg_version;
}
int Plugin::APIVersion()
{
return api_version;
}
void Plugin::SetAPIVersion(int arg_version)
{
api_version = arg_version;
}
void Plugin::Init()
@ -50,17 +103,26 @@ void Plugin::InitBif()
for ( bif_init_func_result::const_iterator i = items.begin(); i != items.end(); i++ )
{
BifItem bi;
bi.id = (*i).first;
bi.type = (BifItem::Type)(*i).second;
BifItem bi((*i).first, (BifItem::Type)(*i).second);
bif_items.push_back(bi);
}
}
}
const Plugin::bif_item_list& Plugin::BifItems()
Plugin::bif_item_list Plugin::BifItems()
{
return bif_items;
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()
{
return bif_item_list();
}
void Plugin::Done()
@ -89,24 +151,18 @@ void Plugin::AddBifInitFunction(bif_init_func c)
void Plugin::Describe(ODesc* d)
{
d->Add("Plugin: ");
d->Add(description.name);
d->Add(name);
if ( description.description.size() )
if ( description && *description )
{
d->Add(" - ");
d->Add(description.description);
d->Add(description);
}
if ( description.version != BRO_PLUGIN_VERSION_BUILTIN )
if ( version != BRO_PLUGIN_VERSION_BUILTIN )
{
d->Add(" (version ");
d->Add(description.version);
if ( description.url.size() )
{
d->Add(", from ");
d->Add(description.url);
}
d->Add(version);
d->Add(")");
}
@ -125,11 +181,13 @@ void Plugin::Describe(ODesc* d)
d->Add("\n");
}
for ( bif_item_list::const_iterator i = bif_items.begin(); i != bif_items.end(); i++ )
bif_item_list items = BifItems();
for ( bif_item_list::const_iterator i = items.begin(); i != items.end(); i++ )
{
const char* type = 0;
switch ( (*i).type ) {
switch ( (*i).GetType() ) {
case BifItem::FUNCTION:
type = "Function";
break;
@ -158,7 +216,7 @@ void Plugin::Describe(ODesc* d)
d->Add("[");
d->Add(type);
d->Add("] ");
d->Add((*i).id);
d->Add((*i).GetID());
d->Add("\n");
}
}

View file

@ -14,25 +14,30 @@ namespace plugin {
class Manager;
class Component;
struct Description {
std::string name;
std::string description;
std::string url;
int version;
int api_version;
Description();
void Describe(ODesc* d);
};
struct BifItem {
class BifItem {
public:
// Values must match the integers bifcl generates.
enum Type { FUNCTION = 1, EVENT = 2, CONSTANT = 3, GLOBAL = 4, TYPE = 5 };
std::string id;
BifItem(const std::string& id, Type type);
BifItem(const BifItem& other);
BifItem& operator=(const BifItem& other);
~BifItem();
const char* GetID() const { return id; }
Type GetType() const { return type; }
private:
const char* id;
Type type;
};
inline BifItem::BifItem(const std::string& arg_id, Type arg_type)
{
id = copy_string(arg_id.c_str());
type = arg_type;
}
class Plugin {
public:
typedef std::list<Component *> component_list;
@ -41,15 +46,17 @@ public:
Plugin();
virtual ~Plugin();
Description GetDescription() const;
void SetDescription(Description& desc);
const char* Name();
const char* Description();
int Version();
int APIVersion();
component_list Components();
void InitBif();
// Must be called after InitBif() only.
const bif_item_list& BifItems();
bif_item_list BifItems();
virtual void Init();
virtual void Done();
@ -57,19 +64,42 @@ public:
void Describe(ODesc* d);
protected:
typedef std::list<std::pair<const char*, int> > bif_init_func_result;
typedef bif_init_func_result (*bif_init_func)();
void SetName(const char* name);
void SetDescription(const char* descr);
void SetVersion(int version);
void SetAPIVersion(int version);
/**
* Takes ownership.
*/
void AddComponent(Component* c);
typedef std::list<std::pair<std::string, int> > bif_init_func_result;
typedef bif_init_func_result (*bif_init_func)();
/**
* Can be overriden by derived class to inform the plugin about
* further BiF items they provide on their own (i.e., outside of the
* standard mechanism processing *.bif files automatically.). This
* information is for information purpuses only and will show up in
* the result of BifItem() as well as in the Describe() output.
*/
virtual bif_item_list CustomBifItems() ;
/**
* Internal function adding an entry point for registering
* auto-generated BiFs.
*/
void AddBifInitFunction(bif_init_func c);
private:
typedef std::list<bif_init_func> bif_init_func_list;
plugin::Description description;
const char* name;
const char* description;
int version;
int api_version;
component_list components;
bif_item_list bif_items;
bif_init_func_list bif_inits;

View file

@ -50,11 +50,9 @@ BuiltinAnalyzers builtin_analyzers;
void BuiltinAnalyzers::Init()
{
plugin::Description desc;
desc.name = "Core-Analyzers";
desc.description = "Built-in protocol analyzers";
desc.version = BRO_PLUGIN_VERSION_BUILTIN;
SetDescription(desc);
SetName("Core-Analyzers");
SetDescription("Built-in protocol analyzers");
SetVersion(BRO_PLUGIN_VERSION_BUILTIN);
DEFINE_ANALYZER("PIA_TCP", PIA_TCP::InstantiateAnalyzer);
DEFINE_ANALYZER("PIA_UDP", PIA_UDP::InstantiateAnalyzer);

View file

@ -16,7 +16,7 @@
#include "plugin/Plugin.h"
BRO_PLUGIN_BEGIN(HTTP)
BRO_PLUGIN_DESCRIPTION = "HTTP Analyzer";
BRO_PLUGIN_DESCRIPTION("HTTP Analyzer");
BRO_PLUGIN_ANALYZER("HTTP", HTTP_Analyzer::InstantiateAnalyzer);
BRO_PLUGIN_BIF_FILE(events);
BRO_PLUGIN_BIF_FILE(functions);

View file

@ -4,7 +4,7 @@
#include "SSL.h"
BRO_PLUGIN_BEGIN(SSL)
BRO_PLUGIN_DESCRIPTION = "SSL Analyzer";
BRO_PLUGIN_DESCRIPTION("SSL Analyzer");
BRO_PLUGIN_ANALYZER("SSL", SSL_Analyzer::InstantiateAnalyzer);
BRO_PLUGIN_BIF_FILE(events);
BRO_PLUGIN_END

View file

@ -4,7 +4,7 @@
#include "Syslog.h"
BRO_PLUGIN_BEGIN(Syslog)
BRO_PLUGIN_DESCRIPTION = "Syslog Analyzer (UDP-only currently)";
BRO_PLUGIN_DESCRIPTION("Syslog Analyzer (UDP-only currently)");
BRO_PLUGIN_ANALYZER("SYSLOG", Syslog_Analyzer::InstantiateAnalyzer);
BRO_PLUGIN_BIF_FILE(events);
BRO_PLUGIN_END

View file

@ -1042,6 +1042,7 @@ static void check_dpd_config_changes()
valdesc.PushIndent();
v->Describe(&valdesc);
#if 0
if ( tag < AnalyzerTag::Error || tag > AnalyzerTag::LastAnalyzer )
{
fprintf(stderr, "Warning: skipped bad analyzer tag: %i\n", tag);
@ -1049,8 +1050,9 @@ static void check_dpd_config_changes()
}
last_reST_doc->AddPortAnalysis(
Analyzer::GetTagName((AnalyzerTag::Tag)tag),
Analyzer::GetTagName((AnalyzerTag)tag),
valdesc.Description());
#endif
}
dpd_table->RemoveAll();

View file

@ -5,8 +5,14 @@
// Expose C99 functionality from inttypes.h, which would otherwise not be
// available in C++.
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <inttypes.h>
#include <stdint.h>