mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
The logging systems now supports fields of type set[<atomic_type>].
This commit is contained in:
parent
52c54859b6
commit
c6e3174bc8
7 changed files with 364 additions and 109 deletions
171
src/LogMgr.cc
171
src/LogMgr.cc
|
@ -63,6 +63,21 @@ struct LogMgr::Stream {
|
||||||
~Stream();
|
~Stream();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LogVal::~LogVal()
|
||||||
|
{
|
||||||
|
if ( type == TYPE_STRING && present )
|
||||||
|
delete val.string_val;
|
||||||
|
|
||||||
|
if ( type == TYPE_TABLE && present )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < val.set_val.size; i++ )
|
||||||
|
delete val.set_val.vals[i];
|
||||||
|
|
||||||
|
delete [] val.set_val.vals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LogVal::Read(SerializationFormat* fmt)
|
bool LogVal::Read(SerializationFormat* fmt)
|
||||||
{
|
{
|
||||||
int ty;
|
int ty;
|
||||||
|
@ -139,6 +154,23 @@ bool LogVal::Read(SerializationFormat* fmt)
|
||||||
return fmt->Read(val.string_val, "string");
|
return fmt->Read(val.string_val, "string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TYPE_TABLE:
|
||||||
|
{
|
||||||
|
if ( ! fmt->Read(&val.set_val.size, "set_size") )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
val.set_val.vals = new LogVal* [val.set_val.size];
|
||||||
|
|
||||||
|
for ( int i = 0; i < val.set_val.size; ++i )
|
||||||
|
{
|
||||||
|
val.set_val.vals[i] = new LogVal;
|
||||||
|
if ( ! val.set_val.vals[i]->Read(fmt) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
internal_error(::fmt("unsupported type %s in LogVal::Write", type_name(type)));
|
internal_error(::fmt("unsupported type %s in LogVal::Write", type_name(type)));
|
||||||
}
|
}
|
||||||
|
@ -205,6 +237,20 @@ bool LogVal::Write(SerializationFormat* fmt) const
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
return fmt->Write(*val.string_val, "string");
|
return fmt->Write(*val.string_val, "string");
|
||||||
|
|
||||||
|
case TYPE_TABLE:
|
||||||
|
{
|
||||||
|
if ( ! fmt->Write(val.set_val.size, "set_size") )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for ( int i = 0; i < val.set_val.size; ++i )
|
||||||
|
{
|
||||||
|
if ( ! val.set_val.vals[i]->Write(fmt) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
internal_error(::fmt("unsupported type %s in LogVal::REad", type_name(type)));
|
internal_error(::fmt("unsupported type %s in LogVal::REad", type_name(type)));
|
||||||
}
|
}
|
||||||
|
@ -402,14 +448,18 @@ bool LogMgr::TraverseRecord(Filter* filter, RecordType* rt, TableVal* include, T
|
||||||
// Recurse.
|
// Recurse.
|
||||||
if ( ! TraverseRecord(filter, t->AsRecordType(), include, exclude, new_path, new_indices) )
|
if ( ! TraverseRecord(filter, t->AsRecordType(), include, exclude, new_path, new_indices) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else if ( t->Tag() == TYPE_TABLE && t->AsTableType()->IsSet() )
|
||||||
{
|
{
|
||||||
|
// That's ok, handle it with all the other types below.
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
run_time("unsupported field type for log column");
|
run_time("unsupported field type for log column");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If include fields are specified, only include if explicitly listed.
|
// If include fields are specified, only include if explicitly listed.
|
||||||
|
@ -701,6 +751,70 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogVal* LogMgr::ValToLogVal(Val* val)
|
||||||
|
{
|
||||||
|
LogVal* lval = new LogVal(val->Type()->Tag());
|
||||||
|
|
||||||
|
switch ( lval->type ) {
|
||||||
|
case TYPE_BOOL:
|
||||||
|
case TYPE_INT:
|
||||||
|
case TYPE_ENUM:
|
||||||
|
lval->val.int_val = val->InternalInt();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_COUNT:
|
||||||
|
case TYPE_COUNTER:
|
||||||
|
lval->val.uint_val = val->InternalUnsigned();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_PORT:
|
||||||
|
lval->val.uint_val = val->AsPortVal()->Port();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_SUBNET:
|
||||||
|
lval->val.subnet_val = *val->AsSubNet();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_NET:
|
||||||
|
case TYPE_ADDR:
|
||||||
|
{
|
||||||
|
addr_type t = val->AsAddr();
|
||||||
|
copy_addr(&t, &lval->val.addr_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
case TYPE_TIME:
|
||||||
|
case TYPE_INTERVAL:
|
||||||
|
lval->val.double_val = val->InternalDouble();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_STRING:
|
||||||
|
{
|
||||||
|
const BroString* s = val->AsString();
|
||||||
|
lval->val.string_val = new string((const char*) s->Bytes(), s->Len());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_TABLE:
|
||||||
|
{
|
||||||
|
ListVal* set = val->AsTableVal()->ConvertToPureList();
|
||||||
|
lval->val.set_val.size = set->Length();
|
||||||
|
lval->val.set_val.vals = new LogVal* [lval->val.set_val.size];
|
||||||
|
|
||||||
|
for ( int i = 0; i < lval->val.set_val.size; i++ )
|
||||||
|
lval->val.set_val.vals[i] = ValToLogVal(set->Index(i));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
internal_error("unsupported type for log_write");
|
||||||
|
}
|
||||||
|
|
||||||
|
return lval;
|
||||||
|
}
|
||||||
|
|
||||||
LogVal** LogMgr::RecordToFilterVals(Filter* filter, RecordVal* columns)
|
LogVal** LogMgr::RecordToFilterVals(Filter* filter, RecordVal* columns)
|
||||||
{
|
{
|
||||||
LogVal** vals = new LogVal*[filter->num_fields];
|
LogVal** vals = new LogVal*[filter->num_fields];
|
||||||
|
@ -727,55 +841,8 @@ LogVal** LogMgr::RecordToFilterVals(Filter* filter, RecordVal* columns)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! val )
|
if ( val )
|
||||||
continue;
|
vals[i] = ValToLogVal(val);
|
||||||
|
|
||||||
vals[i] = new LogVal(type);
|
|
||||||
|
|
||||||
switch ( val->Type()->Tag() ) {
|
|
||||||
case TYPE_BOOL:
|
|
||||||
case TYPE_INT:
|
|
||||||
case TYPE_ENUM:
|
|
||||||
vals[i]->val.int_val = val->InternalInt();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_COUNT:
|
|
||||||
case TYPE_COUNTER:
|
|
||||||
vals[i]->val.uint_val = val->InternalUnsigned();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_PORT:
|
|
||||||
vals[i]->val.uint_val = val->AsPortVal()->Port();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
|
||||||
vals[i]->val.subnet_val = *val->AsSubNet();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_NET:
|
|
||||||
case TYPE_ADDR:
|
|
||||||
{
|
|
||||||
addr_type t = val->AsAddr();
|
|
||||||
copy_addr(&t, &vals[i]->val.addr_val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TYPE_DOUBLE:
|
|
||||||
case TYPE_TIME:
|
|
||||||
case TYPE_INTERVAL:
|
|
||||||
vals[i]->val.double_val = val->InternalDouble();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_STRING:
|
|
||||||
{
|
|
||||||
const BroString* s = val->AsString();
|
|
||||||
vals[i]->val.string_val = new string((const char*) s->Bytes(), s->Len());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
internal_error("unsupported type for log_write");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vals;
|
return vals;
|
||||||
|
|
|
@ -36,17 +36,20 @@ struct LogVal {
|
||||||
|
|
||||||
// The following union is a subset of BroValUnion, including only the
|
// The following union is a subset of BroValUnion, including only the
|
||||||
// atomic types.
|
// atomic types.
|
||||||
union {
|
struct set_t { bro_int_t size; LogVal** vals; };
|
||||||
|
|
||||||
|
union _val {
|
||||||
bro_int_t int_val;
|
bro_int_t int_val;
|
||||||
bro_uint_t uint_val;
|
bro_uint_t uint_val;
|
||||||
addr_type addr_val;
|
addr_type addr_val;
|
||||||
subnet_type subnet_val;
|
subnet_type subnet_val;
|
||||||
double double_val;
|
double double_val;
|
||||||
string* string_val;
|
string* string_val;
|
||||||
|
set_t set_val;
|
||||||
} val;
|
} val;
|
||||||
|
|
||||||
LogVal(TypeTag arg_type = TYPE_ERROR, bool arg_present = true) : type(arg_type), present(arg_present) {}
|
LogVal(TypeTag arg_type = TYPE_ERROR, bool arg_present = true) : type(arg_type), present(arg_present) {}
|
||||||
~LogVal() { if ( type == TYPE_STRING && present ) delete val.string_val; }
|
~LogVal();
|
||||||
|
|
||||||
bool Read(SerializationFormat* fmt);
|
bool Read(SerializationFormat* fmt);
|
||||||
bool Write(SerializationFormat* fmt) const;
|
bool Write(SerializationFormat* fmt) const;
|
||||||
|
@ -97,6 +100,7 @@ private:
|
||||||
struct WriterInfo;
|
struct WriterInfo;
|
||||||
|
|
||||||
bool TraverseRecord(Filter* filter, RecordType* rt, TableVal* include, TableVal* exclude, string path, list<int> indices);
|
bool TraverseRecord(Filter* filter, RecordType* rt, TableVal* include, TableVal* exclude, string path, list<int> indices);
|
||||||
|
LogVal* ValToLogVal(Val* val);
|
||||||
LogVal** RecordToFilterVals(Filter* filter, RecordVal* columns);
|
LogVal** RecordToFilterVals(Filter* filter, RecordVal* columns);
|
||||||
Stream* FindStream(EnumVal* id);
|
Stream* FindStream(EnumVal* id);
|
||||||
void RemoveDisabledWriters(Stream* stream);
|
void RemoveDisabledWriters(Stream* stream);
|
||||||
|
|
|
@ -16,6 +16,10 @@ LogWriterAscii::LogWriterAscii()
|
||||||
separator = new char[separator_len];
|
separator = new char[separator_len];
|
||||||
memcpy(separator, BifConst::LogAscii::separator->Bytes(), separator_len);
|
memcpy(separator, BifConst::LogAscii::separator->Bytes(), separator_len);
|
||||||
|
|
||||||
|
set_separator_len = BifConst::LogAscii::set_separator->Len();
|
||||||
|
set_separator = new char[set_separator_len];
|
||||||
|
memcpy(set_separator, BifConst::LogAscii::set_separator->Bytes(), set_separator_len);
|
||||||
|
|
||||||
empty_field_len = BifConst::LogAscii::empty_field->Len();
|
empty_field_len = BifConst::LogAscii::empty_field->Len();
|
||||||
empty_field = new char[empty_field_len];
|
empty_field = new char[empty_field_len];
|
||||||
memcpy(empty_field, BifConst::LogAscii::empty_field->Bytes(), empty_field_len);
|
memcpy(empty_field, BifConst::LogAscii::empty_field->Bytes(), empty_field_len);
|
||||||
|
@ -27,6 +31,7 @@ LogWriterAscii::LogWriterAscii()
|
||||||
header_prefix_len = BifConst::LogAscii::header_prefix->Len();
|
header_prefix_len = BifConst::LogAscii::header_prefix->Len();
|
||||||
header_prefix = new char[header_prefix_len];
|
header_prefix = new char[header_prefix_len];
|
||||||
memcpy(header_prefix, BifConst::LogAscii::header_prefix->Bytes(), header_prefix_len);
|
memcpy(header_prefix, BifConst::LogAscii::header_prefix->Bytes(), header_prefix_len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogWriterAscii::~LogWriterAscii()
|
LogWriterAscii::~LogWriterAscii()
|
||||||
|
@ -35,6 +40,7 @@ LogWriterAscii::~LogWriterAscii()
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
delete [] separator;
|
delete [] separator;
|
||||||
|
delete [] set_separator;
|
||||||
delete [] empty_field;
|
delete [] empty_field;
|
||||||
delete [] unset_field;
|
delete [] unset_field;
|
||||||
delete [] header_prefix;
|
delete [] header_prefix;
|
||||||
|
@ -89,6 +95,86 @@ void LogWriterAscii::DoFinish()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LogWriterAscii::DoWriteOne(ODesc* desc, LogVal* val, const LogField* field)
|
||||||
|
{
|
||||||
|
if ( ! val->present )
|
||||||
|
{
|
||||||
|
desc->AddN(unset_field, unset_field_len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( val->type ) {
|
||||||
|
|
||||||
|
case TYPE_BOOL:
|
||||||
|
desc->Add(val->val.int_val ? "T" : "F");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_INT:
|
||||||
|
case TYPE_ENUM:
|
||||||
|
desc->Add(val->val.int_val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_COUNT:
|
||||||
|
case TYPE_COUNTER:
|
||||||
|
case TYPE_PORT:
|
||||||
|
desc->Add(val->val.uint_val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_SUBNET:
|
||||||
|
desc->Add(dotted_addr(val->val.subnet_val.net));
|
||||||
|
desc->Add("/");
|
||||||
|
desc->Add(val->val.subnet_val.width);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_NET:
|
||||||
|
case TYPE_ADDR:
|
||||||
|
desc->Add(dotted_addr(val->val.addr_val));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
case TYPE_TIME:
|
||||||
|
case TYPE_INTERVAL:
|
||||||
|
desc->Add(val->val.double_val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_STRING:
|
||||||
|
{
|
||||||
|
int size = val->val.string_val->size();
|
||||||
|
if ( size )
|
||||||
|
desc->AddN(val->val.string_val->data(), val->val.string_val->size());
|
||||||
|
else
|
||||||
|
desc->AddN(empty_field, empty_field_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_TABLE:
|
||||||
|
{
|
||||||
|
if ( ! val->val.set_val.size )
|
||||||
|
{
|
||||||
|
desc->AddN(empty_field, empty_field_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int j = 0; j < val->val.set_val.size; j++ )
|
||||||
|
{
|
||||||
|
if ( j > 0 )
|
||||||
|
desc->AddN(set_separator, set_separator_len);
|
||||||
|
|
||||||
|
if ( ! DoWriteOne(desc, val->val.set_val.vals[j], field) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Error(Fmt("unsupported field format %d for %s", val->type, field->name.c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, LogVal** vals)
|
bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, LogVal** vals)
|
||||||
{
|
{
|
||||||
ODesc desc(DESC_READABLE);
|
ODesc desc(DESC_READABLE);
|
||||||
|
@ -99,63 +185,9 @@ bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, Log
|
||||||
if ( i > 0 )
|
if ( i > 0 )
|
||||||
desc.AddRaw(separator, separator_len);
|
desc.AddRaw(separator, separator_len);
|
||||||
|
|
||||||
LogVal* val = vals[i];
|
if ( ! DoWriteOne(&desc, vals[i], fields[i]) )
|
||||||
const LogField* field = fields[i];
|
|
||||||
|
|
||||||
if ( ! val->present )
|
|
||||||
{
|
|
||||||
desc.AddN(unset_field, unset_field_len);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( field->type ) {
|
|
||||||
case TYPE_BOOL:
|
|
||||||
desc.Add(val->val.int_val ? "T" : "F");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_INT:
|
|
||||||
case TYPE_ENUM:
|
|
||||||
desc.Add(val->val.int_val);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_COUNT:
|
|
||||||
case TYPE_COUNTER:
|
|
||||||
case TYPE_PORT:
|
|
||||||
desc.Add(val->val.uint_val);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_SUBNET:
|
|
||||||
desc.Add(dotted_addr(val->val.subnet_val.net));
|
|
||||||
desc.Add("/");
|
|
||||||
desc.Add(val->val.subnet_val.width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_NET:
|
|
||||||
case TYPE_ADDR:
|
|
||||||
desc.Add(dotted_addr(val->val.addr_val));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_DOUBLE:
|
|
||||||
case TYPE_TIME:
|
|
||||||
case TYPE_INTERVAL:
|
|
||||||
desc.Add(val->val.double_val);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_STRING:
|
|
||||||
{
|
|
||||||
int size = val->val.string_val->size();
|
|
||||||
if ( size )
|
|
||||||
desc.AddN(val->val.string_val->data(), val->val.string_val->size());
|
|
||||||
else
|
|
||||||
desc.AddN(empty_field, empty_field_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
Error(Fmt("unsupported field format %d for %s", field->type, field->name.c_str()));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
desc.Add("\n");
|
desc.Add("\n");
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsSpecial(string path) { return path.find("/dev/") == 0; }
|
bool IsSpecial(string path) { return path.find("/dev/") == 0; }
|
||||||
|
bool DoWriteOne(ODesc* desc, LogVal* val, const LogField* field);
|
||||||
|
|
||||||
FILE* file;
|
FILE* file;
|
||||||
string fname;
|
string fname;
|
||||||
|
@ -35,6 +36,9 @@ private:
|
||||||
char* separator;
|
char* separator;
|
||||||
int separator_len;
|
int separator_len;
|
||||||
|
|
||||||
|
char* set_separator;
|
||||||
|
int set_separator_len;
|
||||||
|
|
||||||
char* empty_field;
|
char* empty_field;
|
||||||
int empty_field_len;
|
int empty_field_len;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ const output_to_stdout: bool;
|
||||||
const include_header: bool;
|
const include_header: bool;
|
||||||
const header_prefix: string;
|
const header_prefix: string;
|
||||||
const separator: string;
|
const separator: string;
|
||||||
|
const set_separator: string;
|
||||||
const empty_field: string;
|
const empty_field: string;
|
||||||
const unset_field: string;
|
const unset_field: string;
|
||||||
|
|
||||||
|
|
90
testing/btest/logging/remote-types.bro
Normal file
90
testing/btest/logging/remote-types.bro
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-run sender bro --pseudo-realtime %INPUT ../sender.bro
|
||||||
|
# @TEST-EXEC: sleep 1
|
||||||
|
# @TEST-EXEC: btest-bg-run receiver bro --pseudo-realtime %INPUT ../receiver.bro
|
||||||
|
# @TEST-EXEC: sleep 1
|
||||||
|
# @TEST-EXEC: btest-bg-wait -k 1
|
||||||
|
# @TEST-EXEC: btest-diff receiver/ssh.log
|
||||||
|
# @TEST-EXEC: cmp receiver/ssh.log sender/ssh.log
|
||||||
|
|
||||||
|
# Remote version testing all types.
|
||||||
|
|
||||||
|
# This is the common part loaded by both sender and receiver.
|
||||||
|
|
||||||
|
redef LogAscii::empty_field = "EMPTY";
|
||||||
|
|
||||||
|
module SSH;
|
||||||
|
|
||||||
|
export {
|
||||||
|
# Create a new ID for our log stream
|
||||||
|
redef enum Log::ID += { SSH };
|
||||||
|
|
||||||
|
type Log: record {
|
||||||
|
b: bool;
|
||||||
|
i: int;
|
||||||
|
e: Log::ID;
|
||||||
|
c: count;
|
||||||
|
p: port;
|
||||||
|
sn: subnet;
|
||||||
|
n: net;
|
||||||
|
a: addr;
|
||||||
|
d: double;
|
||||||
|
t: time;
|
||||||
|
iv: interval;
|
||||||
|
s: string;
|
||||||
|
sc: set[count];
|
||||||
|
ss: set[string];
|
||||||
|
se: set[string];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
global log_ssh: event(rec: Log);
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
Log::create_stream(SSH, [$columns=Log, $ev=log_ssh]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#####
|
||||||
|
|
||||||
|
@TEST-START-FILE sender.bro
|
||||||
|
|
||||||
|
module SSH;
|
||||||
|
|
||||||
|
@load listen-clear
|
||||||
|
|
||||||
|
event remote_connection_handshake_done(p: event_peer)
|
||||||
|
{
|
||||||
|
local empty_set: set[string];
|
||||||
|
|
||||||
|
Log::write(SSH, [
|
||||||
|
$b=T,
|
||||||
|
$i=-42,
|
||||||
|
$e=SSH,
|
||||||
|
$c=21,
|
||||||
|
$p=123/tcp,
|
||||||
|
$sn=10.0.0.1/24,
|
||||||
|
$n=10.0.,
|
||||||
|
$a=1.2.3.4,
|
||||||
|
$d=3.14,
|
||||||
|
$t=network_time(),
|
||||||
|
$iv=100secs,
|
||||||
|
$s="hurz",
|
||||||
|
$sc=set(1,2,3,4),
|
||||||
|
$ss=set("AA", "BB", "CC"),
|
||||||
|
$se=empty_set
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
@TEST-START-FILE receiver.bro
|
||||||
|
|
||||||
|
#####
|
||||||
|
|
||||||
|
@load remote
|
||||||
|
|
||||||
|
redef Remote::destinations += {
|
||||||
|
["foo"] = [$host = 127.0.0.1, $connect=T, $request_logs=T]
|
||||||
|
};
|
||||||
|
|
||||||
|
@TEST-END-FILE
|
57
testing/btest/logging/types.bro
Normal file
57
testing/btest/logging/types.bro
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: bro %INPUT
|
||||||
|
# @TEST-EXEC: btest-diff ssh.log
|
||||||
|
#
|
||||||
|
# Testing all possible types.
|
||||||
|
|
||||||
|
redef LogAscii::empty_field = "EMPTY";
|
||||||
|
|
||||||
|
module SSH;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Log::ID += { SSH };
|
||||||
|
|
||||||
|
type Log: record {
|
||||||
|
b: bool;
|
||||||
|
i: int;
|
||||||
|
e: Log::ID;
|
||||||
|
c: count;
|
||||||
|
p: port;
|
||||||
|
sn: subnet;
|
||||||
|
n: net;
|
||||||
|
a: addr;
|
||||||
|
d: double;
|
||||||
|
t: time;
|
||||||
|
iv: interval;
|
||||||
|
s: string;
|
||||||
|
sc: set[count];
|
||||||
|
ss: set[string];
|
||||||
|
se: set[string];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
Log::create_stream(SSH, [$columns=Log]);
|
||||||
|
|
||||||
|
local empty_set: set[string];
|
||||||
|
|
||||||
|
Log::write(SSH, [
|
||||||
|
$b=T,
|
||||||
|
$i=-42,
|
||||||
|
$e=SSH,
|
||||||
|
$c=21,
|
||||||
|
$p=123/tcp,
|
||||||
|
$sn=10.0.0.1/24,
|
||||||
|
$n=10.0.,
|
||||||
|
$a=1.2.3.4,
|
||||||
|
$d=3.14,
|
||||||
|
$t=network_time(),
|
||||||
|
$iv=100secs,
|
||||||
|
$s="hurz",
|
||||||
|
$sc=set(1,2,3,4),
|
||||||
|
$ss=set("AA", "BB", "CC"),
|
||||||
|
$se=empty_set
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue