mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
broker integration: add bifs to inspect/manipulate broker data
i.e. script-layer functions to convert between bro values and broker values; mostly for use w/ Bro's data store interface (coming soon).
This commit is contained in:
parent
0537711fd4
commit
d2ea87735a
10 changed files with 1154 additions and 40 deletions
|
@ -19,4 +19,9 @@ export {
|
|||
name: string &optional; # nil for invalid event/args.
|
||||
args: vector of Comm::Data;
|
||||
};
|
||||
|
||||
type Comm::TableItem : record {
|
||||
key: Comm::Data;
|
||||
val: Comm::Data;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -123,6 +123,19 @@ void Reporter::ExprRuntimeError(const Expr* expr, const char* fmt, ...)
|
|||
throw InterpreterException();
|
||||
}
|
||||
|
||||
void Reporter::RuntimeError(const Location* location, const char* fmt, ...)
|
||||
{
|
||||
++errors;
|
||||
PushLocation(location);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
FILE* out = errors_to_stderr ? stderr : 0;
|
||||
DoLog("runtime error", reporter_error, out, 0, 0, true, true, "", fmt, ap);
|
||||
va_end(ap);
|
||||
PopLocation();
|
||||
throw InterpreterException();
|
||||
}
|
||||
|
||||
void Reporter::InternalError(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
|
|
@ -73,6 +73,10 @@ public:
|
|||
// function will not return but raise an InterpreterException.
|
||||
void ExprRuntimeError(const Expr* expr, const char* fmt, ...);
|
||||
|
||||
// Report a runtime error in evaluating a Bro script expression. This
|
||||
// function will not return but raise an InterpreterException.
|
||||
void RuntimeError(const Location* location, const char* fmt, ...);
|
||||
|
||||
// Report a traffic weirdness, i.e., an unexpected protocol situation
|
||||
// that may lead to incorrectly processing a connnection.
|
||||
void Weird(const char* name); // Raises net_weird().
|
||||
|
|
168
src/comm/Data.cc
168
src/comm/Data.cc
|
@ -4,6 +4,10 @@
|
|||
using namespace std;
|
||||
|
||||
OpaqueType* comm::opaque_of_data_type;
|
||||
OpaqueType* comm::opaque_of_set_iterator;
|
||||
OpaqueType* comm::opaque_of_table_iterator;
|
||||
OpaqueType* comm::opaque_of_vector_iterator;
|
||||
OpaqueType* comm::opaque_of_record_iterator;
|
||||
|
||||
static broker::port::protocol to_broker_port_proto(TransportProto tp)
|
||||
{
|
||||
|
@ -20,7 +24,7 @@ static broker::port::protocol to_broker_port_proto(TransportProto tp)
|
|||
}
|
||||
}
|
||||
|
||||
static TransportProto to_bro_port_proto(broker::port::protocol tp)
|
||||
TransportProto comm::to_bro_port_proto(broker::port::protocol tp)
|
||||
{
|
||||
switch ( tp ) {
|
||||
case broker::port::protocol::tcp:
|
||||
|
@ -70,7 +74,7 @@ struct val_converter {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
result_type operator()(const std::string& a)
|
||||
result_type operator()(std::string& a)
|
||||
{
|
||||
switch ( type->Tag() ) {
|
||||
case TYPE_STRING:
|
||||
|
@ -103,7 +107,7 @@ struct val_converter {
|
|||
}
|
||||
}
|
||||
|
||||
result_type operator()(const broker::address& a)
|
||||
result_type operator()(broker::address& a)
|
||||
{
|
||||
if ( type->Tag() == TYPE_ADDR )
|
||||
{
|
||||
|
@ -114,7 +118,7 @@ struct val_converter {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
result_type operator()(const broker::subnet& a)
|
||||
result_type operator()(broker::subnet& a)
|
||||
{
|
||||
if ( type->Tag() == TYPE_SUBNET )
|
||||
{
|
||||
|
@ -125,15 +129,15 @@ struct val_converter {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
result_type operator()(const broker::port& a)
|
||||
result_type operator()(broker::port& a)
|
||||
{
|
||||
if ( type->Tag() == TYPE_PORT )
|
||||
return new PortVal(a.number(), to_bro_port_proto(a.type()));
|
||||
return new PortVal(a.number(), comm::to_bro_port_proto(a.type()));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
result_type operator()(const broker::time_point& a)
|
||||
result_type operator()(broker::time_point& a)
|
||||
{
|
||||
if ( type->Tag() == TYPE_TIME )
|
||||
return new Val(a.value, TYPE_TIME);
|
||||
|
@ -141,7 +145,7 @@ struct val_converter {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
result_type operator()(const broker::time_duration& a)
|
||||
result_type operator()(broker::time_duration& a)
|
||||
{
|
||||
if ( type->Tag() == TYPE_INTERVAL )
|
||||
return new Val(a.value, TYPE_INTERVAL);
|
||||
|
@ -149,7 +153,7 @@ struct val_converter {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
result_type operator()(const broker::enum_value& a)
|
||||
result_type operator()(broker::enum_value& a)
|
||||
{
|
||||
if ( type->Tag() == TYPE_ENUM )
|
||||
{
|
||||
|
@ -175,12 +179,13 @@ struct val_converter {
|
|||
|
||||
for ( auto& item : a )
|
||||
{
|
||||
broker::vector composite_key;
|
||||
auto indices = broker::get<broker::vector>(item);
|
||||
|
||||
if ( ! indices )
|
||||
{
|
||||
Unref(rval);
|
||||
return nullptr;
|
||||
composite_key.emplace_back(move(item));
|
||||
indices = &composite_key;
|
||||
}
|
||||
|
||||
auto expected_index_types = tt->Indices()->Types();
|
||||
|
@ -226,12 +231,13 @@ struct val_converter {
|
|||
|
||||
for ( auto& item : a )
|
||||
{
|
||||
broker::vector composite_key;
|
||||
auto indices = broker::get<broker::vector>(item.first);
|
||||
|
||||
if ( ! indices )
|
||||
{
|
||||
Unref(rval);
|
||||
return nullptr;
|
||||
composite_key.emplace_back(move(item.first));
|
||||
indices = &composite_key;
|
||||
}
|
||||
|
||||
auto expected_index_types = tt->Indices()->Types();
|
||||
|
@ -341,7 +347,7 @@ Val* comm::data_to_val(broker::data d, BroType* type)
|
|||
return broker::visit(val_converter{type}, d);
|
||||
}
|
||||
|
||||
broker::util::optional<broker::data> comm::val_to_data(const Val* v)
|
||||
broker::util::optional<broker::data> comm::val_to_data(Val* v)
|
||||
{
|
||||
switch ( v->Type()->Tag() ) {
|
||||
case TYPE_BOOL:
|
||||
|
@ -388,7 +394,7 @@ broker::util::optional<broker::data> comm::val_to_data(const Val* v)
|
|||
{
|
||||
auto enum_type = v->Type()->AsEnumType();
|
||||
auto enum_name = enum_type->Lookup(v->AsEnum());
|
||||
return {broker::enum_value(enum_name ? "<unknown enum>" : enum_name)};
|
||||
return {broker::enum_value(enum_name ? enum_name : "<unknown enum>")};
|
||||
}
|
||||
case TYPE_STRING:
|
||||
{
|
||||
|
@ -433,7 +439,9 @@ broker::util::optional<broker::data> comm::val_to_data(const Val* v)
|
|||
auto entry = table->NextEntry(k, c);
|
||||
auto vl = table_val->RecoverIndex(k);
|
||||
iter_guard ig(k, vl);
|
||||
broker::vector key;
|
||||
|
||||
broker::vector composite_key;
|
||||
composite_key.reserve(vl->Length());
|
||||
|
||||
for ( auto k = 0; k < vl->Length(); ++k )
|
||||
{
|
||||
|
@ -442,9 +450,16 @@ broker::util::optional<broker::data> comm::val_to_data(const Val* v)
|
|||
if ( ! key_part )
|
||||
return {};
|
||||
|
||||
key.emplace_back(move(*key_part));
|
||||
composite_key.emplace_back(move(*key_part));
|
||||
}
|
||||
|
||||
broker::data key;
|
||||
|
||||
if ( composite_key.size() == 1 )
|
||||
key = move(composite_key[0]);
|
||||
else
|
||||
key = move(composite_key);
|
||||
|
||||
if ( is_set )
|
||||
broker::get<broker::set>(rval)->emplace(move(key));
|
||||
else
|
||||
|
@ -521,7 +536,7 @@ broker::util::optional<broker::data> comm::val_to_data(const Val* v)
|
|||
return {};
|
||||
}
|
||||
|
||||
RecordVal* comm::make_data_val(const Val* v)
|
||||
RecordVal* comm::make_data_val(Val* v)
|
||||
{
|
||||
auto rval = new RecordVal(BifType::Record::Comm::Data);
|
||||
auto data = val_to_data(v);
|
||||
|
@ -531,3 +546,120 @@ RecordVal* comm::make_data_val(const Val* v)
|
|||
|
||||
return rval;
|
||||
}
|
||||
|
||||
RecordVal* comm::make_data_val(broker::data d)
|
||||
{
|
||||
auto rval = new RecordVal(BifType::Record::Comm::Data);
|
||||
rval->Assign(0, new DataVal(move(d)));
|
||||
return rval;
|
||||
}
|
||||
|
||||
struct data_type_getter {
|
||||
using result_type = EnumVal*;
|
||||
|
||||
result_type operator()(bool a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::BOOL,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(uint64_t a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::COUNT,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(int64_t a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::INT,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(double a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::DOUBLE,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const std::string& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::STRING,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::address& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::ADDR,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::subnet& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::SUBNET,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::port& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::PORT,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::time_point& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::TIME,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::time_duration& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::INTERVAL,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::enum_value& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::ENUM,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::set& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::SET,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::table& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::TABLE,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::vector& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::VECTOR,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
|
||||
result_type operator()(const broker::record& a)
|
||||
{
|
||||
return new EnumVal(BifEnum::Comm::RECORD,
|
||||
BifType::Enum::Comm::DataType);
|
||||
}
|
||||
};
|
||||
|
||||
EnumVal* comm::get_data_type(RecordVal* v, Frame* frame)
|
||||
{
|
||||
return broker::visit(data_type_getter{}, opaque_field_to_data(v, frame));
|
||||
}
|
||||
|
||||
broker::data& comm::opaque_field_to_data(RecordVal* v, Frame* f)
|
||||
{
|
||||
Val* d = v->Lookup(0);
|
||||
|
||||
if ( ! d )
|
||||
reporter->RuntimeError(f->GetCall()->GetLocationInfo(),
|
||||
"Comm::Data's opaque field is not set");
|
||||
|
||||
return static_cast<DataVal*>(d)->data;
|
||||
}
|
||||
|
|
155
src/comm/Data.h
155
src/comm/Data.h
|
@ -3,14 +3,27 @@
|
|||
|
||||
#include <broker/data.hh>
|
||||
#include "Val.h"
|
||||
#include "Reporter.h"
|
||||
#include "Frame.h"
|
||||
#include "Expr.h"
|
||||
|
||||
namespace comm {
|
||||
|
||||
extern OpaqueType* opaque_of_data_type;
|
||||
extern OpaqueType* opaque_of_set_iterator;
|
||||
extern OpaqueType* opaque_of_table_iterator;
|
||||
extern OpaqueType* opaque_of_vector_iterator;
|
||||
extern OpaqueType* opaque_of_record_iterator;
|
||||
|
||||
RecordVal* make_data_val(const Val* v);
|
||||
TransportProto to_bro_port_proto(broker::port::protocol tp);
|
||||
|
||||
broker::util::optional<broker::data> val_to_data(const Val* v);
|
||||
RecordVal* make_data_val(Val* v);
|
||||
|
||||
RecordVal* make_data_val(broker::data d);
|
||||
|
||||
EnumVal* get_data_type(RecordVal* v, Frame* frame);
|
||||
|
||||
broker::util::optional<broker::data> val_to_data(Val* v);
|
||||
|
||||
Val* data_to_val(broker::data d, BroType* type);
|
||||
|
||||
|
@ -21,9 +34,147 @@ public:
|
|||
: OpaqueVal(comm::opaque_of_data_type), data(std::move(arg_data))
|
||||
{}
|
||||
|
||||
void ValDescribe(ODesc* d) const override
|
||||
{
|
||||
d->Add("broker::data{");
|
||||
d->Add(broker::to_string(data));
|
||||
d->Add("}");
|
||||
}
|
||||
|
||||
broker::data data;
|
||||
};
|
||||
|
||||
struct type_name_getter {
|
||||
using result_type = const char*;
|
||||
|
||||
result_type operator()(bool a)
|
||||
{ return "bool"; }
|
||||
|
||||
result_type operator()(uint64_t a)
|
||||
{ return "uint64_t"; }
|
||||
|
||||
result_type operator()(int64_t a)
|
||||
{ return "int64_t"; }
|
||||
|
||||
result_type operator()(double a)
|
||||
{ return "double"; }
|
||||
|
||||
result_type operator()(const std::string& a)
|
||||
{ return "string"; }
|
||||
|
||||
result_type operator()(const broker::address& a)
|
||||
{ return "address"; }
|
||||
|
||||
result_type operator()(const broker::subnet& a)
|
||||
{ return "subnet"; }
|
||||
|
||||
result_type operator()(const broker::port& a)
|
||||
{ return "port"; }
|
||||
|
||||
result_type operator()(const broker::time_point& a)
|
||||
{ return "time"; }
|
||||
|
||||
result_type operator()(const broker::time_duration& a)
|
||||
{ return "interval"; }
|
||||
|
||||
result_type operator()(const broker::enum_value& a)
|
||||
{ return "enum"; }
|
||||
|
||||
result_type operator()(const broker::set& a)
|
||||
{ return "set"; }
|
||||
|
||||
result_type operator()(const broker::table& a)
|
||||
{ return "table"; }
|
||||
|
||||
result_type operator()(const broker::vector& a)
|
||||
{ return "vector"; }
|
||||
|
||||
result_type operator()(const broker::record& a)
|
||||
{ return "record"; }
|
||||
};
|
||||
|
||||
broker::data& opaque_field_to_data(RecordVal* v, Frame* f);
|
||||
|
||||
template <typename T>
|
||||
T& require_data_type(broker::data& d, TypeTag tag, Frame* f)
|
||||
{
|
||||
auto ptr = broker::get<T>(d);
|
||||
|
||||
if ( ! ptr )
|
||||
reporter->RuntimeError(f->GetCall()->GetLocationInfo(),
|
||||
"data is of type '%s' not of type '%s'",
|
||||
broker::visit(type_name_getter{}, d),
|
||||
type_name(tag));
|
||||
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T& require_data_type(RecordVal* v, TypeTag tag, Frame* f)
|
||||
{
|
||||
return require_data_type<T>(opaque_field_to_data(v, f), tag, f);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Val* refine(RecordVal* v, TypeTag tag, Frame* f)
|
||||
{
|
||||
return new Val(require_data_type<T>(v, tag, f), tag);
|
||||
}
|
||||
|
||||
// Copying data in to iterator vals is not the fastest approach, but safer...
|
||||
|
||||
class SetIterator : public OpaqueVal {
|
||||
public:
|
||||
|
||||
SetIterator(RecordVal* v, TypeTag tag, Frame* f)
|
||||
: OpaqueVal(comm::opaque_of_set_iterator),
|
||||
dat(require_data_type<broker::set>(v, TYPE_TABLE, f)),
|
||||
it(dat.begin())
|
||||
{}
|
||||
|
||||
broker::set dat;
|
||||
broker::set::iterator it;
|
||||
};
|
||||
|
||||
class TableIterator : public OpaqueVal {
|
||||
public:
|
||||
|
||||
TableIterator(RecordVal* v, TypeTag tag, Frame* f)
|
||||
: OpaqueVal(comm::opaque_of_table_iterator),
|
||||
dat(require_data_type<broker::table>(v, TYPE_TABLE, f)),
|
||||
it(dat.begin())
|
||||
{}
|
||||
|
||||
broker::table dat;
|
||||
broker::table::iterator it;
|
||||
};
|
||||
|
||||
class VectorIterator : public OpaqueVal {
|
||||
public:
|
||||
|
||||
VectorIterator(RecordVal* v, TypeTag tag, Frame* f)
|
||||
: OpaqueVal(comm::opaque_of_vector_iterator),
|
||||
dat(require_data_type<broker::vector>(v, TYPE_VECTOR, f)),
|
||||
it(dat.begin())
|
||||
{}
|
||||
|
||||
broker::vector dat;
|
||||
broker::vector::iterator it;
|
||||
};
|
||||
|
||||
class RecordIterator : public OpaqueVal {
|
||||
public:
|
||||
|
||||
RecordIterator(RecordVal* v, TypeTag tag, Frame* f)
|
||||
: OpaqueVal(comm::opaque_of_record_iterator),
|
||||
dat(require_data_type<broker::record>(v, TYPE_VECTOR, f)),
|
||||
it(dat.fields.begin())
|
||||
{}
|
||||
|
||||
broker::record dat;
|
||||
decltype(broker::record::fields)::iterator it;
|
||||
};
|
||||
|
||||
} // namespace comm
|
||||
|
||||
#endif // BRO_COMM_DATA_H
|
||||
|
|
|
@ -22,7 +22,7 @@ bool comm::Manager::InitPreScript()
|
|||
return true;
|
||||
}
|
||||
|
||||
static int require_field(const RecordType* rt, const char* name)
|
||||
static int require_field(RecordType* rt, const char* name)
|
||||
{
|
||||
auto rval = rt->FieldOffset(name);
|
||||
|
||||
|
@ -43,6 +43,10 @@ bool comm::Manager::InitPostScript()
|
|||
log_id_type = internal_type("Log::ID")->AsEnumType();
|
||||
|
||||
comm::opaque_of_data_type = new OpaqueType("Comm::Data");
|
||||
comm::opaque_of_set_iterator = new OpaqueType("Comm::SetIterator");
|
||||
comm::opaque_of_table_iterator = new OpaqueType("Comm::TableIterator");
|
||||
comm::opaque_of_vector_iterator = new OpaqueType("Comm::VectorIterator");
|
||||
comm::opaque_of_record_iterator = new OpaqueType("Comm::RecordIterator");
|
||||
vector_of_data_type = new VectorType(internal_type("Comm::Data")->Ref());
|
||||
|
||||
auto res = broker::init();
|
||||
|
@ -110,7 +114,7 @@ bool comm::Manager::Disconnect(const string& addr, uint16_t port)
|
|||
return rval;
|
||||
}
|
||||
|
||||
bool comm::Manager::Print(string topic, string msg, const Val* flags)
|
||||
bool comm::Manager::Print(string topic, string msg, Val* flags)
|
||||
{
|
||||
endpoint->send(move(topic), broker::message{move(msg)}, GetFlags(flags));
|
||||
return true;
|
||||
|
@ -122,8 +126,7 @@ bool comm::Manager::Event(std::string topic, broker::message msg, int flags)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool comm::Manager::Log(const EnumVal* stream, const RecordVal* columns,
|
||||
int flags)
|
||||
bool comm::Manager::Log(EnumVal* stream, RecordVal* columns, int flags)
|
||||
{
|
||||
auto stream_name = stream->Type()->AsEnumType()->Lookup(stream->AsEnum());
|
||||
|
||||
|
@ -150,8 +153,7 @@ bool comm::Manager::Log(const EnumVal* stream, const RecordVal* columns,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool comm::Manager::Event(std::string topic, const RecordVal* args,
|
||||
const Val* flags)
|
||||
bool comm::Manager::Event(std::string topic, RecordVal* args, Val* flags)
|
||||
{
|
||||
if ( ! args->Lookup(0) )
|
||||
return false;
|
||||
|
@ -165,7 +167,7 @@ bool comm::Manager::Event(std::string topic, const RecordVal* args,
|
|||
for ( auto i = 0u; i < vv->Size(); ++i )
|
||||
{
|
||||
auto val = vv->Lookup(i)->AsRecordVal()->Lookup(0);
|
||||
auto data_val = dynamic_cast<DataVal*>(val);
|
||||
auto data_val = static_cast<DataVal*>(val);
|
||||
msg.emplace_back(data_val->data);
|
||||
}
|
||||
|
||||
|
@ -173,7 +175,7 @@ bool comm::Manager::Event(std::string topic, const RecordVal* args,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool comm::Manager::AutoEvent(string topic, const Val* event, const Val* flags)
|
||||
bool comm::Manager::AutoEvent(string topic, Val* event, Val* flags)
|
||||
{
|
||||
if ( event->Type()->Tag() != TYPE_FUNC )
|
||||
{
|
||||
|
@ -202,7 +204,7 @@ bool comm::Manager::AutoEvent(string topic, const Val* event, const Val* flags)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool comm::Manager::AutoEventStop(const string& topic, const Val* event)
|
||||
bool comm::Manager::AutoEventStop(const string& topic, Val* event)
|
||||
{
|
||||
if ( event->Type()->Tag() != TYPE_FUNC )
|
||||
{
|
||||
|
@ -232,12 +234,12 @@ bool comm::Manager::AutoEventStop(const string& topic, const Val* event)
|
|||
return true;
|
||||
}
|
||||
|
||||
RecordVal* comm::Manager::MakeEventArgs(const val_list* args)
|
||||
RecordVal* comm::Manager::MakeEventArgs(val_list* args)
|
||||
{
|
||||
auto rval = new RecordVal(BifType::Record::Comm::EventArgs);
|
||||
auto arg_vec = new VectorVal(vector_of_data_type);
|
||||
rval->Assign(1, arg_vec);
|
||||
const Func* func;
|
||||
Func* func;
|
||||
|
||||
for ( auto i = 0u; i < args->length(); ++i )
|
||||
{
|
||||
|
@ -347,7 +349,7 @@ bool comm::Manager::UnsubscribeToLogs(const string& topic_prefix)
|
|||
return log_subscriptions.erase(topic_prefix);
|
||||
}
|
||||
|
||||
int comm::Manager::GetFlags(const Val* flags)
|
||||
int comm::Manager::GetFlags(Val* flags)
|
||||
{
|
||||
auto r = flags->AsRecordVal();
|
||||
int rval = 0;
|
||||
|
|
|
@ -31,18 +31,18 @@ public:
|
|||
|
||||
bool Disconnect(const std::string& addr, uint16_t port);
|
||||
|
||||
bool Print(std::string topic, std::string msg, const Val* flags);
|
||||
bool Print(std::string topic, std::string msg, Val* flags);
|
||||
|
||||
bool Event(std::string topic, broker::message msg, int flags);
|
||||
bool Event(std::string topic, const RecordVal* args, const Val* flags);
|
||||
bool Event(std::string topic, RecordVal* args, Val* flags);
|
||||
|
||||
bool Log(const EnumVal* stream_id, const RecordVal* columns, int flags);
|
||||
bool Log(EnumVal* stream_id, RecordVal* columns, int flags);
|
||||
|
||||
bool AutoEvent(std::string topic, const Val* event, const Val* flags);
|
||||
bool AutoEvent(std::string topic, Val* event, Val* flags);
|
||||
|
||||
bool AutoEventStop(const std::string& topic, const Val* event);
|
||||
bool AutoEventStop(const std::string& topic, Val* event);
|
||||
|
||||
RecordVal* MakeEventArgs(const val_list* args);
|
||||
RecordVal* MakeEventArgs(val_list* args);
|
||||
|
||||
bool SubscribeToPrints(std::string topic_prefix);
|
||||
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
bool UnsubscribeToLogs(const std::string& topic_prefix);
|
||||
|
||||
static int GetFlags(const Val* flags);
|
||||
static int GetFlags(Val* flags);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -82,7 +82,6 @@ private:
|
|||
static int send_flags_self_idx;
|
||||
static int send_flags_peers_idx;
|
||||
static int send_flags_unsolicited_idx;
|
||||
|
||||
};
|
||||
|
||||
} // namespace comm
|
||||
|
|
|
@ -7,17 +7,507 @@
|
|||
|
||||
module Comm;
|
||||
|
||||
enum DataType %{
|
||||
BOOL,
|
||||
INT,
|
||||
COUNT,
|
||||
DOUBLE,
|
||||
STRING,
|
||||
ADDR,
|
||||
SUBNET,
|
||||
PORT,
|
||||
TIME,
|
||||
INTERVAL,
|
||||
ENUM,
|
||||
SET,
|
||||
TABLE,
|
||||
VECTOR,
|
||||
RECORD,
|
||||
%}
|
||||
|
||||
type Comm::SendFlags: record;
|
||||
|
||||
type Comm::Data: record;
|
||||
|
||||
type Comm::EventArgs: record;
|
||||
|
||||
type Comm::TableItem: record;
|
||||
|
||||
function Comm::data%(d: any%): Comm::Data
|
||||
%{
|
||||
return comm::make_data_val(d);
|
||||
%}
|
||||
|
||||
function Comm::data_type%(d: Comm::Data%): Comm::DataType
|
||||
%{
|
||||
return comm::get_data_type(d->AsRecordVal(), frame);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_bool%(d: Comm::Data%): bool
|
||||
%{
|
||||
return comm::refine<bool>(d->AsRecordVal(), TYPE_BOOL, frame);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_int%(d: Comm::Data%): int
|
||||
%{
|
||||
return comm::refine<int64_t>(d->AsRecordVal(), TYPE_INT, frame);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_count%(d: Comm::Data%): count
|
||||
%{
|
||||
return comm::refine<uint64_t>(d->AsRecordVal(), TYPE_COUNT, frame);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_double%(d: Comm::Data%): double
|
||||
%{
|
||||
return comm::refine<double>(d->AsRecordVal(), TYPE_DOUBLE, frame);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_string%(d: Comm::Data%): string
|
||||
%{
|
||||
return new StringVal(comm::require_data_type<std::string>(d->AsRecordVal(),
|
||||
TYPE_STRING,
|
||||
frame));
|
||||
%}
|
||||
|
||||
function Comm::refine_to_addr%(d: Comm::Data%): addr
|
||||
%{
|
||||
auto& a = comm::require_data_type<broker::address>(d->AsRecordVal(),
|
||||
TYPE_ADDR, frame);
|
||||
auto bits = reinterpret_cast<const in6_addr*>(&a.bytes());
|
||||
return new AddrVal(IPAddr(*bits));
|
||||
%}
|
||||
|
||||
function Comm::refine_to_subnet%(d: Comm::Data%): subnet
|
||||
%{
|
||||
auto& a = comm::require_data_type<broker::subnet>(d->AsRecordVal(),
|
||||
TYPE_SUBNET, frame);
|
||||
auto bits = reinterpret_cast<const in6_addr*>(&a.network().bytes());
|
||||
return new SubNetVal(IPPrefix(IPAddr(*bits), a.length()));
|
||||
%}
|
||||
|
||||
function Comm::refine_to_port%(d: Comm::Data%): port
|
||||
%{
|
||||
auto& a = comm::require_data_type<broker::port>(d->AsRecordVal(),
|
||||
TYPE_SUBNET, frame);
|
||||
return new PortVal(a.number(), comm::to_bro_port_proto(a.type()));
|
||||
%}
|
||||
|
||||
function Comm::refine_to_time%(d: Comm::Data%): time
|
||||
%{
|
||||
auto v = comm::require_data_type<broker::time_point>(d->AsRecordVal(),
|
||||
TYPE_TIME, frame).value;
|
||||
return new Val(v, TYPE_TIME);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_interval%(d: Comm::Data%): interval
|
||||
%{
|
||||
auto v = comm::require_data_type<broker::time_duration>(d->AsRecordVal(),
|
||||
TYPE_TIME, frame).value;
|
||||
return new Val(v, TYPE_INTERVAL);
|
||||
%}
|
||||
|
||||
function Comm::refine_to_enum_name%(d: Comm::Data%): string
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::enum_value>(d->AsRecordVal(),
|
||||
TYPE_ENUM, frame).name;
|
||||
return new StringVal(v);
|
||||
%}
|
||||
|
||||
function Comm::set_create%(%): Comm::Data
|
||||
%{
|
||||
return comm::make_data_val(broker::set());
|
||||
%}
|
||||
|
||||
function Comm::set_clear%(s: Comm::Data%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::set>(s->AsRecordVal(), TYPE_TABLE,
|
||||
frame);
|
||||
v.clear();
|
||||
return new Val(true, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::set_size%(s: Comm::Data%): count
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::set>(s->AsRecordVal(), TYPE_TABLE,
|
||||
frame);
|
||||
return new Val(static_cast<uint64_t>(v.size()), TYPE_COUNT);
|
||||
%}
|
||||
|
||||
function Comm::set_contains%(s: Comm::Data, key: Comm::Data%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::set>(s->AsRecordVal(), TYPE_TABLE,
|
||||
frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
return new Val(v.find(k) != v.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::set_insert%(s: Comm::Data, key: Comm::Data%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::set>(s->AsRecordVal(), TYPE_TABLE,
|
||||
frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
return new Val(v.insert(k).second, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::set_remove%(s: Comm::Data, key: Comm::Data%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::set>(s->AsRecordVal(), TYPE_TABLE,
|
||||
frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
return new Val(v.erase(k) > 0, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::set_iterator%(s: Comm::Data%): opaque of Comm::SetIterator
|
||||
%{
|
||||
return new comm::SetIterator(s->AsRecordVal(), TYPE_TABLE, frame);
|
||||
%}
|
||||
|
||||
function Comm::set_iterator_last%(it: opaque of Comm::SetIterator%): bool
|
||||
%{
|
||||
auto set_it = static_cast<comm::SetIterator*>(it);
|
||||
return new Val(set_it->it == set_it->dat.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::set_iterator_next%(it: opaque of Comm::SetIterator%): bool
|
||||
%{
|
||||
auto set_it = static_cast<comm::SetIterator*>(it);
|
||||
|
||||
if ( set_it->it == set_it->dat.end() )
|
||||
return new Val(false, TYPE_BOOL);
|
||||
|
||||
++set_it->it;
|
||||
return new Val(set_it->it != set_it->dat.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::set_iterator_value%(it: opaque of Comm::SetIterator%): Comm::Data
|
||||
%{
|
||||
auto set_it = static_cast<comm::SetIterator*>(it);
|
||||
auto rval = new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
if ( set_it->it == set_it->dat.end() )
|
||||
{
|
||||
reporter->PushLocation(frame->GetCall()->GetLocationInfo());
|
||||
reporter->Warning("attempt to retrieve value of invalid set iterator");
|
||||
reporter->PopLocation();
|
||||
return rval;
|
||||
}
|
||||
|
||||
rval->Assign(0, new comm::DataVal(*set_it->it));
|
||||
return rval;
|
||||
%}
|
||||
|
||||
function Comm::table_create%(%): Comm::Data
|
||||
%{
|
||||
return comm::make_data_val(broker::table());
|
||||
%}
|
||||
|
||||
function Comm::table_clear%(t: Comm::Data%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::table>(t->AsRecordVal(),
|
||||
TYPE_TABLE, frame);
|
||||
v.clear();
|
||||
return new Val(true, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::table_size%(t: Comm::Data%): count
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::table>(t->AsRecordVal(),
|
||||
TYPE_TABLE, frame);
|
||||
return new Val(static_cast<uint64_t>(v.size()), TYPE_COUNT);
|
||||
%}
|
||||
|
||||
function Comm::table_contains%(t: Comm::Data, key: Comm::Data%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::table>(t->AsRecordVal(),
|
||||
TYPE_TABLE, frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
return new Val(v.find(k) != v.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::table_insert%(t: Comm::Data, key: Comm::Data, val: Comm::Data%): Comm::Data
|
||||
%{
|
||||
auto& table = comm::require_data_type<broker::table>(t->AsRecordVal(),
|
||||
TYPE_TABLE, frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
auto& v = comm::opaque_field_to_data(val->AsRecordVal(), frame);
|
||||
|
||||
try
|
||||
{
|
||||
auto& prev = table.at(k);
|
||||
auto rval = comm::make_data_val(move(prev));
|
||||
prev = v;
|
||||
return rval;
|
||||
}
|
||||
catch (const std::out_of_range&)
|
||||
{
|
||||
table[k] = v;
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
}
|
||||
%}
|
||||
|
||||
function Comm::table_remove%(t: Comm::Data, key: Comm::Data%): Comm::Data
|
||||
%{
|
||||
auto& table = comm::require_data_type<broker::table>(t->AsRecordVal(),
|
||||
TYPE_TABLE, frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
auto it = table.find(k);
|
||||
|
||||
if ( it == table.end() )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
else
|
||||
{
|
||||
auto rval = comm::make_data_val(move(it->second));
|
||||
table.erase(it);
|
||||
return rval;
|
||||
}
|
||||
%}
|
||||
|
||||
function Comm::table_lookup%(t: Comm::Data, key: Comm::Data%): Comm::Data
|
||||
%{
|
||||
auto& table = comm::require_data_type<broker::table>(t->AsRecordVal(),
|
||||
TYPE_TABLE, frame);
|
||||
auto& k = comm::opaque_field_to_data(key->AsRecordVal(), frame);
|
||||
auto it = table.find(k);
|
||||
|
||||
if ( it == table.end() )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
else
|
||||
return comm::make_data_val(it->second);
|
||||
%}
|
||||
|
||||
function Comm::table_iterator%(t: Comm::Data%): opaque of Comm::TableIterator
|
||||
%{
|
||||
return new comm::TableIterator(t->AsRecordVal(), TYPE_TABLE, frame);
|
||||
%}
|
||||
|
||||
function Comm::table_iterator_last%(it: opaque of Comm::TableIterator%): bool
|
||||
%{
|
||||
auto ti = static_cast<comm::TableIterator*>(it);
|
||||
return new Val(ti->it == ti->dat.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::table_iterator_next%(it: opaque of Comm::TableIterator%): bool
|
||||
%{
|
||||
auto ti = static_cast<comm::TableIterator*>(it);
|
||||
|
||||
if ( ti->it == ti->dat.end() )
|
||||
return new Val(false, TYPE_BOOL);
|
||||
|
||||
++ti->it;
|
||||
return new Val(ti->it != ti->dat.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::table_iterator_value%(it: opaque of Comm::TableIterator%): Comm::TableItem
|
||||
%{
|
||||
auto ti = static_cast<comm::TableIterator*>(it);
|
||||
auto rval = new RecordVal(BifType::Record::Comm::TableItem);
|
||||
auto key_val = new RecordVal(BifType::Record::Comm::Data);
|
||||
auto val_val = new RecordVal(BifType::Record::Comm::Data);
|
||||
rval->Assign(0, key_val);
|
||||
rval->Assign(1, val_val);
|
||||
|
||||
if ( ti->it == ti->dat.end() )
|
||||
{
|
||||
reporter->PushLocation(frame->GetCall()->GetLocationInfo());
|
||||
reporter->Warning("attempt to retrieve value of invalid table iterator");
|
||||
reporter->PopLocation();
|
||||
return rval;
|
||||
}
|
||||
|
||||
key_val->Assign(0, new comm::DataVal(ti->it->first));
|
||||
val_val->Assign(0, new comm::DataVal(ti->it->second));
|
||||
return rval;
|
||||
%}
|
||||
|
||||
function Comm::vector_create%(%): Comm::Data
|
||||
%{
|
||||
return comm::make_data_val(broker::vector());
|
||||
%}
|
||||
|
||||
function Comm::vector_clear%(v: Comm::Data%): bool
|
||||
%{
|
||||
auto& vec = comm::require_data_type<broker::vector>(v->AsRecordVal(),
|
||||
TYPE_VECTOR, frame);
|
||||
vec.clear();
|
||||
return new Val(true, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::vector_size%(v: Comm::Data%): count
|
||||
%{
|
||||
auto& vec = comm::require_data_type<broker::vector>(v->AsRecordVal(),
|
||||
TYPE_VECTOR, frame);
|
||||
return new Val(static_cast<uint64_t>(vec.size()), TYPE_COUNT);
|
||||
%}
|
||||
|
||||
function Comm::vector_insert%(v: Comm::Data, d: Comm::Data, idx: count%): bool
|
||||
%{
|
||||
auto& vec = comm::require_data_type<broker::vector>(v->AsRecordVal(),
|
||||
TYPE_VECTOR, frame);
|
||||
auto& item = comm::opaque_field_to_data(d->AsRecordVal(), frame);
|
||||
idx = min(idx, static_cast<uint64_t>(vec.size()));
|
||||
vec.insert(vec.begin() + idx, item);
|
||||
return new Val(true, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::vector_replace%(v: Comm::Data, d: Comm::Data, idx: count%): Comm::Data
|
||||
%{
|
||||
auto& vec = comm::require_data_type<broker::vector>(v->AsRecordVal(),
|
||||
TYPE_VECTOR, frame);
|
||||
auto& item = comm::opaque_field_to_data(d->AsRecordVal(), frame);
|
||||
|
||||
if ( idx >= vec.size() )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
auto rval = comm::make_data_val(move(vec[idx]));
|
||||
vec[idx] = item;
|
||||
return rval;
|
||||
%}
|
||||
|
||||
function Comm::vector_remove%(v: Comm::Data, idx: count%): Comm::Data
|
||||
%{
|
||||
auto& vec = comm::require_data_type<broker::vector>(v->AsRecordVal(),
|
||||
TYPE_VECTOR, frame);
|
||||
|
||||
if ( idx >= vec.size() )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
auto rval = comm::make_data_val(move(vec[idx]));
|
||||
vec.erase(vec.begin() + idx);
|
||||
return rval;
|
||||
%}
|
||||
|
||||
function Comm::vector_lookup%(v: Comm::Data, idx: count%): Comm::Data
|
||||
%{
|
||||
auto& vec = comm::require_data_type<broker::vector>(v->AsRecordVal(),
|
||||
TYPE_VECTOR, frame);
|
||||
|
||||
if ( idx >= vec.size() )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
return comm::make_data_val(vec[idx]);
|
||||
%}
|
||||
|
||||
function Comm::vector_iterator%(v: Comm::Data%): opaque of Comm::VectorIterator
|
||||
%{
|
||||
return new comm::VectorIterator(v->AsRecordVal(), TYPE_VECTOR, frame);
|
||||
%}
|
||||
|
||||
function Comm::vector_iterator_last%(it: opaque of Comm::VectorIterator%): bool
|
||||
%{
|
||||
auto vi = static_cast<comm::VectorIterator*>(it);
|
||||
return new Val(vi->it == vi->dat.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::vector_iterator_next%(it: opaque of Comm::VectorIterator%): bool
|
||||
%{
|
||||
auto vi = static_cast<comm::VectorIterator*>(it);
|
||||
|
||||
if ( vi->it == vi->dat.end() )
|
||||
return new Val(false, TYPE_BOOL);
|
||||
|
||||
++vi->it;
|
||||
return new Val(vi->it != vi->dat.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::vector_iterator_value%(it: opaque of Comm::VectorIterator%): Comm::Data
|
||||
%{
|
||||
auto vi = static_cast<comm::VectorIterator*>(it);
|
||||
auto rval = new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
if ( vi->it == vi->dat.end() )
|
||||
{
|
||||
reporter->PushLocation(frame->GetCall()->GetLocationInfo());
|
||||
reporter->Warning("attempt to retrieve value of invalid table iterator");
|
||||
reporter->PopLocation();
|
||||
return rval;
|
||||
}
|
||||
|
||||
rval->Assign(0, new comm::DataVal(*vi->it));
|
||||
return rval;
|
||||
%}
|
||||
|
||||
function Comm::record_create%(sz: count%): Comm::Data
|
||||
%{
|
||||
return comm::make_data_val(broker::record(std::vector<broker::record::field>(sz)));
|
||||
%}
|
||||
|
||||
function Comm::record_size%(r: Comm::Data%): count
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::record>(r->AsRecordVal(),
|
||||
TYPE_RECORD, frame);
|
||||
return new Val(static_cast<uint64_t>(v.fields.size()), TYPE_COUNT);
|
||||
%}
|
||||
|
||||
function Comm::record_assign%(r: Comm::Data, d: Comm::Data, idx: count%): bool
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::record>(r->AsRecordVal(),
|
||||
TYPE_RECORD, frame);
|
||||
auto& item = comm::opaque_field_to_data(d->AsRecordVal(), frame);
|
||||
|
||||
if ( idx >= v.fields.size() )
|
||||
return new Val(false, TYPE_BOOL);
|
||||
|
||||
v.fields[idx] = item;
|
||||
return new Val(true, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::record_lookup%(r: Comm::Data, idx: count%): Comm::Data
|
||||
%{
|
||||
auto& v = comm::require_data_type<broker::record>(r->AsRecordVal(),
|
||||
TYPE_RECORD, frame);
|
||||
|
||||
if ( idx >= v.size() )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
if ( ! v.fields[idx] )
|
||||
return new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
return comm::make_data_val(*v.fields[idx]);
|
||||
%}
|
||||
|
||||
function Comm::record_iterator%(r: Comm::Data%): opaque of Comm::RecordIterator
|
||||
%{
|
||||
return new comm::RecordIterator(r->AsRecordVal(), TYPE_RECORD, frame);
|
||||
%}
|
||||
|
||||
function Comm::record_iterator_last%(it: opaque of Comm::RecordIterator%): bool
|
||||
%{
|
||||
auto ri = static_cast<comm::RecordIterator*>(it);
|
||||
return new Val(ri->it == ri->dat.fields.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::record_iterator_next%(it: opaque of Comm::RecordIterator%): bool
|
||||
%{
|
||||
auto ri = static_cast<comm::RecordIterator*>(it);
|
||||
|
||||
if ( ri->it == ri->dat.fields.end() )
|
||||
return new Val(false, TYPE_BOOL);
|
||||
|
||||
++ri->it;
|
||||
return new Val(ri->it != ri->dat.fields.end(), TYPE_BOOL);
|
||||
%}
|
||||
|
||||
function Comm::record_iterator_value%(it: opaque of Comm::RecordIterator%): Comm::Data
|
||||
%{
|
||||
auto ri = static_cast<comm::RecordIterator*>(it);
|
||||
auto rval = new RecordVal(BifType::Record::Comm::Data);
|
||||
|
||||
if ( ri->it == ri->dat.fields.end() )
|
||||
{
|
||||
reporter->PushLocation(frame->GetCall()->GetLocationInfo());
|
||||
reporter->Warning("attempt to retrieve value of invalid record iterator");
|
||||
reporter->PopLocation();
|
||||
return rval;
|
||||
}
|
||||
|
||||
if ( ! *ri->it )
|
||||
return rval; // field isn't set
|
||||
|
||||
rval->Assign(0, new comm::DataVal(**ri->it));
|
||||
return rval;
|
||||
%}
|
||||
|
||||
event Comm::remote_connection_established%(peer_address: string,
|
||||
peer_port: port,
|
||||
peer_name: string%);
|
||||
|
|
99
testing/btest/Baseline/comm.data/out
Normal file
99
testing/btest/Baseline/comm.data/out
Normal file
|
@ -0,0 +1,99 @@
|
|||
Comm::BOOL
|
||||
Comm::INT
|
||||
Comm::COUNT
|
||||
Comm::DOUBLE
|
||||
Comm::STRING
|
||||
Comm::ADDR
|
||||
Comm::SUBNET
|
||||
Comm::PORT
|
||||
Comm::TIME
|
||||
Comm::INTERVAL
|
||||
Comm::ENUM
|
||||
Comm::SET
|
||||
Comm::TABLE
|
||||
Comm::VECTOR
|
||||
Comm::RECORD
|
||||
***************************
|
||||
T
|
||||
F
|
||||
1
|
||||
0
|
||||
-1
|
||||
1
|
||||
0
|
||||
1.1
|
||||
-11.1
|
||||
hello
|
||||
1.2.3.4
|
||||
192.168.0.0/16
|
||||
22/tcp
|
||||
42.0
|
||||
180.0
|
||||
Comm::BOOL
|
||||
***************************
|
||||
{
|
||||
two,
|
||||
one,
|
||||
three
|
||||
}
|
||||
0
|
||||
T
|
||||
1
|
||||
T
|
||||
F
|
||||
T
|
||||
2
|
||||
T
|
||||
1
|
||||
F
|
||||
{
|
||||
bye
|
||||
}
|
||||
0
|
||||
***************************
|
||||
{
|
||||
[two] = 2,
|
||||
[one] = 1,
|
||||
[three] = 3
|
||||
}
|
||||
0
|
||||
[d=<uninitialized>]
|
||||
1
|
||||
T
|
||||
42
|
||||
F
|
||||
[d=<uninitialized>]
|
||||
2
|
||||
[d=broker::data{7}]
|
||||
2
|
||||
37
|
||||
[d=broker::data{42}]
|
||||
1
|
||||
***************************
|
||||
[zero, one, two]
|
||||
0
|
||||
T
|
||||
T
|
||||
T
|
||||
T
|
||||
[hi, salutations, hello, greetings]
|
||||
4
|
||||
[d=broker::data{hello}]
|
||||
[d=broker::data{bah}]
|
||||
[d=broker::data{hi}]
|
||||
[hi, salutations, bah, greetings]
|
||||
[d=broker::data{bah}]
|
||||
[hi, salutations, greetings]
|
||||
3
|
||||
***************************
|
||||
[a=<uninitialized>, b=bee, c=1]
|
||||
[a=test, b=bee, c=1]
|
||||
[a=test, b=testagain, c=1]
|
||||
3
|
||||
T
|
||||
T
|
||||
T
|
||||
[d=broker::data{hi}]
|
||||
[d=broker::data{hello}]
|
||||
[d=broker::data{37}]
|
||||
3
|
219
testing/btest/comm/data.bro
Normal file
219
testing/btest/comm/data.bro
Normal file
|
@ -0,0 +1,219 @@
|
|||
# @TEST-EXEC: bro -b %INPUT >out
|
||||
# @TEST-EXEC: btest-diff out
|
||||
|
||||
type bro_set: set[string];
|
||||
type bro_table: table[string] of count;
|
||||
type bro_vector: vector of string;
|
||||
|
||||
type bro_record : record {
|
||||
a: string &optional;
|
||||
b: string &default = "bee";
|
||||
c: count;
|
||||
};
|
||||
|
||||
function comm_record_to_bro_record_recurse(it: opaque of Comm::RecordIterator,
|
||||
rval: bro_record,
|
||||
idx: count): bro_record
|
||||
{
|
||||
if ( Comm::record_iterator_last(it) )
|
||||
return rval;
|
||||
|
||||
local field_value = Comm::record_iterator_value(it);
|
||||
|
||||
if ( field_value?$d )
|
||||
switch ( idx ) {
|
||||
case 0:
|
||||
rval$a = Comm::refine_to_string(field_value);
|
||||
break;
|
||||
case 1:
|
||||
rval$b = Comm::refine_to_string(field_value);
|
||||
break;
|
||||
case 2:
|
||||
rval$c = Comm::refine_to_count(field_value);
|
||||
break;
|
||||
};
|
||||
|
||||
++idx;
|
||||
Comm::record_iterator_next(it);
|
||||
return comm_record_to_bro_record_recurse(it, rval, idx);
|
||||
}
|
||||
|
||||
function comm_record_to_bro_record(d: Comm::Data): bro_record
|
||||
{
|
||||
return comm_record_to_bro_record_recurse(Comm::record_iterator(d),
|
||||
bro_record($c = 0), 0);
|
||||
}
|
||||
|
||||
function
|
||||
comm_set_to_bro_set_recurse(it: opaque of Comm::SetIterator,
|
||||
rval: bro_set): bro_set
|
||||
{
|
||||
if ( Comm::set_iterator_last(it) )
|
||||
return rval;
|
||||
|
||||
add rval[Comm::refine_to_string(Comm::set_iterator_value(it))];
|
||||
Comm::set_iterator_next(it);
|
||||
return comm_set_to_bro_set_recurse(it, rval);
|
||||
}
|
||||
|
||||
|
||||
function comm_set_to_bro_set(d: Comm::Data): bro_set
|
||||
{
|
||||
return comm_set_to_bro_set_recurse(Comm::set_iterator(d), bro_set());
|
||||
}
|
||||
|
||||
function
|
||||
comm_table_to_bro_table_recurse(it: opaque of Comm::TableIterator,
|
||||
rval: bro_table): bro_table
|
||||
{
|
||||
if ( Comm::table_iterator_last(it) )
|
||||
return rval;
|
||||
|
||||
local item = Comm::table_iterator_value(it);
|
||||
rval[Comm::refine_to_string(item$key)] = Comm::refine_to_count(item$val);
|
||||
Comm::table_iterator_next(it);
|
||||
return comm_table_to_bro_table_recurse(it, rval);
|
||||
}
|
||||
|
||||
function comm_table_to_bro_table(d: Comm::Data): bro_table
|
||||
{
|
||||
return comm_table_to_bro_table_recurse(Comm::table_iterator(d),
|
||||
bro_table());
|
||||
}
|
||||
|
||||
function comm_vector_to_bro_vector_recurse(it: opaque of Comm::VectorIterator,
|
||||
rval: bro_vector): bro_vector
|
||||
{
|
||||
if ( Comm::vector_iterator_last(it) )
|
||||
return rval;
|
||||
|
||||
rval[|rval|] = Comm::refine_to_string(Comm::vector_iterator_value(it));
|
||||
Comm::vector_iterator_next(it);
|
||||
return comm_vector_to_bro_vector_recurse(it, rval);
|
||||
}
|
||||
|
||||
function comm_vector_to_bro_vector(d: Comm::Data): bro_vector
|
||||
{
|
||||
return comm_vector_to_bro_vector_recurse(Comm::vector_iterator(d),
|
||||
bro_vector());
|
||||
}
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
print Comm::data_type(Comm::data(T));
|
||||
print Comm::data_type(Comm::data(+1));
|
||||
print Comm::data_type(Comm::data(1));
|
||||
print Comm::data_type(Comm::data(1.1));
|
||||
print Comm::data_type(Comm::data("1 (how creative)"));
|
||||
print Comm::data_type(Comm::data(1.1.1.1));
|
||||
print Comm::data_type(Comm::data(1.1.1.1/1));
|
||||
print Comm::data_type(Comm::data(1/udp));
|
||||
print Comm::data_type(Comm::data(double_to_time(1)));
|
||||
print Comm::data_type(Comm::data(1sec));
|
||||
print Comm::data_type(Comm::data(Comm::BOOL));
|
||||
local s: bro_set = bro_set("one", "two", "three");
|
||||
local t: bro_table = bro_table(["one"] = 1, ["two"] = 2, ["three"] = 3);
|
||||
local v: bro_vector = bro_vector("zero", "one", "two");
|
||||
local r: bro_record = bro_record($c = 1);
|
||||
print Comm::data_type(Comm::data(s));
|
||||
print Comm::data_type(Comm::data(t));
|
||||
print Comm::data_type(Comm::data(v));
|
||||
print Comm::data_type(Comm::data(r));
|
||||
|
||||
print "***************************";
|
||||
|
||||
print Comm::refine_to_bool(Comm::data(T));
|
||||
print Comm::refine_to_bool(Comm::data(F));
|
||||
print Comm::refine_to_int(Comm::data(+1));
|
||||
print Comm::refine_to_int(Comm::data(+0));
|
||||
print Comm::refine_to_int(Comm::data(-1));
|
||||
print Comm::refine_to_count(Comm::data(1));
|
||||
print Comm::refine_to_count(Comm::data(0));
|
||||
print Comm::refine_to_double(Comm::data(1.1));
|
||||
print Comm::refine_to_double(Comm::data(-11.1));
|
||||
print Comm::refine_to_string(Comm::data("hello"));
|
||||
print Comm::refine_to_addr(Comm::data(1.2.3.4));
|
||||
print Comm::refine_to_subnet(Comm::data(192.168.1.1/16));
|
||||
print Comm::refine_to_port(Comm::data(22/tcp));
|
||||
print Comm::refine_to_time(Comm::data(double_to_time(42)));
|
||||
print Comm::refine_to_interval(Comm::data(3min));
|
||||
print Comm::refine_to_enum_name(Comm::data(Comm::BOOL));
|
||||
|
||||
print "***************************";
|
||||
|
||||
local cs = Comm::data(s);
|
||||
print comm_set_to_bro_set(cs);
|
||||
cs = Comm::set_create();
|
||||
print Comm::set_size(cs);
|
||||
print Comm::set_insert(cs, Comm::data("hi"));
|
||||
print Comm::set_size(cs);
|
||||
print Comm::set_contains(cs, Comm::data("hi"));
|
||||
print Comm::set_contains(cs, Comm::data("bye"));
|
||||
print Comm::set_insert(cs, Comm::data("bye"));
|
||||
print Comm::set_size(cs);
|
||||
print Comm::set_remove(cs, Comm::data("hi"));
|
||||
print Comm::set_size(cs);
|
||||
print Comm::set_remove(cs, Comm::data("hi"));
|
||||
print comm_set_to_bro_set(cs);
|
||||
Comm::set_clear(cs);
|
||||
print Comm::set_size(cs);
|
||||
|
||||
print "***************************";
|
||||
|
||||
local ct = Comm::data(t);
|
||||
print comm_table_to_bro_table(ct);
|
||||
ct = Comm::table_create();
|
||||
print Comm::table_size(ct);
|
||||
print Comm::table_insert(ct, Comm::data("hi"), Comm::data(42));
|
||||
print Comm::table_size(ct);
|
||||
print Comm::table_contains(ct, Comm::data("hi"));
|
||||
print Comm::refine_to_count(Comm::table_lookup(ct, Comm::data("hi")));
|
||||
print Comm::table_contains(ct, Comm::data("bye"));
|
||||
print Comm::table_insert(ct, Comm::data("bye"), Comm::data(7));
|
||||
print Comm::table_size(ct);
|
||||
print Comm::table_insert(ct, Comm::data("bye"), Comm::data(37));
|
||||
print Comm::table_size(ct);
|
||||
print Comm::refine_to_count(Comm::table_lookup(ct, Comm::data("bye")));
|
||||
print Comm::table_remove(ct, Comm::data("hi"));
|
||||
print Comm::table_size(ct);
|
||||
|
||||
print "***************************";
|
||||
|
||||
local cv = Comm::data(v);
|
||||
print comm_vector_to_bro_vector(cv);
|
||||
cv = Comm::vector_create();
|
||||
print Comm::vector_size(cv);
|
||||
print Comm::vector_insert(cv, Comm::data("hi"), 0);
|
||||
print Comm::vector_insert(cv, Comm::data("hello"), 1);
|
||||
print Comm::vector_insert(cv, Comm::data("greetings"), 2);
|
||||
print Comm::vector_insert(cv, Comm::data("salutations"), 1);
|
||||
print comm_vector_to_bro_vector(cv);
|
||||
print Comm::vector_size(cv);
|
||||
print Comm::vector_replace(cv, Comm::data("bah"), 2);
|
||||
print Comm::vector_lookup(cv, 2);
|
||||
print Comm::vector_lookup(cv, 0);
|
||||
print comm_vector_to_bro_vector(cv);
|
||||
print Comm::vector_remove(cv, 2);
|
||||
print comm_vector_to_bro_vector(cv);
|
||||
print Comm::vector_size(cv);
|
||||
|
||||
print "***************************";
|
||||
|
||||
local cr = Comm::data(r);
|
||||
print comm_record_to_bro_record(cr);
|
||||
r$a = "test";
|
||||
cr = Comm::data(r);
|
||||
print comm_record_to_bro_record(cr);
|
||||
r$b = "testagain";
|
||||
cr = Comm::data(r);
|
||||
print comm_record_to_bro_record(cr);
|
||||
cr = Comm::record_create(3);
|
||||
print Comm::record_size(cr);
|
||||
print Comm::record_assign(cr, Comm::data("hi"), 0);
|
||||
print Comm::record_assign(cr, Comm::data("hello"), 1);
|
||||
print Comm::record_assign(cr, Comm::data(37), 2);
|
||||
print Comm::record_lookup(cr, 0);
|
||||
print Comm::record_lookup(cr, 1);
|
||||
print Comm::record_lookup(cr, 2);
|
||||
print Comm::record_size(cr);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue