mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add pattern support to input framework.
This commit is contained in:
parent
f2b7764769
commit
cfeb6f0f0d
7 changed files with 157 additions and 2 deletions
|
@ -224,7 +224,7 @@ ReaderBackend* Manager::CreateBackend(ReaderFrontend* frontend, EnumVal* tag)
|
|||
return backend;
|
||||
}
|
||||
|
||||
// Create a new input reader object to be used at whomevers leisure lateron.
|
||||
// Create a new input reader object to be used at whomevers leisure later on.
|
||||
bool Manager::CreateStream(Stream* info, RecordVal* description)
|
||||
{
|
||||
RecordType* rtype = description->Type()->AsRecordType();
|
||||
|
@ -232,7 +232,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
|
|||
|| same_type(rtype, BifType::Record::Input::EventDescription, 0)
|
||||
|| same_type(rtype, BifType::Record::Input::AnalysisDescription, 0) ) )
|
||||
{
|
||||
reporter->Error("Streamdescription argument not of right type for new input stream");
|
||||
reporter->Error("Stream description argument not of right type for new input stream");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -824,6 +824,7 @@ bool Manager::IsCompatibleType(BroType* t, bool atomic_only)
|
|||
case TYPE_INTERVAL:
|
||||
case TYPE_ENUM:
|
||||
case TYPE_STRING:
|
||||
case TYPE_PATTERN:
|
||||
return true;
|
||||
|
||||
case TYPE_RECORD:
|
||||
|
@ -2074,6 +2075,12 @@ int Manager::GetValueLength(const Value* val) const
|
|||
}
|
||||
break;
|
||||
|
||||
case TYPE_PATTERN:
|
||||
{
|
||||
length += strlen(val->val.pattern_text_val) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
{
|
||||
for ( int i = 0; i < val->val.set_val.size; i++ )
|
||||
|
@ -2193,6 +2200,14 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) const
|
|||
return length;
|
||||
}
|
||||
|
||||
case TYPE_PATTERN:
|
||||
{
|
||||
// include null-terminator
|
||||
int length = strlen(val->val.pattern_text_val) + 1;
|
||||
memcpy(data + startpos, val->val.pattern_text_val, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
{
|
||||
int length = 0;
|
||||
|
@ -2350,6 +2365,13 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ
|
|||
return subnetval;
|
||||
}
|
||||
|
||||
case TYPE_PATTERN:
|
||||
{
|
||||
RE_Matcher* re = new RE_Matcher(val->val.pattern_text_val);
|
||||
re->Compile();
|
||||
return new PatternVal(re);
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
{
|
||||
// all entries have to have the same type...
|
||||
|
@ -2492,6 +2514,13 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co
|
|||
return subnetval;
|
||||
}
|
||||
|
||||
case TYPE_PATTERN:
|
||||
{
|
||||
RE_Matcher* re = new RE_Matcher(val->val.pattern_text_val);
|
||||
re->Compile();
|
||||
return new PatternVal(re);
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
{
|
||||
TypeList* set_index;
|
||||
|
|
|
@ -126,6 +126,7 @@ struct Value {
|
|||
vec_t vector_val;
|
||||
addr_t addr_val;
|
||||
subnet_t subnet_val;
|
||||
const char* pattern_text_val;
|
||||
|
||||
struct {
|
||||
char* data;
|
||||
|
|
|
@ -325,6 +325,28 @@ threading::Value* Ascii::ParseValue(const string& s, const string& name, TypeTag
|
|||
break;
|
||||
}
|
||||
|
||||
case TYPE_PATTERN:
|
||||
{
|
||||
string cannidate = get_unescaped_string(s);
|
||||
// A string is a cannidate pattern iff it begins and ends with
|
||||
// a '/'. Rather or not the rest of the string is legal will
|
||||
// be determined later when it is given to the RE engine.
|
||||
if ( cannidate.size() >= 2 )
|
||||
{
|
||||
if ( cannidate.front() == cannidate.back() &&
|
||||
cannidate.back() == '/' )
|
||||
{
|
||||
// Remove the '/'s
|
||||
cannidate.erase(0, 1);
|
||||
cannidate.erase(cannidate.size() - 1);
|
||||
val->val.pattern_text_val = copy_string(cannidate.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
GetThread()->Error(GetThread()->Fmt("String '%s' contained no parseable pattern.", cannidate.c_str()));
|
||||
goto parse_error;
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
case TYPE_VECTOR:
|
||||
// First - common initialization
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
error: input.log/Input::READER_ASCII: String '/cat/sss' contained no parseable pattern.
|
||||
warning: input.log/Input::READER_ASCII: Could not convert line '2 /cat/sss' of input.log to Val. Ignoring line.
|
||||
error: input.log/Input::READER_ASCII: String '/foo|bar' contained no parseable pattern.
|
||||
warning: input.log/Input::READER_ASCII: Could not convert line '3 /foo|bar' of input.log to Val. Ignoring line.
|
||||
error: input.log/Input::READER_ASCII: String 'this is not a pattern' contained no parseable pattern.
|
||||
warning: input.log/Input::READER_ASCII: Could not convert line '4 this is not a pattern' of input.log to Val. Ignoring line.
|
||||
error: input.log/Input::READER_ASCII: String '/5' contained no parseable pattern.
|
||||
warning: input.log/Input::READER_ASCII: Could not convert line '5 /5' of input.log to Val. Ignoring line.
|
||||
received termination signal
|
|
@ -0,0 +1,9 @@
|
|||
T
|
||||
F
|
||||
T
|
||||
{
|
||||
[2] = [p=/^?(cat)$?/],
|
||||
[4] = [p=/^?(^oob)$?/],
|
||||
[1] = [p=/^?(dog)$?/],
|
||||
[3] = [p=/^?(foo|bar)$?/]
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
# @TEST-EXEC: zeek -b %INPUT
|
||||
# @TEST-EXEC: btest-diff .stderr
|
||||
|
||||
@TEST-START-FILE input.log
|
||||
#separator \x09
|
||||
#fields i p
|
||||
#types count pattern
|
||||
1 /d/og/
|
||||
2 /cat/sss
|
||||
3 /foo|bar
|
||||
4 this is not a pattern
|
||||
5 /5
|
||||
@TEST-END-FILE
|
||||
|
||||
redef exit_only_after_terminate = T;
|
||||
|
||||
module A;
|
||||
|
||||
type Idx: record {
|
||||
i: int;
|
||||
};
|
||||
|
||||
type Val: record {
|
||||
p: pattern;
|
||||
};
|
||||
|
||||
event kill_me()
|
||||
{
|
||||
terminate();
|
||||
}
|
||||
|
||||
global pats: table[int] of Val = table();
|
||||
|
||||
event zeek_init()
|
||||
{
|
||||
Input::add_table([$source="input.log", $name="pats", $idx=Idx, $val=Val, $destination=pats]);
|
||||
schedule 10msec { kill_me() };
|
||||
}
|
47
testing/btest/scripts/base/frameworks/input/patterns.zeek
Normal file
47
testing/btest/scripts/base/frameworks/input/patterns.zeek
Normal file
|
@ -0,0 +1,47 @@
|
|||
# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT
|
||||
# @TEST-EXEC: btest-bg-wait 10
|
||||
|
||||
|
||||
redef exit_only_after_terminate = T;
|
||||
|
||||
@TEST-START-FILE input.log
|
||||
#separator \x09
|
||||
#fields i p
|
||||
#types count pattern
|
||||
1 /dog/
|
||||
2 /cat/
|
||||
3 /foo|bar/
|
||||
4 /^oob/
|
||||
@TEST-END-FILE
|
||||
|
||||
global outfile: file;
|
||||
|
||||
module A;
|
||||
|
||||
type Idx: record {
|
||||
i: int;
|
||||
};
|
||||
|
||||
type Val: record {
|
||||
p: pattern;
|
||||
};
|
||||
|
||||
global pats: table[int] of Val = table();
|
||||
|
||||
event zeek_init()
|
||||
{
|
||||
outfile = open("../out");
|
||||
# first read in the old stuff into the table...
|
||||
Input::add_table([$source="../input.log", $name="pats", $idx=Idx, $val=Val, $destination=pats]);
|
||||
}
|
||||
|
||||
event Input::end_of_data(name: string, source:string)
|
||||
{
|
||||
print outfile, (pats[3]$p in "foobar"); # T
|
||||
print outfile, (pats[4]$p in "foobar"); # F
|
||||
print outfile, (pats[3]$p == "foo"); # T
|
||||
print outfile, pats;
|
||||
Input::remove("pats");
|
||||
close(outfile);
|
||||
terminate();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue