Factor out the need for a tag field in Files::AnalyzerArgs record.

This cleans up internals of how analyzer instances get identified by the
tag plus any args given to it and doesn't change script code a user
would write.
This commit is contained in:
Jon Siwek 2013-07-31 09:48:19 -05:00
parent 8df4df0b8b
commit 5fa9c5865b
14 changed files with 177 additions and 107 deletions

View file

@ -228,11 +228,6 @@ redef record fa_file += {
info: Info &optional; info: Info &optional;
}; };
redef record AnalyzerArgs += {
# This is used interally for the core file analyzer api.
tag: Files::Tag &optional;
};
# Store the callbacks for protocol analyzers that have files. # Store the callbacks for protocol analyzers that have files.
global registered_protocols: table[Analyzer::Tag] of ProtoRegistration = table(); global registered_protocols: table[Analyzer::Tag] of ProtoRegistration = table();
@ -275,14 +270,12 @@ function set_timeout_interval(f: fa_file, t: interval): bool
function add_analyzer(f: fa_file, tag: Files::Tag, args: AnalyzerArgs): bool function add_analyzer(f: fa_file, tag: Files::Tag, args: AnalyzerArgs): bool
{ {
# This is to construct the correct args for the core API.
args$tag = tag;
add f$info$analyzers[Files::analyzer_name(tag)]; add f$info$analyzers[Files::analyzer_name(tag)];
if ( tag in analyzer_add_callbacks ) if ( tag in analyzer_add_callbacks )
analyzer_add_callbacks[tag](f, args); analyzer_add_callbacks[tag](f, args);
if ( ! __add_analyzer(f$id, args) ) if ( ! __add_analyzer(f$id, tag, args) )
{ {
Reporter::warning(fmt("Analyzer %s not added successfully to file %s.", tag, f$id)); Reporter::warning(fmt("Analyzer %s not added successfully to file %s.", tag, f$id));
return F; return F;
@ -297,8 +290,7 @@ function register_analyzer_add_callback(tag: Files::Tag, callback: function(f: f
function remove_analyzer(f: fa_file, tag: Files::Tag, args: AnalyzerArgs): bool function remove_analyzer(f: fa_file, tag: Files::Tag, args: AnalyzerArgs): bool
{ {
args$tag = tag; return __remove_analyzer(f$id, tag, args);
return __remove_analyzer(f$id, args);
} }
function stop(f: fa_file): bool function stop(f: fa_file): bool

View file

@ -0,0 +1,11 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "Analyzer.h"
#include "Manager.h"
file_analysis::Analyzer::~Analyzer()
{
DBG_LOG(DBG_FILE_ANALYSIS, "Destroy file analyzer %s",
file_mgr->GetAnalyzerName(tag));
Unref(args);
}

View file

@ -5,14 +5,12 @@
#include "Val.h" #include "Val.h"
#include "NetVar.h" #include "NetVar.h"
#include "analyzer/Tag.h" #include "Tag.h"
#include "file_analysis/file_analysis.bif.h" #include "file_analysis/file_analysis.bif.h"
namespace file_analysis { namespace file_analysis {
typedef int FA_Tag;
class File; class File;
/** /**
@ -25,11 +23,7 @@ public:
* Destructor. Nothing special about it. Virtual since we definitely expect * Destructor. Nothing special about it. Virtual since we definitely expect
* to delete instances of derived classes via pointers to this class. * to delete instances of derived classes via pointers to this class.
*/ */
virtual ~Analyzer() virtual ~Analyzer();
{
DBG_LOG(DBG_FILE_ANALYSIS, "Destroy file analyzer %d", tag);
Unref(args);
}
/** /**
* Subclasses may override this metod to receive file data non-sequentially. * Subclasses may override this metod to receive file data non-sequentially.
@ -76,7 +70,7 @@ public:
/** /**
* @return the analyzer type enum value. * @return the analyzer type enum value.
*/ */
FA_Tag Tag() const { return tag; } file_analysis::Tag Tag() const { return tag; }
/** /**
* @return the AnalyzerArgs associated with the analyzer. * @return the AnalyzerArgs associated with the analyzer.
@ -88,18 +82,6 @@ public:
*/ */
File* GetFile() const { return file; } File* GetFile() const { return file; }
/**
* Retrieves an analyzer tag field from full analyzer argument record.
* @param args an \c AnalyzerArgs (script-layer type) value.
* @return the analyzer tag equivalent of the 'tag' field from the
* \c AnalyzerArgs value \a args.
*/
static FA_Tag ArgsTag(const RecordVal* args)
{
using BifType::Record::Files::AnalyzerArgs;
return args->Lookup(AnalyzerArgs->FieldOffset("tag"))->AsEnum();
}
protected: protected:
/** /**
@ -108,15 +90,15 @@ protected:
* tunable options, if any, related to a particular analyzer type. * tunable options, if any, related to a particular analyzer type.
* @param arg_file the file to which the the analyzer is being attached. * @param arg_file the file to which the the analyzer is being attached.
*/ */
Analyzer(RecordVal* arg_args, File* arg_file) Analyzer(file_analysis::Tag arg_tag, RecordVal* arg_args, File* arg_file)
: tag(file_analysis::Analyzer::ArgsTag(arg_args)), : tag(arg_tag),
args(arg_args->Ref()->AsRecordVal()), args(arg_args->Ref()->AsRecordVal()),
file(arg_file) file(arg_file)
{} {}
private: private:
FA_Tag tag; /**< The particular analyzer type of the analyzer instance. */ file_analysis::Tag tag; /**< The particular type of the analyzer instance. */
RecordVal* args; /**< \c AnalyzerArgs val gives tunable analyzer params. */ RecordVal* args; /**< \c AnalyzerArgs val gives tunable analyzer params. */
File* file; /**< The file to which the analyzer is attached. */ File* file; /**< The file to which the analyzer is attached. */
}; };

View file

@ -15,6 +15,7 @@ static void analyzer_del_func(void* v)
AnalyzerSet::AnalyzerSet(File* arg_file) : file(arg_file) AnalyzerSet::AnalyzerSet(File* arg_file) : file(arg_file)
{ {
TypeList* t = new TypeList(); TypeList* t = new TypeList();
t->Append(file_mgr->GetTagEnumType());
t->Append(BifType::Record::Files::AnalyzerArgs->Ref()); t->Append(BifType::Record::Files::AnalyzerArgs->Ref());
analyzer_hash = new CompositeHash(t); analyzer_hash = new CompositeHash(t);
Unref(t); Unref(t);
@ -34,20 +35,20 @@ AnalyzerSet::~AnalyzerSet()
delete analyzer_hash; delete analyzer_hash;
} }
bool AnalyzerSet::Add(RecordVal* args) bool AnalyzerSet::Add(file_analysis::Tag tag, RecordVal* args)
{ {
HashKey* key = GetKey(args); HashKey* key = GetKey(tag, args);
if ( analyzer_map.Lookup(key) ) if ( analyzer_map.Lookup(key) )
{ {
DBG_LOG(DBG_FILE_ANALYSIS, "Instantiate analyzer %d skipped for file id" DBG_LOG(DBG_FILE_ANALYSIS, "Instantiate analyzer %s skipped for file id"
" %s: already exists", file_analysis::Analyzer::ArgsTag(args), " %s: already exists", file_mgr->GetAnalyzerName(tag),
file->GetID().c_str()); file->GetID().c_str());
delete key; delete key;
return true; return true;
} }
file_analysis::Analyzer* a = InstantiateAnalyzer(args); file_analysis::Analyzer* a = InstantiateAnalyzer(tag, args);
if ( ! a ) if ( ! a )
{ {
@ -60,10 +61,10 @@ bool AnalyzerSet::Add(RecordVal* args)
return true; return true;
} }
bool AnalyzerSet::QueueAdd(RecordVal* args) bool AnalyzerSet::QueueAdd(file_analysis::Tag tag, RecordVal* args)
{ {
HashKey* key = GetKey(args); HashKey* key = GetKey(tag, args);
file_analysis::Analyzer* a = InstantiateAnalyzer(args); file_analysis::Analyzer* a = InstantiateAnalyzer(tag, args);
if ( ! a ) if ( ! a )
{ {
@ -80,8 +81,9 @@ bool AnalyzerSet::AddMod::Perform(AnalyzerSet* set)
{ {
if ( set->analyzer_map.Lookup(key) ) if ( set->analyzer_map.Lookup(key) )
{ {
DBG_LOG(DBG_FILE_ANALYSIS, "Add analyzer %d skipped for file id" DBG_LOG(DBG_FILE_ANALYSIS, "Add analyzer %s skipped for file id"
" %s: already exists", a->Tag(), a->GetFile()->GetID().c_str()); " %s: already exists", file_mgr->GetAnalyzerName(a->Tag()),
a->GetFile()->GetID().c_str());
Abort(); Abort();
return true; return true;
@ -91,12 +93,12 @@ bool AnalyzerSet::AddMod::Perform(AnalyzerSet* set)
return true; return true;
} }
bool AnalyzerSet::Remove(const RecordVal* args) bool AnalyzerSet::Remove(file_analysis::Tag tag, RecordVal* args)
{ {
return Remove(file_analysis::Analyzer::ArgsTag(args), GetKey(args)); return Remove(tag, GetKey(tag, args));
} }
bool AnalyzerSet::Remove(FA_Tag tag, HashKey* key) bool AnalyzerSet::Remove(file_analysis::Tag tag, HashKey* key)
{ {
file_analysis::Analyzer* a = file_analysis::Analyzer* a =
(file_analysis::Analyzer*) analyzer_map.Remove(key); (file_analysis::Analyzer*) analyzer_map.Remove(key);
@ -105,22 +107,22 @@ bool AnalyzerSet::Remove(FA_Tag tag, HashKey* key)
if ( ! a ) if ( ! a )
{ {
DBG_LOG(DBG_FILE_ANALYSIS, "Skip remove analyzer %d for file id %s", DBG_LOG(DBG_FILE_ANALYSIS, "Skip remove analyzer %s for file id %s",
tag, file->GetID().c_str()); file_mgr->GetAnalyzerName(tag), file->GetID().c_str());
return false; return false;
} }
DBG_LOG(DBG_FILE_ANALYSIS, "Remove analyzer %d for file id %s", a->Tag(), DBG_LOG(DBG_FILE_ANALYSIS, "Remove analyzer %s for file id %s",
file_mgr->GetAnalyzerName(tag),
file->GetID().c_str()); file->GetID().c_str());
delete a; delete a;
return true; return true;
} }
bool AnalyzerSet::QueueRemove(const RecordVal* args) bool AnalyzerSet::QueueRemove(file_analysis::Tag tag, RecordVal* args)
{ {
HashKey* key = GetKey(args); HashKey* key = GetKey(tag, args);
FA_Tag tag = file_analysis::Analyzer::ArgsTag(args);
mod_queue.push(new RemoveMod(tag, key)); mod_queue.push(new RemoveMod(tag, key));
@ -132,18 +134,22 @@ bool AnalyzerSet::RemoveMod::Perform(AnalyzerSet* set)
return set->Remove(tag, key); return set->Remove(tag, key);
} }
HashKey* AnalyzerSet::GetKey(const RecordVal* args) const HashKey* AnalyzerSet::GetKey(file_analysis::Tag t, RecordVal* args) const
{ {
HashKey* key = analyzer_hash->ComputeHash(args, 1); ListVal* lv = new ListVal(TYPE_ANY);
lv->Append(t.AsEnumVal()->Ref());
lv->Append(args->Ref());
HashKey* key = analyzer_hash->ComputeHash(lv, 1);
Unref(lv);
if ( ! key ) if ( ! key )
reporter->InternalError("AnalyzerArgs type mismatch"); reporter->InternalError("AnalyzerArgs type mismatch");
return key; return key;
} }
file_analysis::Analyzer* AnalyzerSet::InstantiateAnalyzer(RecordVal* args) const file_analysis::Analyzer* AnalyzerSet::InstantiateAnalyzer(Tag tag,
RecordVal* args) const
{ {
FA_Tag tag = file_analysis::Analyzer::ArgsTag(args);
file_analysis::Analyzer* a = file_mgr->InstantiateAnalyzer(tag, args, file); file_analysis::Analyzer* a = file_mgr->InstantiateAnalyzer(tag, args, file);
if ( ! a ) if ( ! a )
@ -158,8 +164,8 @@ file_analysis::Analyzer* AnalyzerSet::InstantiateAnalyzer(RecordVal* args) const
void AnalyzerSet::Insert(file_analysis::Analyzer* a, HashKey* key) void AnalyzerSet::Insert(file_analysis::Analyzer* a, HashKey* key)
{ {
DBG_LOG(DBG_FILE_ANALYSIS, "Add analyzer %d for file id %s", a->Tag(), DBG_LOG(DBG_FILE_ANALYSIS, "Add analyzer %s for file id %s",
file->GetID().c_str()); file_mgr->GetAnalyzerName(a->Tag()), file->GetID().c_str());
analyzer_map.Insert(key, a); analyzer_map.Insert(key, a);
delete key; delete key;
} }

View file

@ -9,6 +9,7 @@
#include "Dict.h" #include "Dict.h"
#include "CompHash.h" #include "CompHash.h"
#include "Val.h" #include "Val.h"
#include "Tag.h"
namespace file_analysis { namespace file_analysis {
@ -38,31 +39,35 @@ public:
/** /**
* Attach an analyzer to #file immediately. * Attach an analyzer to #file immediately.
* @param tag the analyzer tag of the file analyzer to add.
* @param args an \c AnalyzerArgs value which specifies an analyzer. * @param args an \c AnalyzerArgs value which specifies an analyzer.
* @return true if analyzer was instantiated/attached, else false. * @return true if analyzer was instantiated/attached, else false.
*/ */
bool Add(RecordVal* args); bool Add(file_analysis::Tag tag, RecordVal* args);
/** /**
* Queue the attachment of an analyzer to #file. * Queue the attachment of an analyzer to #file.
* @param tag the analyzer tag of the file analyzer to add.
* @param args an \c AnalyzerArgs value which specifies an analyzer. * @param args an \c AnalyzerArgs value which specifies an analyzer.
* @return true if analyzer was able to be instantiated, else false. * @return true if analyzer was able to be instantiated, else false.
*/ */
bool QueueAdd(RecordVal* args); bool QueueAdd(file_analysis::Tag tag, RecordVal* args);
/** /**
* Remove an analyzer from #file immediately. * Remove an analyzer from #file immediately.
* @param tag the analyzer tag of the file analyzer to remove.
* @param args an \c AnalyzerArgs value which specifies an analyzer. * @param args an \c AnalyzerArgs value which specifies an analyzer.
* @return false if analyzer didn't exist and so wasn't removed, else true. * @return false if analyzer didn't exist and so wasn't removed, else true.
*/ */
bool Remove(const RecordVal* args); bool Remove(file_analysis::Tag tag, RecordVal* args);
/** /**
* Queue the removal of an analyzer from #file. * Queue the removal of an analyzer from #file.
* @param tag the analyzer tag of the file analyzer to remove.
* @param args an \c AnalyzerArgs value which specifies an analyzer. * @param args an \c AnalyzerArgs value which specifies an analyzer.
* @return true if analyzer exists at time of call, else false; * @return true if analyzer exists at time of call, else false;
*/ */
bool QueueRemove(const RecordVal* args); bool QueueRemove(file_analysis::Tag tag, RecordVal* args);
/** /**
* Perform all queued modifications to the current analyzer set. * Perform all queued modifications to the current analyzer set.
@ -91,17 +96,20 @@ protected:
/** /**
* Get a hash key which represents an analyzer instance. * Get a hash key which represents an analyzer instance.
* @param tag the file analyzer tag.
* @param args an \c AnalyzerArgs value which specifies an analyzer. * @param args an \c AnalyzerArgs value which specifies an analyzer.
* @return the hash key calculated from \a args * @return the hash key calculated from \a args
*/ */
HashKey* GetKey(const RecordVal* args) const; HashKey* GetKey(file_analysis::Tag tag, RecordVal* args) const;
/** /**
* Create an instance of a file analyzer. * Create an instance of a file analyzer.
* @param tag the tag of a file analyzer.
* @param args an \c AnalyzerArgs value which specifies an analyzer. * @param args an \c AnalyzerArgs value which specifies an analyzer.
* @return a new file analyzer instance. * @return a new file analyzer instance.
*/ */
file_analysis::Analyzer* InstantiateAnalyzer(RecordVal* args) const; file_analysis::Analyzer* InstantiateAnalyzer(file_analysis::Tag tag,
RecordVal* args) const;
/** /**
* Insert an analyzer instance in to the set. * Insert an analyzer instance in to the set.
@ -116,7 +124,7 @@ protected:
* just used for debugging messages. * just used for debugging messages.
* @param key the hash key which represents the analyzer's \c AnalyzerArgs. * @param key the hash key which represents the analyzer's \c AnalyzerArgs.
*/ */
bool Remove(FA_Tag tag, HashKey* key); bool Remove(file_analysis::Tag tag, HashKey* key);
private: private:
@ -175,14 +183,14 @@ private:
* @param arg_a an analyzer instance to add to an analyzer set. * @param arg_a an analyzer instance to add to an analyzer set.
* @param arg_key hash key representing the analyzer's \c AnalyzerArgs. * @param arg_key hash key representing the analyzer's \c AnalyzerArgs.
*/ */
RemoveMod(FA_Tag arg_tag, HashKey* arg_key) RemoveMod(file_analysis::Tag arg_tag, HashKey* arg_key)
: Modification(), tag(arg_tag), key(arg_key) {} : Modification(), tag(arg_tag), key(arg_key) {}
virtual ~RemoveMod() {} virtual ~RemoveMod() {}
virtual bool Perform(AnalyzerSet* set); virtual bool Perform(AnalyzerSet* set);
virtual void Abort() { delete key; } virtual void Abort() { delete key; }
protected: protected:
FA_Tag tag; file_analysis::Tag tag;
HashKey* key; HashKey* key;
}; };

View file

@ -11,7 +11,7 @@ set(file_analysis_SRCS
Manager.cc Manager.cc
File.cc File.cc
FileTimer.cc FileTimer.cc
Analyzer.h Analyzer.cc
AnalyzerSet.cc AnalyzerSet.cc
Component.cc Component.cc
Tag.cc Tag.cc

View file

@ -230,14 +230,14 @@ void File::ScheduleInactivityTimer() const
timer_mgr->Add(new FileTimer(network_time, id, GetTimeoutInterval())); timer_mgr->Add(new FileTimer(network_time, id, GetTimeoutInterval()));
} }
bool File::AddAnalyzer(RecordVal* args) bool File::AddAnalyzer(file_analysis::Tag tag, RecordVal* args)
{ {
return done ? false : analyzers.QueueAdd(args); return done ? false : analyzers.QueueAdd(tag, args);
} }
bool File::RemoveAnalyzer(const RecordVal* args) bool File::RemoveAnalyzer(file_analysis::Tag tag, RecordVal* args)
{ {
return done ? false : analyzers.QueueRemove(args); return done ? false : analyzers.QueueRemove(tag, args);
} }
bool File::BufferBOF(const u_char* data, uint64 len) bool File::BufferBOF(const u_char* data, uint64 len)
@ -320,7 +320,7 @@ void File::DataIn(const u_char* data, uint64 len, uint64 offset)
while ( (a = analyzers.NextEntry(c)) ) while ( (a = analyzers.NextEntry(c)) )
{ {
if ( ! a->DeliverChunk(data, len, offset) ) if ( ! a->DeliverChunk(data, len, offset) )
analyzers.QueueRemove(a->Args()); analyzers.QueueRemove(a->Tag(), a->Args());
} }
analyzers.DrainModifications(); analyzers.DrainModifications();
@ -355,7 +355,7 @@ void File::DataIn(const u_char* data, uint64 len)
{ {
if ( ! a->DeliverStream(data, len) ) if ( ! a->DeliverStream(data, len) )
{ {
analyzers.QueueRemove(a->Args()); analyzers.QueueRemove(a->Tag(), a->Args());
continue; continue;
} }
@ -363,7 +363,7 @@ void File::DataIn(const u_char* data, uint64 len)
LookupFieldDefaultCount(missing_bytes_idx); LookupFieldDefaultCount(missing_bytes_idx);
if ( ! a->DeliverChunk(data, len, offset) ) if ( ! a->DeliverChunk(data, len, offset) )
analyzers.QueueRemove(a->Args()); analyzers.QueueRemove(a->Tag(), a->Args());
} }
analyzers.DrainModifications(); analyzers.DrainModifications();
@ -388,7 +388,7 @@ void File::EndOfFile()
while ( (a = analyzers.NextEntry(c)) ) while ( (a = analyzers.NextEntry(c)) )
{ {
if ( ! a->EndOfFile() ) if ( ! a->EndOfFile() )
analyzers.QueueRemove(a->Args()); analyzers.QueueRemove(a->Tag(), a->Args());
} }
FileEvent(file_state_remove); FileEvent(file_state_remove);
@ -410,7 +410,7 @@ void File::Gap(uint64 offset, uint64 len)
while ( (a = analyzers.NextEntry(c)) ) while ( (a = analyzers.NextEntry(c)) )
{ {
if ( ! a->Undelivered(offset, len) ) if ( ! a->Undelivered(offset, len) )
analyzers.QueueRemove(a->Args()); analyzers.QueueRemove(a->Tag(), a->Args());
} }
if ( FileEventAvailable(file_gap) ) if ( FileEventAvailable(file_gap) )

View file

@ -10,6 +10,7 @@
#include "Conn.h" #include "Conn.h"
#include "Val.h" #include "Val.h"
#include "Tag.h"
#include "AnalyzerSet.h" #include "AnalyzerSet.h"
#include "BroString.h" #include "BroString.h"
@ -94,17 +95,19 @@ public:
/** /**
* Queues attaching an analyzer. Only one analyzer per type can be attached * Queues attaching an analyzer. Only one analyzer per type can be attached
* at a time unless the arguments differ. * at a time unless the arguments differ.
* @param tag the analyzer tag of the file analyzer to add.
* @param args an \c AnalyzerArgs value representing a file analyzer. * @param args an \c AnalyzerArgs value representing a file analyzer.
* @return false if analyzer can't be instantiated, else true. * @return false if analyzer can't be instantiated, else true.
*/ */
bool AddAnalyzer(RecordVal* args); bool AddAnalyzer(file_analysis::Tag tag, RecordVal* args);
/** /**
* Queues removal of an analyzer. * Queues removal of an analyzer.
* @param tag the analyzer tag of the file analyzer to remove.
* @param args an \c AnalyzerArgs value representing a file analyzer. * @param args an \c AnalyzerArgs value representing a file analyzer.
* @return true if analyzer was active at time of call, else false. * @return true if analyzer was active at time of call, else false.
*/ */
bool RemoveAnalyzer(const RecordVal* args); bool RemoveAnalyzer(file_analysis::Tag tag, RecordVal* args);
/** /**
* Pass in non-sequential data and deliver to attached analyzers. * Pass in non-sequential data and deliver to attached analyzers.

View file

@ -206,24 +206,26 @@ bool Manager::SetTimeoutInterval(const string& file_id, double interval) const
return true; return true;
} }
bool Manager::AddAnalyzer(const string& file_id, RecordVal* args) const bool Manager::AddAnalyzer(const string& file_id, file_analysis::Tag tag,
RecordVal* args) const
{ {
File* file = Lookup(file_id); File* file = Lookup(file_id);
if ( ! file ) if ( ! file )
return false; return false;
return file->AddAnalyzer(args); return file->AddAnalyzer(tag, args);
} }
bool Manager::RemoveAnalyzer(const string& file_id, const RecordVal* args) const bool Manager::RemoveAnalyzer(const string& file_id, file_analysis::Tag tag,
RecordVal* args) const
{ {
File* file = Lookup(file_id); File* file = Lookup(file_id);
if ( ! file ) if ( ! file )
return false; return false;
return file->RemoveAnalyzer(args); return file->RemoveAnalyzer(tag, args);
} }
File* Manager::GetFile(const string& file_id, Connection* conn, File* Manager::GetFile(const string& file_id, Connection* conn,
@ -367,13 +369,13 @@ bool Manager::IsDisabled(analyzer::Tag tag)
return rval; return rval;
} }
Analyzer* Manager::InstantiateAnalyzer(int tag, RecordVal* args, File* f) const Analyzer* Manager::InstantiateAnalyzer(Tag tag, RecordVal* args, File* f) const
{ {
analyzer_map_by_val::const_iterator it = analyzers_by_val.find(tag); analyzer_map_by_tag::const_iterator it = analyzers_by_tag.find(tag);
if ( it == analyzers_by_val.end() ) if ( it == analyzers_by_tag.end() )
reporter->InternalError("cannot instantiate unknown file analyzer: %d", reporter->InternalError("cannot instantiate unknown file analyzer: %s",
tag); tag.AsString().c_str());
Component* c = it->second; Component* c = it->second;
@ -384,17 +386,43 @@ Analyzer* Manager::InstantiateAnalyzer(int tag, RecordVal* args, File* f) const
return c->Factory()(args, f); return c->Factory()(args, f);
} }
const char* Manager::GetAnalyzerName(int tag) const const char* Manager::GetAnalyzerName(Val* v) const
{ {
analyzer_map_by_val::const_iterator it = analyzers_by_val.find(tag); return GetAnalyzerName(file_analysis::Tag(v->AsEnumVal()));
}
if ( it == analyzers_by_val.end() ) const char* Manager::GetAnalyzerName(file_analysis::Tag tag) const
reporter->InternalError("cannot get name of unknown file analyzer: %d", {
tag); analyzer_map_by_tag::const_iterator it = analyzers_by_tag.find(tag);
if ( it == analyzers_by_tag.end() )
reporter->InternalError("cannot get name of unknown file analyzer: %s",
tag.AsString().c_str());
return it->second->CanonicalName(); return it->second->CanonicalName();
} }
file_analysis::Tag Manager::GetAnalyzerTag(const char* name) const
{
analyzer_map_by_name::const_iterator it = analyzers_by_name.find(name);
if ( it == analyzers_by_name.end() )
return file_analysis::Tag();
return it->second->Tag();
}
file_analysis::Tag Manager::GetAnalyzerTag(Val* v) const
{
analyzer_map_by_val::const_iterator it =
analyzers_by_val.find(v->AsEnumVal()->InternalInt());
if ( it == analyzers_by_val.end() )
return file_analysis::Tag();
return it->second->Tag();
}
EnumType* Manager::GetTagEnumType() EnumType* Manager::GetTagEnumType()
{ {
return tag_enum_type; return tag_enum_type;

View file

@ -177,18 +177,22 @@ public:
* analyzers of a given type can be attached per file identifier at a time * analyzers of a given type can be attached per file identifier at a time
* as long as the arguments differ. * as long as the arguments differ.
* @param file_id the file identifier/hash. * @param file_id the file identifier/hash.
* @param tag the analyzer tag of the file analyzer to add.
* @param args a \c AnalyzerArgs value which describes a file analyzer. * @param args a \c AnalyzerArgs value which describes a file analyzer.
* @return false if the analyzer failed to be instantiated, else true. * @return false if the analyzer failed to be instantiated, else true.
*/ */
bool AddAnalyzer(const string& file_id, RecordVal* args) const; bool AddAnalyzer(const string& file_id, file_analysis::Tag tag,
RecordVal* args) const;
/** /**
* Queue removal of an analyzer for a given file identifier. * Queue removal of an analyzer for a given file identifier.
* @param file_id the file identifier/hash. * @param file_id the file identifier/hash.
* @param tag the analyzer tag of the file analyzer to remove.
* @param args a \c AnalyzerArgs value which describes a file analyzer. * @param args a \c AnalyzerArgs value which describes a file analyzer.
* @return true if the analyzer is active at the time of call, else false. * @return true if the analyzer is active at the time of call, else false.
*/ */
bool RemoveAnalyzer(const string& file_id, const RecordVal* args) const; bool RemoveAnalyzer(const string& file_id, file_analysis::Tag tag,
RecordVal* args) const;
/** /**
* Tells whether analysis for a file is active or ignored. * Tells whether analysis for a file is active or ignored.
@ -204,15 +208,43 @@ public:
* @param f The file analzer is to be associated with. * @param f The file analzer is to be associated with.
* @return The new analyzer instance or null if tag is invalid. * @return The new analyzer instance or null if tag is invalid.
*/ */
Analyzer* InstantiateAnalyzer(int tag, RecordVal* args, File* f) const; Analyzer* InstantiateAnalyzer(Tag tag, RecordVal* args, File* f) const;
/** /**
* Translates a script-level file analyzer tag in to corresponding file * Translates a script-level file analyzer tag in to corresponding file
* analyzer name. * analyzer name.
* @param tag The enum val of a file analyzer. * @param v The enum val of a file analyzer.
* @return The human-readable name of the file analyzer. * @return The human-readable name of the file analyzer.
*/ */
const char* GetAnalyzerName(int tag) const; const char* GetAnalyzerName(Val* v) const;
/**
* Translates a script-level file analyzer tag in to corresponding file
* analyzer name.
* @param tag The analyzer tag of a file analyzer.
* @return The human-readable name of the file analyzer.
*/
const char* GetAnalyzerName(file_analysis::Tag tag) const;
/**
* 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.
*/
file_analysis::Tag GetAnalyzerTag(const char* name) const;
/**
* Translates an analyzer enum value into the corresponding tag.
*
* @param v the enum val of the file analyzer.
*
* @return The tag. If the val does not correspond to a valid
* analyzer, the returned tag will evaluate to false.
*/
file_analysis::Tag GetAnalyzerTag(Val* v) const;
/** /**
* Returns the enum type that corresponds to the script-level type * Returns the enum type that corresponds to the script-level type

View file

@ -6,12 +6,15 @@
#include "EventRegistry.h" #include "EventRegistry.h"
#include "Event.h" #include "Event.h"
#include "util.h" #include "util.h"
#include "file_analysis/Manager.h"
using namespace file_analysis; using namespace file_analysis;
DataEvent::DataEvent(RecordVal* args, File* file, DataEvent::DataEvent(RecordVal* args, File* file,
EventHandlerPtr ce, EventHandlerPtr se) EventHandlerPtr ce, EventHandlerPtr se)
: file_analysis::Analyzer(args, file), chunk_event(ce), stream_event(se) : file_analysis::Analyzer(file_mgr->GetAnalyzerTag("DATA_EVENT"),
args, file),
chunk_event(ce), stream_event(se)
{ {
} }

View file

@ -4,11 +4,13 @@
#include "Extract.h" #include "Extract.h"
#include "util.h" #include "util.h"
#include "file_analysis/Manager.h"
using namespace file_analysis; using namespace file_analysis;
Extract::Extract(RecordVal* args, File* file, const string& arg_filename) Extract::Extract(RecordVal* args, File* file, const string& arg_filename)
: file_analysis::Analyzer(args, file), filename(arg_filename) : file_analysis::Analyzer(file_mgr->GetAnalyzerTag("EXTRACT"), args, file),
filename(arg_filename)
{ {
fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666); fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);

View file

@ -5,11 +5,12 @@
#include "Hash.h" #include "Hash.h"
#include "util.h" #include "util.h"
#include "Event.h" #include "Event.h"
#include "file_analysis/Manager.h"
using namespace file_analysis; using namespace file_analysis;
Hash::Hash(RecordVal* args, File* file, HashVal* hv, const char* arg_kind) Hash::Hash(RecordVal* args, File* file, HashVal* hv, const char* arg_kind)
: file_analysis::Analyzer(args, file), hash(hv), fed(false), kind(arg_kind) : file_analysis::Analyzer(file_mgr->GetAnalyzerTag(to_upper(string(arg_kind)).c_str()), args, file), hash(hv), fed(false), kind(arg_kind)
{ {
hash->Init(); hash->Init();
} }

View file

@ -16,21 +16,23 @@ function Files::__set_timeout_interval%(file_id: string, t: interval%): bool
%} %}
## :bro:see:`Files::add_analyzer`. ## :bro:see:`Files::add_analyzer`.
function Files::__add_analyzer%(file_id: string, args: any%): bool function Files::__add_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool
%{ %{
using BifType::Record::Files::AnalyzerArgs; using BifType::Record::Files::AnalyzerArgs;
RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs);
bool result = file_mgr->AddAnalyzer(file_id->CheckString(), rv); bool result = file_mgr->AddAnalyzer(file_id->CheckString(),
file_mgr->GetAnalyzerTag(tag), rv);
Unref(rv); Unref(rv);
return new Val(result, TYPE_BOOL); return new Val(result, TYPE_BOOL);
%} %}
## :bro:see:`Files::remove_analyzer`. ## :bro:see:`Files::remove_analyzer`.
function Files::__remove_analyzer%(file_id: string, args: any%): bool function Files::__remove_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool
%{ %{
using BifType::Record::Files::AnalyzerArgs; using BifType::Record::Files::AnalyzerArgs;
RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs);
bool result = file_mgr->RemoveAnalyzer(file_id->CheckString(), rv); bool result = file_mgr->RemoveAnalyzer(file_id->CheckString(),
file_mgr->GetAnalyzerTag(tag) , rv);
Unref(rv); Unref(rv);
return new Val(result, TYPE_BOOL); return new Val(result, TYPE_BOOL);
%} %}
@ -45,7 +47,7 @@ function Files::__stop%(file_id: string%): bool
## :bro:see:`Files::analyzer_name`. ## :bro:see:`Files::analyzer_name`.
function Files::__analyzer_name%(tag: Files::Tag%) : string function Files::__analyzer_name%(tag: Files::Tag%) : string
%{ %{
return new StringVal(file_mgr->GetAnalyzerName(tag->InternalInt())); return new StringVal(file_mgr->GetAnalyzerName(tag));
%} %}
module GLOBAL; module GLOBAL;