mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
support for filters and little event fix
This commit is contained in:
parent
4845c3a9a6
commit
2e3874331d
4 changed files with 210 additions and 31 deletions
|
@ -11,6 +11,16 @@ export {
|
||||||
destination: any;
|
destination: any;
|
||||||
reader: Reader &default=default_reader;
|
reader: Reader &default=default_reader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type Filter: record {
|
||||||
|
name: string;
|
||||||
|
## descriptive name. for later removal
|
||||||
|
|
||||||
|
|
||||||
|
pred: function(typ: Input::Event, left: any, right: any): bool &optional;
|
||||||
|
## decision function, that decides if an inserton, update or removal should really be executed
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@load base/input.bif
|
@load base/input.bif
|
||||||
|
|
198
src/InputMgr.cc
198
src/InputMgr.cc
|
@ -24,6 +24,11 @@ public:
|
||||||
|
|
||||||
declare(PDict, InputHash);
|
declare(PDict, InputHash);
|
||||||
|
|
||||||
|
struct InputMgr::Filter {
|
||||||
|
EnumVal* id;
|
||||||
|
string name;
|
||||||
|
Func* pred;
|
||||||
|
};
|
||||||
|
|
||||||
struct InputMgr::ReaderInfo {
|
struct InputMgr::ReaderInfo {
|
||||||
EnumVal* id;
|
EnumVal* id;
|
||||||
|
@ -39,10 +44,17 @@ struct InputMgr::ReaderInfo {
|
||||||
PDict(InputHash)* currDict;
|
PDict(InputHash)* currDict;
|
||||||
PDict(InputHash)* lastDict;
|
PDict(InputHash)* lastDict;
|
||||||
|
|
||||||
list<string>* events; // events we fire when "something" happens
|
list<string> events; // events we fire when "something" happens
|
||||||
|
list<InputMgr::Filter> filters; // events we fire when "something" happens
|
||||||
|
|
||||||
|
// ~ReaderInfo();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//void InputMgr::~ReaderInfo() {
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
struct InputReaderDefinition {
|
struct InputReaderDefinition {
|
||||||
bro_int_t type; // the type
|
bro_int_t type; // the type
|
||||||
const char *name; // descriptive name for error messages
|
const char *name; // descriptive name for error messages
|
||||||
|
@ -167,8 +179,6 @@ InputReader* InputMgr::CreateReader(EnumVal* id, RecordVal* description)
|
||||||
info->currDict = new PDict(InputHash);
|
info->currDict = new PDict(InputHash);
|
||||||
info->lastDict = new PDict(InputHash);
|
info->lastDict = new PDict(InputHash);
|
||||||
|
|
||||||
info->events = new list<string>();
|
|
||||||
|
|
||||||
int success = reader_obj->Init(source, fieldsV.size(), idxfields, fields);
|
int success = reader_obj->Init(source, fieldsV.size(), idxfields, fields);
|
||||||
if ( success == false ) {
|
if ( success == false ) {
|
||||||
RemoveReader(id);
|
RemoveReader(id);
|
||||||
|
@ -264,7 +274,7 @@ bool InputMgr::RegisterEvent(const EnumVal* id, string eventName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
i->events->push_back(eventName);
|
i->events.push_back(eventName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -276,21 +286,23 @@ bool InputMgr::UnregisterEvent(const EnumVal* id, string eventName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool erased = false;
|
//bool erased = false;
|
||||||
|
|
||||||
std::list<string>::iterator it = i->events->begin();
|
std::list<string>::iterator it = i->events.begin();
|
||||||
while ( it != i->events->end() )
|
while ( it != i->events.end() )
|
||||||
{
|
{
|
||||||
if ( *it == eventName ) {
|
if ( *it == eventName ) {
|
||||||
it = i->events->erase(it);
|
it = i->events.erase(it);
|
||||||
erased = true;
|
return true;
|
||||||
|
// erased = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return erased;
|
return false;
|
||||||
|
//return erased;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -337,6 +349,59 @@ bool InputMgr::ForceUpdate(const EnumVal* id)
|
||||||
return i->reader->Update();
|
return i->reader->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputMgr::AddFilter(EnumVal *id, RecordVal* fval) {
|
||||||
|
ReaderInfo *i = FindReader(id);
|
||||||
|
if ( i == 0 ) {
|
||||||
|
reporter->InternalError("Reader not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordType* rtype = fval->Type()->AsRecordType();
|
||||||
|
if ( ! same_type(rtype, BifType::Record::Input::Filter, 0) )
|
||||||
|
{
|
||||||
|
reporter->Error("filter argument not of right type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Val* name = fval->Lookup(rtype->FieldOffset("name"));
|
||||||
|
Val* pred = fval->Lookup(rtype->FieldOffset("pred"));
|
||||||
|
|
||||||
|
Filter filter;
|
||||||
|
filter.name = name->AsString()->CheckString();
|
||||||
|
filter.id = id->Ref()->AsEnumVal();
|
||||||
|
filter.pred = pred ? pred->AsFunc() : 0;
|
||||||
|
|
||||||
|
i->filters.push_back(filter);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputMgr::RemoveFilter(EnumVal* id, const string &name) {
|
||||||
|
ReaderInfo *i = FindReader(id);
|
||||||
|
if ( i == 0 ) {
|
||||||
|
reporter->InternalError("Reader not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::list<InputMgr::Filter>::iterator it = i->filters.begin();
|
||||||
|
while ( it != i->filters.end() )
|
||||||
|
{
|
||||||
|
if ( (*it).name == name ) {
|
||||||
|
it = i->filters.erase(it);
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Val* InputMgr::LogValToIndexVal(int num_fields, const RecordType *type, const LogVal* const *vals) {
|
Val* InputMgr::LogValToIndexVal(int num_fields, const RecordType *type, const LogVal* const *vals) {
|
||||||
Val* idxval;
|
Val* idxval;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
|
@ -398,6 +463,7 @@ void InputMgr::SendEntry(const InputReader* reader, const LogVal* const *vals) {
|
||||||
i->lastDict->Remove(idxhash);
|
i->lastDict->Remove(idxhash);
|
||||||
delete(h);
|
delete(h);
|
||||||
updated = true;
|
updated = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,6 +503,48 @@ void InputMgr::SendEntry(const InputReader* reader, const LogVal* const *vals) {
|
||||||
valval = r;
|
valval = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Val* oldval = 0;
|
||||||
|
if ( updated == true ) {
|
||||||
|
// in that case, we need the old value to send the event (if we send an event).
|
||||||
|
oldval = i->tab->Lookup(idxval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// call filters first do determine if we really add / change the entry
|
||||||
|
std::list<InputMgr::Filter>::iterator it = i->filters.begin();
|
||||||
|
while ( it != i->filters.end() ) {
|
||||||
|
if (! (*it).pred ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumVal* ev;
|
||||||
|
Ref(idxval);
|
||||||
|
Ref(valval);
|
||||||
|
|
||||||
|
if ( updated ) {
|
||||||
|
ev = new EnumVal(BifEnum::Input::EVENT_CHANGED, BifType::Enum::Input::Event);
|
||||||
|
} else {
|
||||||
|
ev = new EnumVal(BifEnum::Input::EVENT_NEW, BifType::Enum::Input::Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
val_list vl(3);
|
||||||
|
vl.append(ev);
|
||||||
|
vl.append(idxval);
|
||||||
|
vl.append(valval);
|
||||||
|
Val* v = (*it).pred->Call(&vl);
|
||||||
|
bool result = v->AsBool();
|
||||||
|
Unref(v);
|
||||||
|
|
||||||
|
if ( result == false ) {
|
||||||
|
// throw away. Hence - we quit.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//i->tab->Assign(idxval, valval);
|
//i->tab->Assign(idxval, valval);
|
||||||
HashKey* k = i->tab->ComputeHash(idxval);
|
HashKey* k = i->tab->ComputeHash(idxval);
|
||||||
if ( !k ) {
|
if ( !k ) {
|
||||||
|
@ -454,22 +562,29 @@ void InputMgr::SendEntry(const InputReader* reader, const LogVal* const *vals) {
|
||||||
|
|
||||||
i->currDict->Insert(idxhash, ih);
|
i->currDict->Insert(idxhash, ih);
|
||||||
|
|
||||||
std::list<string>::iterator it = i->events->begin();
|
// send events now that we are kind of finished.
|
||||||
while ( it != i->events->end() ) {
|
std::list<string>::iterator filter_iterator = i->events.begin();
|
||||||
|
while ( filter_iterator != i->events.end() ) {
|
||||||
EnumVal* ev;
|
EnumVal* ev;
|
||||||
if ( updated ) {
|
Ref(idxval);
|
||||||
|
|
||||||
|
if ( updated ) { // in case of update send back the old value.
|
||||||
ev = new EnumVal(BifEnum::Input::EVENT_CHANGED, BifType::Enum::Input::Event);
|
ev = new EnumVal(BifEnum::Input::EVENT_CHANGED, BifType::Enum::Input::Event);
|
||||||
|
assert ( oldval != 0 );
|
||||||
|
Ref(oldval);
|
||||||
|
SendEvent(*filter_iterator, ev, idxval, oldval);
|
||||||
} else {
|
} else {
|
||||||
ev = new EnumVal(BifEnum::Input::EVENT_NEW, BifType::Enum::Input::Event);
|
ev = new EnumVal(BifEnum::Input::EVENT_NEW, BifType::Enum::Input::Event);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Ref(idxval);
|
|
||||||
Ref(valval);
|
Ref(valval);
|
||||||
SendEvent(*it, ev, idxval, valval);
|
SendEvent(*filter_iterator, ev, idxval, valval);
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
++filter_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -484,14 +599,49 @@ void InputMgr::EndCurrentSend(const InputReader* reader) {
|
||||||
InputHash* ih;
|
InputHash* ih;
|
||||||
while ( ( ih = i->lastDict->NextEntry(c) ) ) {
|
while ( ( ih = i->lastDict->NextEntry(c) ) ) {
|
||||||
|
|
||||||
if ( i->events->size() > 0 ) {
|
if ( i->events.size() != 0 || i->filters.size() != 0 ) // we have a filter or an event
|
||||||
|
{
|
||||||
|
|
||||||
ListVal *idx = i->tab->RecoverIndex(ih->idxkey);
|
ListVal *idx = i->tab->RecoverIndex(ih->idxkey);
|
||||||
assert(idx != 0);
|
assert(idx != 0);
|
||||||
Val *val = i->tab->Lookup(idx);
|
Val *val = i->tab->Lookup(idx);
|
||||||
assert(val != 0);
|
assert(val != 0);
|
||||||
|
|
||||||
std::list<string>::iterator it = i->events->begin();
|
|
||||||
while ( it != i->events->end() ) {
|
{
|
||||||
|
// ask filter, if we want to expire this element...
|
||||||
|
std::list<InputMgr::Filter>::iterator it = i->filters.begin();
|
||||||
|
while ( it != i->filters.end() ) {
|
||||||
|
if (! (*it).pred ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumVal* ev = new EnumVal(BifEnum::Input::EVENT_REMOVED, BifType::Enum::Input::Event);
|
||||||
|
Ref(idx);
|
||||||
|
Ref(val);
|
||||||
|
|
||||||
|
val_list vl(3);
|
||||||
|
vl.append(ev);
|
||||||
|
vl.append(idx);
|
||||||
|
vl.append(val);
|
||||||
|
Val* v = (*it).pred->Call(&vl);
|
||||||
|
bool result = v->AsBool();
|
||||||
|
Unref(v);
|
||||||
|
|
||||||
|
if ( result == false ) {
|
||||||
|
// throw away. Hence - we quit and simply go to the next entry of lastDict
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
{
|
||||||
|
std::list<string>::iterator it = i->events.begin();
|
||||||
|
while ( it != i->events.end() ) {
|
||||||
Ref(idx);
|
Ref(idx);
|
||||||
Ref(val);
|
Ref(val);
|
||||||
EnumVal *ev = new EnumVal(BifEnum::Input::EVENT_REMOVED, BifType::Enum::Input::Event);
|
EnumVal *ev = new EnumVal(BifEnum::Input::EVENT_REMOVED, BifType::Enum::Input::Event);
|
||||||
|
@ -500,7 +650,9 @@ void InputMgr::EndCurrentSend(const InputReader* reader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reporter->Error("Expiring element");
|
}
|
||||||
|
|
||||||
|
//reporter->Error("Expiring element");
|
||||||
i->tab->Delete(ih->idxkey);
|
i->tab->Delete(ih->idxkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@ public:
|
||||||
bool RegisterEvent(const EnumVal* id, string eventName);
|
bool RegisterEvent(const EnumVal* id, string eventName);
|
||||||
bool UnregisterEvent(const EnumVal* id, string eventName);
|
bool UnregisterEvent(const EnumVal* id, string eventName);
|
||||||
|
|
||||||
|
bool AddFilter(EnumVal *id, RecordVal* filter);
|
||||||
|
bool RemoveFilter(EnumVal* id, const string &name);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class InputReader;
|
friend class InputReader;
|
||||||
|
@ -62,6 +65,8 @@ private:
|
||||||
|
|
||||||
string Hash(const string &input);
|
string Hash(const string &input);
|
||||||
|
|
||||||
|
struct Filter;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern InputMgr* input_mgr;
|
extern InputMgr* input_mgr;
|
||||||
|
|
|
@ -8,34 +8,46 @@ module Input;
|
||||||
%%}
|
%%}
|
||||||
|
|
||||||
type ReaderDescription: record;
|
type ReaderDescription: record;
|
||||||
|
type Filter: record;
|
||||||
|
|
||||||
function Input::__create_reader%(id: ID, description: Input::ReaderDescription%) : bool
|
function Input::__create_reader%(id: Log::ID, description: Input::ReaderDescription%) : bool
|
||||||
%{
|
%{
|
||||||
InputReader *the_reader = input_mgr->CreateReader(id->AsEnumVal(), description->AsRecordVal());
|
InputReader *the_reader = input_mgr->CreateReader(id->AsEnumVal(), description->AsRecordVal());
|
||||||
return new Val( the_reader != 0, TYPE_BOOL );
|
return new Val( the_reader != 0, TYPE_BOOL );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function Input::__force_update%(id: ID%) : bool
|
function Input::__force_update%(id: Log::ID%) : bool
|
||||||
%{
|
%{
|
||||||
bool res = input_mgr->ForceUpdate(id->AsEnumVal());
|
bool res = input_mgr->ForceUpdate(id->AsEnumVal());
|
||||||
return new Val( res, TYPE_BOOL );
|
return new Val( res, TYPE_BOOL );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function Input::__add_event%(id: ID, name: string%) : bool
|
function Input::__add_event%(id: Log::ID, name: string%) : bool
|
||||||
%{
|
%{
|
||||||
bool res = input_mgr->RegisterEvent(id->AsEnumVal(), name->AsString()->CheckString());
|
bool res = input_mgr->RegisterEvent(id->AsEnumVal(), name->AsString()->CheckString());
|
||||||
return new Val( res, TYPE_BOOL );
|
return new Val( res, TYPE_BOOL );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function Input::__remove_event%(id: ID, name: string%) : bool
|
function Input::__remove_event%(id: Log::ID, name: string%) : bool
|
||||||
%{
|
%{
|
||||||
bool res = input_mgr->UnregisterEvent(id->AsEnumVal(), name->AsString()->CheckString());
|
bool res = input_mgr->UnregisterEvent(id->AsEnumVal(), name->AsString()->CheckString());
|
||||||
return new Val( res, TYPE_BOOL );
|
return new Val( res, TYPE_BOOL );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function Input::__remove_reader%(id: ID%) : bool
|
function Input::__remove_reader%(id: Log::ID%) : bool
|
||||||
%{
|
%{
|
||||||
bool res = input_mgr->RemoveReader(id->AsEnumVal());
|
bool res = input_mgr->RemoveReader(id->AsEnumVal());
|
||||||
return new Val( res, TYPE_BOOL );
|
return new Val( res, TYPE_BOOL );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
function Input::__add_filter%(id: Log::ID, filter: Input::Filter%) : bool
|
||||||
|
%{
|
||||||
|
bool res = input_mgr->AddFilter(id->AsEnumVal(), filter->AsRecordVal());
|
||||||
|
return new Val( res, TYPE_BOOL );
|
||||||
|
%}
|
||||||
|
|
||||||
|
function Input::__remove_filter%(id: Log::ID, name: string%) : bool
|
||||||
|
%{
|
||||||
|
bool res = input_mgr->RemoveFilter(id->AsEnumVal(), name->AsString()->CheckString());
|
||||||
|
return new Val( res, TYPE_BOOL);
|
||||||
|
%}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue