Reformat the world

This commit is contained in:
Tim Wojtulewicz 2021-09-16 15:35:39 -07:00
parent 194cb24547
commit b2f171ec69
714 changed files with 35149 additions and 35203 deletions

View file

@ -1,36 +1,36 @@
#include "zeek/Anon.h" #include "zeek/Anon.h"
#include <stdlib.h>
#include <unistd.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h>
#include "zeek/util.h" #include "zeek/Event.h"
#include "zeek/net_util.h" #include "zeek/ID.h"
#include "zeek/Val.h" #include "zeek/IPAddr.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/Scope.h" #include "zeek/Scope.h"
#include "zeek/ID.h" #include "zeek/Val.h"
#include "zeek/IPAddr.h" #include "zeek/net_util.h"
#include "zeek/Event.h" #include "zeek/util.h"
namespace zeek::detail { namespace zeek::detail
{
AnonymizeIPAddr* ip_anonymizer[NUM_ADDR_ANONYMIZATION_METHODS] = {nullptr}; AnonymizeIPAddr* ip_anonymizer[NUM_ADDR_ANONYMIZATION_METHODS] = {nullptr};
static uint32_t rand32() static uint32_t rand32()
{ {
return ((util::detail::random_number() & 0xffff) << 16) | (util::detail::random_number() & 0xffff); return ((util::detail::random_number() & 0xffff) << 16) |
(util::detail::random_number() & 0xffff);
} }
// From tcpdpriv. // From tcpdpriv.
static int bi_ffs(uint32_t value) static int bi_ffs(uint32_t value)
{ {
int add = 0; int add = 0;
static uint8_t bvals[] = { static uint8_t bvals[] = {0, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1};
0, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
};
if ( (value & 0xFFFF0000) == 0 ) if ( (value & 0xFFFF0000) == 0 )
{ {
@ -82,7 +82,8 @@ bool AnonymizeIPAddr::PreservePrefix(ipaddr32_t /* input */, int /* num_bits */)
bool AnonymizeIPAddr::PreserveNet(ipaddr32_t input) bool AnonymizeIPAddr::PreserveNet(ipaddr32_t input)
{ {
switch ( addr_to_class(ntohl(input)) ) { switch ( addr_to_class(ntohl(input)) )
{
case 'A': case 'A':
return PreservePrefix(input, 8); return PreservePrefix(input, 8);
case 'B': case 'B':
@ -113,7 +114,6 @@ ipaddr32_t AnonymizeIPAddr_RandomMD5::anonymize(ipaddr32_t input)
return output; return output;
} }
// This code is from "On the Design and Performance of Prefix-Preserving // This code is from "On the Design and Performance of Prefix-Preserving
// IP Traffic Trace Anonymization", by Xu et al (IMW 2001) // IP Traffic Trace Anonymization", by Xu et al (IMW 2001)
// //
@ -130,13 +130,13 @@ ipaddr32_t AnonymizeIPAddr_PrefixMD5::anonymize(ipaddr32_t input)
{ {
// PAD(x_0 ... x_{i-1}) = x_0 ... x_{i-1} 1 0 ... 0 . // PAD(x_0 ... x_{i-1}) = x_0 ... x_{i-1} 1 0 ... 0 .
prefix.len = htonl(i + 1); prefix.len = htonl(i + 1);
prefix.prefix = htonl((input & ~(prefix_mask>>i)) | (1<<(31-i))); prefix.prefix = htonl((input & ~(prefix_mask >> i)) | (1 << (31 - i)));
// HK(PAD(x_0 ... x_{i-1})). // HK(PAD(x_0 ... x_{i-1})).
util::detail::hmac_md5(sizeof(prefix), (u_char*) &prefix, digest); util::detail::hmac_md5(sizeof(prefix), (u_char*)&prefix, digest);
// f_{i-1} = LSB(HK(PAD(x_0 ... x_{i-1}))). // f_{i-1} = LSB(HK(PAD(x_0 ... x_{i-1}))).
ipaddr32_t bit_mask = (digest[0] & 1) << (31-i); ipaddr32_t bit_mask = (digest[0] & 1) << (31 - i);
// x_i' = x_i ^ f_{i-1}. // x_i' = x_i ^ f_{i-1}.
output ^= bit_mask; output ^= bit_mask;
@ -148,7 +148,7 @@ ipaddr32_t AnonymizeIPAddr_PrefixMD5::anonymize(ipaddr32_t input)
AnonymizeIPAddr_A50::~AnonymizeIPAddr_A50() AnonymizeIPAddr_A50::~AnonymizeIPAddr_A50()
{ {
for ( auto& b : blocks ) for ( auto& b : blocks )
delete [] b; delete[] b;
} }
void AnonymizeIPAddr_A50::init() void AnonymizeIPAddr_A50::init()
@ -167,9 +167,7 @@ void AnonymizeIPAddr_A50::init()
bool AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits) bool AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits)
{ {
DEBUG_MSG("%s/%d\n", DEBUG_MSG("%s/%d\n", IPAddr(IPv4, &input, IPAddr::Network).AsString().c_str(), num_bits);
IPAddr(IPv4, &input, IPAddr::Network).AsString().c_str(),
num_bits);
if ( ! before_anonymization ) if ( ! before_anonymization )
{ {
@ -225,7 +223,7 @@ AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::new_node_block()
blocks.push_back(block); blocks.push_back(block);
for ( int i = 1; i < block_size - 1; ++i ) for ( int i = 1; i < block_size - 1; ++i )
block[i].child[0] = &block[i+1]; block[i].child[0] = &block[i + 1];
block[block_size - 1].child[0] = nullptr; block[block_size - 1].child[0] = nullptr;
next_free_node = &block[1]; next_free_node = &block[1];
@ -247,7 +245,7 @@ inline AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::new_node()
return new_node_block(); return new_node_block();
} }
inline void AnonymizeIPAddr_A50::free_node(Node *n) inline void AnonymizeIPAddr_A50::free_node(Node* n)
{ {
n->child[0] = next_free_node; n->child[0] = next_free_node;
next_free_node = n; next_free_node = n;
@ -261,8 +259,7 @@ ipaddr32_t AnonymizeIPAddr_A50::make_output(ipaddr32_t old_output, int swivel) c
else else
{ {
// Bits up to swivel are unchanged; bit swivel is flipped. // Bits up to swivel are unchanged; bit swivel is flipped.
ipaddr32_t known_part = ipaddr32_t known_part = ((old_output >> (32 - swivel)) ^ 1) << (32 - swivel);
((old_output >> (32 - swivel)) ^ 1) << (32 - swivel);
// Remainder of bits are random. // Remainder of bits are random.
return known_part | ((rand32() & 0x7FFFFFFF) >> swivel); return known_part | ((rand32() & 0x7FFFFFFF) >> swivel);
@ -340,8 +337,7 @@ AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::find_node(ipaddr32_t a)
{ {
// swivel is the first bit in which the two children // swivel is the first bit in which the two children
// differ. // differ.
int swivel = int swivel = bi_ffs(n->child[0]->input ^ n->child[1]->input);
bi_ffs(n->child[0]->input ^ n->child[1]->input);
if ( bi_ffs(a ^ n->input) < swivel ) if ( bi_ffs(a ^ n->input) < swivel )
// Input differs earlier. // Input differs earlier.
@ -394,7 +390,8 @@ ipaddr32_t anonymize_ip(ipaddr32_t ip, enum ip_addr_anonymization_class_t cl)
int method = -1; int method = -1;
switch ( cl ) { switch ( cl )
{
case ORIG_ADDR: // client address case ORIG_ADDR: // client address
preserve_addr = anon_preserve_orig_addr.get(); preserve_addr = anon_preserve_orig_addr.get();
method = orig_addr_anonymization; method = orig_addr_anonymization;
@ -442,12 +439,10 @@ ipaddr32_t anonymize_ip(ipaddr32_t ip, enum ip_addr_anonymization_class_t cl)
void log_anonymization_mapping(ipaddr32_t input, ipaddr32_t output) void log_anonymization_mapping(ipaddr32_t input, ipaddr32_t output)
{ {
if ( anonymization_mapping ) if ( anonymization_mapping )
event_mgr.Enqueue(anonymization_mapping, event_mgr.Enqueue(anonymization_mapping, make_intrusive<AddrVal>(input),
make_intrusive<AddrVal>(input), make_intrusive<AddrVal>(output));
make_intrusive<AddrVal>(output)
);
} }
#endif #endif
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -10,36 +10,40 @@
#pragma once #pragma once
#include <vector>
#include <map>
#include <cstdint> #include <cstdint>
#include <map>
#include <vector>
namespace zeek::detail { namespace zeek::detail
{
// TODO: Anon.h may not be the right place to put these functions ... // TODO: Anon.h may not be the right place to put these functions ...
enum ip_addr_anonymization_class_t { enum ip_addr_anonymization_class_t
{
ORIG_ADDR, // client address ORIG_ADDR, // client address
RESP_ADDR, // server address RESP_ADDR, // server address
OTHER_ADDR, OTHER_ADDR,
NUM_ADDR_ANONYMIZATION_CLASSES, NUM_ADDR_ANONYMIZATION_CLASSES,
}; };
enum ip_addr_anonymization_method_t { enum ip_addr_anonymization_method_t
{
KEEP_ORIG_ADDR, KEEP_ORIG_ADDR,
SEQUENTIALLY_NUMBERED, SEQUENTIALLY_NUMBERED,
RANDOM_MD5, RANDOM_MD5,
PREFIX_PRESERVING_A50, PREFIX_PRESERVING_A50,
PREFIX_PRESERVING_MD5, PREFIX_PRESERVING_MD5,
NUM_ADDR_ANONYMIZATION_METHODS, NUM_ADDR_ANONYMIZATION_METHODS,
}; };
typedef uint32_t ipaddr32_t; typedef uint32_t ipaddr32_t;
// NOTE: all addresses in parameters of *public* functions are in // NOTE: all addresses in parameters of *public* functions are in
// network order. // network order.
class AnonymizeIPAddr { class AnonymizeIPAddr
{
public: public:
virtual ~AnonymizeIPAddr() = default; virtual ~AnonymizeIPAddr() = default;
@ -53,34 +57,39 @@ public:
protected: protected:
std::map<ipaddr32_t, ipaddr32_t> mapping; std::map<ipaddr32_t, ipaddr32_t> mapping;
}; };
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr { class AnonymizeIPAddr_Seq : public AnonymizeIPAddr
{
public: public:
AnonymizeIPAddr_Seq() { seq = 1; } AnonymizeIPAddr_Seq() { seq = 1; }
ipaddr32_t anonymize(ipaddr32_t addr) override; ipaddr32_t anonymize(ipaddr32_t addr) override;
protected: protected:
ipaddr32_t seq; ipaddr32_t seq;
}; };
class AnonymizeIPAddr_RandomMD5 : public AnonymizeIPAddr { class AnonymizeIPAddr_RandomMD5 : public AnonymizeIPAddr
{
public: public:
ipaddr32_t anonymize(ipaddr32_t addr) override; ipaddr32_t anonymize(ipaddr32_t addr) override;
}; };
class AnonymizeIPAddr_PrefixMD5 : public AnonymizeIPAddr { class AnonymizeIPAddr_PrefixMD5 : public AnonymizeIPAddr
{
public: public:
ipaddr32_t anonymize(ipaddr32_t addr) override; ipaddr32_t anonymize(ipaddr32_t addr) override;
protected: protected:
struct anon_prefix { struct anon_prefix
{
int len; int len;
ipaddr32_t prefix; ipaddr32_t prefix;
} prefix; } prefix;
}; };
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr { class AnonymizeIPAddr_A50 : public AnonymizeIPAddr
{
public: public:
AnonymizeIPAddr_A50() { init(); } AnonymizeIPAddr_A50() { init(); }
~AnonymizeIPAddr_A50() override; ~AnonymizeIPAddr_A50() override;
@ -89,7 +98,8 @@ public:
bool PreservePrefix(ipaddr32_t input, int num_bits) override; bool PreservePrefix(ipaddr32_t input, int num_bits) override;
protected: protected:
struct Node { struct Node
{
ipaddr32_t input; ipaddr32_t input;
ipaddr32_t output; ipaddr32_t output;
Node* child[2]; Node* child[2];
@ -118,7 +128,7 @@ protected:
ipaddr32_t make_output(ipaddr32_t, int) const; ipaddr32_t make_output(ipaddr32_t, int) const;
Node* make_peer(ipaddr32_t, Node*); Node* make_peer(ipaddr32_t, Node*);
Node* find_node(ipaddr32_t); Node* find_node(ipaddr32_t);
}; };
// The global IP anonymizers. // The global IP anonymizers.
extern AnonymizeIPAddr* ip_anonymizer[NUM_ADDR_ANONYMIZATION_METHODS]; extern AnonymizeIPAddr* ip_anonymizer[NUM_ADDR_ANONYMIZATION_METHODS];
@ -129,4 +139,4 @@ ipaddr32_t anonymize_ip(ipaddr32_t ip, enum ip_addr_anonymization_class_t cl);
#define LOG_ANONYMIZATION_MAPPING #define LOG_ANONYMIZATION_MAPPING
void log_anonymization_mapping(ipaddr32_t input, ipaddr32_t output); void log_anonymization_mapping(ipaddr32_t input, ipaddr32_t output);
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,47 +1,61 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Attr.h" #include "zeek/Attr.h"
#include "zeek/Expr.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Val.h" #include "zeek/Expr.h"
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
#include "zeek/Val.h"
#include "zeek/input/Manager.h" #include "zeek/input/Manager.h"
#include "zeek/threading/SerialTypes.h" #include "zeek/threading/SerialTypes.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
const char* attr_name(AttrTag t) const char* attr_name(AttrTag t)
{ {
static const char* attr_names[int(NUM_ATTRS)] = { static const char* attr_names[int(NUM_ATTRS)] = {
"&optional", "&default", "&redef", "&optional",
"&add_func", "&delete_func", "&expire_func", "&default",
"&read_expire", "&write_expire", "&create_expire", "&redef",
"&raw_output", "&priority", "&add_func",
"&group", "&log", "&error_handler", "&type_column", "&delete_func",
"(&tracked)", "&on_change", "&broker_store", "&expire_func",
"&broker_allow_complex_type", "&backend", "&deprecated", "&read_expire",
"&is_assigned", "&is_used", "&write_expire",
"&create_expire",
"&raw_output",
"&priority",
"&group",
"&log",
"&error_handler",
"&type_column",
"(&tracked)",
"&on_change",
"&broker_store",
"&broker_allow_complex_type",
"&backend",
"&deprecated",
"&is_assigned",
"&is_used",
}; };
return attr_names[int(t)]; return attr_names[int(t)];
} }
Attr::Attr(AttrTag t, ExprPtr e) Attr::Attr(AttrTag t, ExprPtr e) : expr(std::move(e))
: expr(std::move(e))
{ {
tag = t; tag = t;
SetLocationInfo(&start_location, &end_location); SetLocationInfo(&start_location, &end_location);
} }
Attr::Attr(AttrTag t) Attr::Attr(AttrTag t) : Attr(t, nullptr) { }
: Attr(t, nullptr)
{
}
void Attr::SetAttrExpr(ExprPtr e) void Attr::SetAttrExpr(ExprPtr e)
{ expr = std::move(e); } {
expr = std::move(e);
}
std::string Attr::DeprecationMessage() const std::string Attr::DeprecationMessage() const
{ {
@ -152,12 +166,11 @@ void Attr::AddTag(ODesc* d) const
} }
Attributes::Attributes(TypePtr t, bool arg_in_record, bool is_global) Attributes::Attributes(TypePtr t, bool arg_in_record, bool is_global)
: Attributes(std::vector<AttrPtr>{}, std::move(t), : Attributes(std::vector<AttrPtr>{}, std::move(t), arg_in_record, is_global)
arg_in_record, is_global) {
{} }
Attributes::Attributes(std::vector<AttrPtr> a, Attributes::Attributes(std::vector<AttrPtr> a, TypePtr t, bool arg_in_record, bool is_global)
TypePtr t, bool arg_in_record, bool is_global)
: type(std::move(t)) : type(std::move(t))
{ {
attrs.reserve(a.size()); attrs.reserve(a.size());
@ -183,7 +196,7 @@ void Attributes::AddAttr(AttrPtr attr, bool is_redef)
if ( new_tag == ATTR_DEPRECATED ) if ( new_tag == ATTR_DEPRECATED )
{ {
if ( ! attr->DeprecationMessage().empty() || if ( ! attr->DeprecationMessage().empty() ||
( existing && ! existing->DeprecationMessage().empty() ) ) (existing && ! existing->DeprecationMessage().empty()) )
return false; return false;
return true; return true;
@ -216,16 +229,14 @@ void Attributes::AddAttr(AttrPtr attr, bool is_redef)
// For ADD_FUNC or DEL_FUNC, add in an implicit REDEF, since // For ADD_FUNC or DEL_FUNC, add in an implicit REDEF, since
// those attributes only have meaning for a redefinable value. // those attributes only have meaning for a redefinable value.
if ( (attr->Tag() == ATTR_ADD_FUNC || attr->Tag() == ATTR_DEL_FUNC) && if ( (attr->Tag() == ATTR_ADD_FUNC || attr->Tag() == ATTR_DEL_FUNC) && ! Find(ATTR_REDEF) )
! Find(ATTR_REDEF) )
{ {
auto a = make_intrusive<Attr>(ATTR_REDEF); auto a = make_intrusive<Attr>(ATTR_REDEF);
attrs.emplace_back(std::move(a)); attrs.emplace_back(std::move(a));
} }
// For DEFAULT, add an implicit OPTIONAL if it's not a global. // For DEFAULT, add an implicit OPTIONAL if it's not a global.
if ( ! global_var && attr->Tag() == ATTR_DEFAULT && if ( ! global_var && attr->Tag() == ATTR_DEFAULT && ! Find(ATTR_OPTIONAL) )
! Find(ATTR_OPTIONAL) )
{ {
auto a = make_intrusive<Attr>(ATTR_OPTIONAL); auto a = make_intrusive<Attr>(ATTR_OPTIONAL);
attrs.emplace_back(std::move(a)); attrs.emplace_back(std::move(a));
@ -290,7 +301,8 @@ void Attributes::DescribeReST(ODesc* d, bool shorten) const
void Attributes::CheckAttr(Attr* a) void Attributes::CheckAttr(Attr* a)
{ {
switch ( a->Tag() ) { switch ( a->Tag() )
{
case ATTR_DEPRECATED: case ATTR_DEPRECATED:
case ATTR_REDEF: case ATTR_REDEF:
case ATTR_IS_ASSIGNED: case ATTR_IS_ASSIGNED:
@ -310,10 +322,8 @@ void Attributes::CheckAttr(Attr* a)
const auto& at = a->GetExpr()->GetType(); const auto& at = a->GetExpr()->GetType();
if ( at->Tag() != TYPE_FUNC ) if ( at->Tag() != TYPE_FUNC )
{ {
a->GetExpr()->Error( a->GetExpr()->Error(is_add ? "&add_func must be a function"
is_add ? : "&delete_func must be a function");
"&add_func must be a function" :
"&delete_func must be a function");
break; break;
} }
@ -321,9 +331,8 @@ void Attributes::CheckAttr(Attr* a)
if ( ! same_type(aft->Yield(), type) ) if ( ! same_type(aft->Yield(), type) )
{ {
a->GetExpr()->Error( a->GetExpr()->Error(
is_add ? is_add ? "&add_func function must yield same type as variable"
"&add_func function must yield same type as variable" : : "&delete_func function must yield same type as variable");
"&delete_func function must yield same type as variable");
break; break;
} }
} }
@ -354,8 +363,7 @@ void Attributes::CheckAttr(Attr* a)
// Ok. // Ok.
break; break;
if ( type->Tag() == TYPE_TABLE && if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() )
type->AsTableType()->IsUnspecifiedTable() )
// Ok. // Ok.
break; break;
@ -423,7 +431,8 @@ void Attributes::CheckAttr(Attr* a)
// Ok. // Ok.
break; break;
if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) ) if ( (atype->Tag() == TYPE_TABLE &&
atype->AsTableType()->IsUnspecifiedTable()) )
{ {
auto e = check_and_promote_expr(a->GetExpr(), type); auto e = check_and_promote_expr(a->GetExpr(), type);
@ -435,8 +444,7 @@ void Attributes::CheckAttr(Attr* a)
} }
// Table defaults may be promotable. // Table defaults may be promotable.
if ( ytype && ytype->Tag() == TYPE_RECORD && if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) ) record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) )
// Ok. // Ok.
break; break;
@ -469,15 +477,15 @@ void Attributes::CheckAttr(Attr* a)
for ( const auto& a : attrs ) for ( const auto& a : attrs )
{ {
if ( a->Tag() == ATTR_EXPIRE_READ || if ( a->Tag() == ATTR_EXPIRE_READ || a->Tag() == ATTR_EXPIRE_WRITE ||
a->Tag() == ATTR_EXPIRE_WRITE ||
a->Tag() == ATTR_EXPIRE_CREATE ) a->Tag() == ATTR_EXPIRE_CREATE )
num_expires++; num_expires++;
} }
if ( num_expires > 1 ) if ( num_expires > 1 )
{ {
Error("set/table can only have one of &read_expire, &write_expire, &create_expire"); Error("set/table can only have one of &read_expire, &write_expire, "
"&create_expire");
break; break;
} }
} }
@ -500,16 +508,15 @@ void Attributes::CheckAttr(Attr* a)
type->AsTableType()->CheckExpireFuncCompatibility({NewRef{}, a}); type->AsTableType()->CheckExpireFuncCompatibility({NewRef{}, a});
if ( Find(ATTR_BROKER_STORE ) ) if ( Find(ATTR_BROKER_STORE) )
Error("&broker_store and &expire_func cannot be used simultaneously"); Error("&broker_store and &expire_func cannot be used simultaneously");
if ( Find(ATTR_BACKEND ) ) if ( Find(ATTR_BACKEND) )
Error("&backend and &expire_func cannot be used simultaneously"); Error("&backend and &expire_func cannot be used simultaneously");
break; break;
} }
case ATTR_ON_CHANGE: case ATTR_ON_CHANGE:
{ {
if ( type->Tag() != TYPE_TABLE ) if ( type->Tag() != TYPE_TABLE )
@ -520,7 +527,8 @@ void Attributes::CheckAttr(Attr* a)
const auto& change_func = a->GetExpr(); const auto& change_func = a->GetExpr();
if ( change_func->GetType()->Tag() != TYPE_FUNC || change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION ) if ( change_func->GetType()->Tag() != TYPE_FUNC ||
change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
Error("&on_change attribute is not a function"); Error("&on_change attribute is not a function");
const FuncType* c_ft = change_func->GetType()->AsFuncType(); const FuncType* c_ft = change_func->GetType()->AsFuncType();
@ -538,7 +546,7 @@ void Attributes::CheckAttr(Attr* a)
const auto& args = c_ft->ParamList()->GetTypes(); const auto& args = c_ft->ParamList()->GetTypes();
const auto& t_indexes = the_table->GetIndexTypes(); const auto& t_indexes = the_table->GetIndexTypes();
if ( args.size() != ( type->IsSet() ? 2 : 3 ) + t_indexes.size() ) if ( args.size() != (type->IsSet() ? 2 : 3) + t_indexes.size() )
{ {
Error("&on_change function has incorrect number of arguments"); Error("&on_change function has incorrect number of arguments");
break; break;
@ -559,7 +567,7 @@ void Attributes::CheckAttr(Attr* a)
for ( size_t i = 0; i < t_indexes.size(); i++ ) for ( size_t i = 0; i < t_indexes.size(); i++ )
{ {
if ( ! same_type(args[2+i], t_indexes[i]) ) if ( ! same_type(args[2 + i], t_indexes[i]) )
{ {
Error("&on_change: index types do not match table"); Error("&on_change: index types do not match table");
break; break;
@ -567,7 +575,7 @@ void Attributes::CheckAttr(Attr* a)
} }
if ( ! type->IsSet() ) if ( ! type->IsSet() )
if ( ! same_type(args[2+t_indexes.size()], the_table->Yield()) ) if ( ! same_type(args[2 + t_indexes.size()], the_table->Yield()) )
{ {
Error("&on_change: value type does not match table"); Error("&on_change: value type does not match table");
break; break;
@ -601,7 +609,7 @@ void Attributes::CheckAttr(Attr* a)
Error("&backend only supports atomic types as table value"); Error("&backend only supports atomic types as table value");
} }
if ( Find(ATTR_EXPIRE_FUNC ) ) if ( Find(ATTR_EXPIRE_FUNC) )
Error("&backend and &expire_func cannot be used simultaneously"); Error("&backend and &expire_func cannot be used simultaneously");
if ( Find(ATTR_EXPIRE_READ) ) if ( Find(ATTR_EXPIRE_READ) )
@ -636,7 +644,7 @@ void Attributes::CheckAttr(Attr* a)
Error("&broker_store only supports atomic types as table value"); Error("&broker_store only supports atomic types as table value");
} }
if ( Find(ATTR_EXPIRE_FUNC ) ) if ( Find(ATTR_EXPIRE_FUNC) )
Error("&broker_store and &expire_func cannot be used simultaneously"); Error("&broker_store and &expire_func cannot be used simultaneously");
if ( Find(ATTR_EXPIRE_READ) ) if ( Find(ATTR_EXPIRE_READ) )
@ -671,14 +679,12 @@ void Attributes::CheckAttr(Attr* a)
break; break;
case ATTR_GROUP: case ATTR_GROUP:
if ( type->Tag() != TYPE_FUNC || if ( type->Tag() != TYPE_FUNC || type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
Error("&group only applicable to events"); Error("&group only applicable to events");
break; break;
case ATTR_ERROR_HANDLER: case ATTR_ERROR_HANDLER:
if ( type->Tag() != TYPE_FUNC || if ( type->Tag() != TYPE_FUNC || type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
Error("&error_handler only applicable to events"); Error("&error_handler only applicable to events");
break; break;
@ -697,7 +703,8 @@ void Attributes::CheckAttr(Attr* a)
const auto& atype = a->GetExpr()->GetType(); const auto& atype = a->GetExpr()->GetType();
if ( atype->Tag() != TYPE_STRING ) { if ( atype->Tag() != TYPE_STRING )
{
Error("type column needs to have a string argument"); Error("type column needs to have a string argument");
break; break;
} }
@ -705,7 +712,6 @@ void Attributes::CheckAttr(Attr* a)
break; break;
} }
default: default:
BadTag("Attributes::CheckAttr", attr_name(a->Tag())); BadTag("Attributes::CheckAttr", attr_name(a->Tag()));
} }
@ -744,4 +750,4 @@ bool Attributes::operator==(const Attributes& other) const
return true; return true;
} }
} }

View file

@ -2,28 +2,31 @@
#pragma once #pragma once
#include <vector>
#include <string> #include <string>
#include <vector>
#include "zeek/IntrusivePtr.h"
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/ZeekList.h" #include "zeek/ZeekList.h"
#include "zeek/IntrusivePtr.h"
// Note that there are two kinds of attributes: the kind (here) which // Note that there are two kinds of attributes: the kind (here) which
// modify expressions or supply metadata on types, and the kind that // modify expressions or supply metadata on types, and the kind that
// are extra metadata on every variable instance. // are extra metadata on every variable instance.
namespace zeek { namespace zeek
{
class Type; class Type;
using TypePtr = IntrusivePtr<Type>; using TypePtr = IntrusivePtr<Type>;
namespace detail { namespace detail
{
class Expr; class Expr;
using ExprPtr = IntrusivePtr<Expr>; using ExprPtr = IntrusivePtr<Expr>;
enum AttrTag { enum AttrTag
{
ATTR_OPTIONAL, ATTR_OPTIONAL,
ATTR_DEFAULT, ATTR_DEFAULT,
ATTR_REDEF, ATTR_REDEF,
@ -48,14 +51,15 @@ enum AttrTag {
ATTR_IS_ASSIGNED, // to suppress usage warnings ATTR_IS_ASSIGNED, // to suppress usage warnings
ATTR_IS_USED, // to suppress usage warnings ATTR_IS_USED, // to suppress usage warnings
NUM_ATTRS // this item should always be last NUM_ATTRS // this item should always be last
}; };
class Attr; class Attr;
using AttrPtr = IntrusivePtr<Attr>; using AttrPtr = IntrusivePtr<Attr>;
class Attributes; class Attributes;
using AttributesPtr = IntrusivePtr<Attributes>; using AttributesPtr = IntrusivePtr<Attributes>;
class Attr final : public Obj { class Attr final : public Obj
{
public: public:
static inline const AttrPtr nil; static inline const AttrPtr nil;
@ -66,8 +70,7 @@ public:
AttrTag Tag() const { return tag; } AttrTag Tag() const { return tag; }
const ExprPtr& GetExpr() const const ExprPtr& GetExpr() const { return expr; }
{ return expr; }
void SetAttrExpr(ExprPtr e); void SetAttrExpr(ExprPtr e);
@ -100,13 +103,13 @@ protected:
AttrTag tag; AttrTag tag;
ExprPtr expr; ExprPtr expr;
}; };
// Manages a collection of attributes. // Manages a collection of attributes.
class Attributes final : public Obj { class Attributes final : public Obj
{
public: public:
Attributes(std::vector<AttrPtr> a, TypePtr t, Attributes(std::vector<AttrPtr> a, TypePtr t, bool in_record, bool is_global);
bool in_record, bool is_global);
Attributes(TypePtr t, bool in_record, bool is_global); Attributes(TypePtr t, bool in_record, bool is_global);
~Attributes() override = default; ~Attributes() override = default;
@ -122,8 +125,7 @@ public:
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool shorten = false) const; void DescribeReST(ODesc* d, bool shorten = false) const;
const std::vector<AttrPtr>& GetAttrs() const const std::vector<AttrPtr>& GetAttrs() const { return attrs; }
{ return attrs; }
bool operator==(const Attributes& other) const; bool operator==(const Attributes& other) const;
@ -135,7 +137,7 @@ protected:
bool in_record; bool in_record;
bool global_var; bool global_var;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,21 +1,23 @@
#include "zeek/zeek-config.h" #include "zeek/Base64.h"
#include <math.h> #include <math.h>
#include "zeek/Base64.h"
#include "zeek/ZeekString.h"
#include "zeek/Reporter.h"
#include "zeek/Conn.h" #include "zeek/Conn.h"
#include "zeek/Reporter.h"
#include "zeek/ZeekString.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
int Base64Converter::default_base64_table[256]; int Base64Converter::default_base64_table[256];
const std::string Base64Converter::default_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const std::string Base64Converter::default_alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void Base64Converter::Encode(int len, const unsigned char* data, int* pblen, char** pbuf) void Base64Converter::Encode(int len, const unsigned char* data, int* pblen, char** pbuf)
{ {
int blen; int blen;
char *buf; char* buf;
if ( ! pbuf ) if ( ! pbuf )
reporter->InternalError("nil pointer to encoding result buffer"); reporter->InternalError("nil pointer to encoding result buffer");
@ -35,20 +37,19 @@ void Base64Converter::Encode(int len, const unsigned char* data, int* pblen, cha
*pblen = blen; *pblen = blen;
} }
for ( int i = 0, j = 0; (i < len) && ( j < blen ); ) for ( int i = 0, j = 0; (i < len) && (j < blen); )
{ {
uint32_t bit32 = data[i++] << 16; uint32_t bit32 = data[i++] << 16;
bit32 += (i++ < len ? data[i-1] : 0) << 8; bit32 += (i++ < len ? data[i - 1] : 0) << 8;
bit32 += i++ < len ? data[i-1] : 0; bit32 += i++ < len ? data[i - 1] : 0;
buf[j++] = alphabet[(bit32 >> 18) & 0x3f]; buf[j++] = alphabet[(bit32 >> 18) & 0x3f];
buf[j++] = alphabet[(bit32 >> 12) & 0x3f]; buf[j++] = alphabet[(bit32 >> 12) & 0x3f];
buf[j++] = (i == (len+2)) ? '=' : alphabet[(bit32 >> 6) & 0x3f]; buf[j++] = (i == (len + 2)) ? '=' : alphabet[(bit32 >> 6) & 0x3f];
buf[j++] = (i >= (len+1)) ? '=' : alphabet[bit32 & 0x3f]; buf[j++] = (i >= (len + 1)) ? '=' : alphabet[bit32 & 0x3f];
} }
} }
int* Base64Converter::InitBase64Table(const std::string& alphabet) int* Base64Converter::InitBase64Table(const std::string& alphabet)
{ {
assert(alphabet.size() == 64); assert(alphabet.size() == 64);
@ -111,7 +112,7 @@ Base64Converter::Base64Converter(Connection* arg_conn, const std::string& arg_al
Base64Converter::~Base64Converter() Base64Converter::~Base64Converter()
{ {
if ( base64_table != default_base64_table ) if ( base64_table != default_base64_table )
delete [] base64_table; delete[] base64_table;
} }
int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf) int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf)
@ -160,11 +161,8 @@ int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf)
if ( buf + num_octets > *pbuf + blen ) if ( buf + num_octets > *pbuf + blen )
break; break;
uint32_t bit32 = uint32_t bit32 = ((base64_group[0] & 0x3f) << 18) | ((base64_group[1] & 0x3f) << 12) |
((base64_group[0] & 0x3f) << 18) | ((base64_group[2] & 0x3f) << 6) | ((base64_group[3] & 0x3f));
((base64_group[1] & 0x3f) << 12) |
((base64_group[2] & 0x3f) << 6) |
((base64_group[3] & 0x3f));
if ( --num_octets >= 0 ) if ( --num_octets >= 0 )
*buf++ = char((bit32 >> 16) & 0xff); *buf++ = char((bit32 >> 16) & 0xff);
@ -173,7 +171,7 @@ int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf)
*buf++ = char((bit32 >> 8) & 0xff); *buf++ = char((bit32 >> 8) & 0xff);
if ( --num_octets >= 0 ) if ( --num_octets >= 0 )
*buf++ = char((bit32) & 0xff); *buf++ = char((bit32)&0xff);
if ( base64_padding > 0 ) if ( base64_padding > 0 )
base64_after_padding = 1; base64_after_padding = 1;
@ -188,13 +186,14 @@ int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf)
if ( data[dlen] == '=' ) if ( data[dlen] == '=' )
++base64_padding; ++base64_padding;
int k = base64_table[(unsigned char) data[dlen]]; int k = base64_table[(unsigned char)data[dlen]];
if ( k >= 0 ) if ( k >= 0 )
base64_group[base64_group_next++] = k; base64_group[base64_group_next++] = k;
else else
{ {
if ( ++errored == 1 ) if ( ++errored == 1 )
IllegalEncoding(util::fmt("character %d ignored by Base64 decoding", (int) (data[dlen]))); IllegalEncoding(
util::fmt("character %d ignored by Base64 decoding", (int)(data[dlen])));
} }
++dlen; ++dlen;
@ -212,7 +211,7 @@ int Base64Converter::Done(int* pblen, char** pbuf)
{ {
if ( base64_group_next < 4 ) if ( base64_group_next < 4 )
IllegalEncoding(util::fmt("incomplete base64 group, padding with %d bits of 0", IllegalEncoding(util::fmt("incomplete base64 group, padding with %d bits of 0",
(4-base64_group_next) * 6)); (4 - base64_group_next) * 6));
Decode(4 - base64_group_next, padding, pblen, pbuf); Decode(4 - base64_group_next, padding, pblen, pbuf);
return -1; return -1;
} }
@ -236,17 +235,16 @@ String* decode_base64(const String* s, const String* a, Connection* conn)
{ {
if ( a && a->Len() != 0 && a->Len() != 64 ) if ( a && a->Len() != 0 && a->Len() != 64 )
{ {
reporter->Error("base64 decoding alphabet is not 64 characters: %s", reporter->Error("base64 decoding alphabet is not 64 characters: %s", a->CheckString());
a->CheckString());
return nullptr; return nullptr;
} }
int buf_len = int((s->Len() + 3) / 4) * 3 + 1; int buf_len = int((s->Len() + 3) / 4) * 3 + 1;
int rlen2, rlen = buf_len; int rlen2, rlen = buf_len;
char* rbuf2, *rbuf = new char[rlen]; char *rbuf2, *rbuf = new char[rlen];
Base64Converter dec(conn, a ? a->CheckString() : ""); Base64Converter dec(conn, a ? a->CheckString() : "");
dec.Decode(s->Len(), (const char*) s->Bytes(), &rlen, &rbuf); dec.Decode(s->Len(), (const char*)s->Bytes(), &rlen, &rbuf);
if ( dec.Errored() ) if ( dec.Errored() )
goto err; goto err;
@ -259,10 +257,10 @@ String* decode_base64(const String* s, const String* a, Connection* conn)
rlen += rlen2; rlen += rlen2;
rbuf[rlen] = '\0'; rbuf[rlen] = '\0';
return new String(true, (u_char*) rbuf, rlen); return new String(true, (u_char*)rbuf, rlen);
err: err:
delete [] rbuf; delete[] rbuf;
return nullptr; return nullptr;
} }
@ -270,17 +268,16 @@ String* encode_base64(const String* s, const String* a, Connection* conn)
{ {
if ( a && a->Len() != 0 && a->Len() != 64 ) if ( a && a->Len() != 0 && a->Len() != 64 )
{ {
reporter->Error("base64 alphabet is not 64 characters: %s", reporter->Error("base64 alphabet is not 64 characters: %s", a->CheckString());
a->CheckString());
return nullptr; return nullptr;
} }
char* outbuf = nullptr; char* outbuf = nullptr;
int outlen = 0; int outlen = 0;
Base64Converter enc(conn, a ? a->CheckString() : ""); Base64Converter enc(conn, a ? a->CheckString() : "");
enc.Encode(s->Len(), (const unsigned char*) s->Bytes(), &outlen, &outbuf); enc.Encode(s->Len(), (const unsigned char*)s->Bytes(), &outlen, &outbuf);
return new String(true, (u_char*)outbuf, outlen); return new String(true, (u_char*)outbuf, outlen);
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,17 +1,21 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <string> #include <string>
namespace zeek { #include "zeek/zeek-config.h"
namespace zeek
{
class String; class String;
class Connection; class Connection;
namespace detail { namespace detail
{
// Maybe we should have a base class for generic decoders? // Maybe we should have a base class for generic decoders?
class Base64Converter { class Base64Converter
{
public: public:
// <conn> is used for error reporting. If it is set to zero (as, // <conn> is used for error reporting. If it is set to zero (as,
// e.g., done by the built-in functions decode_base64() and // e.g., done by the built-in functions decode_base64() and
@ -59,11 +63,10 @@ protected:
int* base64_table; int* base64_table;
int errored; // if true, we encountered an error - skip further processing int errored; // if true, we encountered an error - skip further processing
Connection* conn; Connection* conn;
};
};
String* decode_base64(const String* s, const String* a = nullptr, Connection* conn = nullptr); String* decode_base64(const String* s, const String* a = nullptr, Connection* conn = nullptr);
String* encode_base64(const String* s, const String* a = nullptr, Connection* conn = nullptr); String* encode_base64(const String* s, const String* a = nullptr, Connection* conn = nullptr);
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,11 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/BifReturnVal.h" #include "zeek/BifReturnVal.h"
#include "zeek/Val.h" #include "zeek/Val.h"
namespace zeek::detail { namespace zeek::detail
{
BifReturnVal::BifReturnVal(std::nullptr_t) noexcept BifReturnVal::BifReturnVal(std::nullptr_t) noexcept { }
{}
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,33 +2,34 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
#include "zeek/zeek-config.h"
namespace zeek { namespace zeek
{
class Val; class Val;
using ValPtr = IntrusivePtr<Val>; using ValPtr = IntrusivePtr<Val>;
namespace detail { namespace detail
{
/** /**
* A simple wrapper class to use for the return value of BIFs so that * A simple wrapper class to use for the return value of BIFs so that
* they may return either a Val* or IntrusivePtr<Val> (the former could * they may return either a Val* or IntrusivePtr<Val> (the former could
* potentially be deprecated). * potentially be deprecated).
*/ */
class BifReturnVal { class BifReturnVal
{
public: public:
template <typename T> BifReturnVal(IntrusivePtr<T> v) noexcept : rval(AdoptRef{}, v.release())
template <typename T> {
BifReturnVal(IntrusivePtr<T> v) noexcept }
: rval(AdoptRef{}, v.release())
{ }
BifReturnVal(std::nullptr_t) noexcept; BifReturnVal(std::nullptr_t) noexcept;
ValPtr rval; ValPtr rval;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,14 +1,15 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/CCL.h" #include "zeek/CCL.h"
#include <algorithm> #include <algorithm>
#include "zeek/RE.h"
#include "zeek/DFA.h" #include "zeek/DFA.h"
#include "zeek/RE.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
CCL::CCL() CCL::CCL()
{ {
@ -48,7 +49,8 @@ void CCL::Sort()
unsigned int CCL::MemoryAllocation() const unsigned int CCL::MemoryAllocation() const
{ {
return padded_sizeof(*this) + padded_sizeof(*syms) + util::pad_size(syms->size() * sizeof(int_list::value_type)); return padded_sizeof(*this) + padded_sizeof(*syms) +
util::pad_size(syms->size() * sizeof(int_list::value_type));
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -5,11 +5,13 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
namespace zeek::detail { namespace zeek::detail
{
using int_list = std::vector<std::intptr_t>; using int_list = std::vector<std::intptr_t>;
class CCL { class CCL
{
public: public:
CCL(); CCL();
~CCL(); ~CCL();
@ -24,15 +26,19 @@ public:
int_list* Syms() { return syms; } int_list* Syms() { return syms; }
void ReplaceSyms(int_list* new_syms) void ReplaceSyms(int_list* new_syms)
{ delete syms; syms = new_syms; } {
delete syms;
syms = new_syms;
}
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const; "GHI-572.")]] unsigned int
MemoryAllocation() const;
protected: protected:
int_list* syms; int_list* syms;
int negated; int negated;
int index; int index;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,24 +1,24 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/CompHash.h" #include "zeek/CompHash.h"
#include <cstring> #include <cstring>
#include <vector>
#include <map> #include <map>
#include <vector>
#include "zeek/ZeekString.h"
#include "zeek/Dict.h" #include "zeek/Dict.h"
#include "zeek/Val.h"
#include "zeek/RE.h"
#include "zeek/Reporter.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/RE.h"
#include "zeek/Reporter.h"
#include "zeek/Val.h"
#include "zeek/ZeekString.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
CompositeHash::CompositeHash(TypeListPtr composite_type) CompositeHash::CompositeHash(TypeListPtr composite_type) : type(std::move(composite_type))
: type(std::move(composite_type))
{ {
singleton_tag = TYPE_INTERNAL_ERROR; singleton_tag = TYPE_INTERNAL_ERROR;
@ -28,7 +28,7 @@ CompositeHash::CompositeHash(TypeListPtr composite_type)
if ( type->GetTypes().size() == 1 ) if ( type->GetTypes().size() == 1 )
{ {
if ( type->GetTypes()[0]->Tag() == TYPE_RECORD || if ( type->GetTypes()[0]->Tag() == TYPE_RECORD ||
type->GetTypes()[0]->Tag() == TYPE_VECTOR) type->GetTypes()[0]->Tag() == TYPE_VECTOR )
{ {
is_complex_type = true; is_complex_type = true;
is_singleton = false; is_singleton = false;
@ -61,8 +61,7 @@ CompositeHash::CompositeHash(TypeListPtr composite_type)
if ( size > 0 ) if ( size > 0 )
// Fixed size. Make sure what we get is fully aligned. // Fixed size. Make sure what we get is fully aligned.
key = reinterpret_cast<char*> key = reinterpret_cast<char*>(new double[size / sizeof(double) + 1]);
(new double[size/sizeof(double) + 1]);
else else
key = nullptr; key = nullptr;
} }
@ -70,12 +69,12 @@ CompositeHash::CompositeHash(TypeListPtr composite_type)
CompositeHash::~CompositeHash() CompositeHash::~CompositeHash()
{ {
delete [] key; delete[] key;
} }
// Computes the piece of the hash for Val*, returning the new kp. // Computes the piece of the hash for Val*, returning the new kp.
char* CompositeHash::SingleValHash(bool type_check, char* kp0, char* CompositeHash::SingleValHash(bool type_check, char* kp0, Type* bt, Val* v,
Type* bt, Val* v, bool optional) const bool optional) const
{ {
char* kp1 = nullptr; char* kp1 = nullptr;
InternalTypeTag t = bt->InternalType(); InternalTypeTag t = bt->InternalType();
@ -84,8 +83,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
{ {
// Add a marker saying whether the optional field is set. // Add a marker saying whether the optional field is set.
char* kp = AlignAndPadType<char>(kp0); char* kp = AlignAndPadType<char>(kp0);
*kp = ( v ? 1 : 0); *kp = (v ? 1 : 0);
kp0 = reinterpret_cast<char*>(kp+1); kp0 = reinterpret_cast<char*>(kp + 1);
if ( ! v ) if ( ! v )
return kp0; return kp0;
@ -98,12 +97,13 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
return nullptr; return nullptr;
} }
switch ( t ) { switch ( t )
{
case TYPE_INTERNAL_INT: case TYPE_INTERNAL_INT:
{ {
bro_int_t* kp = AlignAndPadType<bro_int_t>(kp0); bro_int_t* kp = AlignAndPadType<bro_int_t>(kp0);
*kp = v->AsInt(); *kp = v->AsInt();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
} }
break; break;
@ -111,7 +111,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
{ {
bro_uint_t* kp = AlignAndPadType<bro_uint_t>(kp0); bro_uint_t* kp = AlignAndPadType<bro_uint_t>(kp0);
*kp = v->AsCount(); *kp = v->AsCount();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
} }
break; break;
@ -119,7 +119,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
{ {
uint32_t* kp = AlignAndPadType<uint32_t>(kp0); uint32_t* kp = AlignAndPadType<uint32_t>(kp0);
v->AsAddr().CopyIPv6(kp); v->AsAddr().CopyIPv6(kp);
kp1 = reinterpret_cast<char*>(kp+4); kp1 = reinterpret_cast<char*>(kp + 4);
} }
break; break;
@ -128,7 +128,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
uint32_t* kp = AlignAndPadType<uint32_t>(kp0); uint32_t* kp = AlignAndPadType<uint32_t>(kp0);
v->AsSubNet().Prefix().CopyIPv6(kp); v->AsSubNet().Prefix().CopyIPv6(kp);
kp[4] = v->AsSubNet().Length(); kp[4] = v->AsSubNet().Length();
kp1 = reinterpret_cast<char*>(kp+5); kp1 = reinterpret_cast<char*>(kp + 5);
} }
break; break;
@ -136,37 +136,36 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
{ {
double* kp = AlignAndPadType<double>(kp0); double* kp = AlignAndPadType<double>(kp0);
*kp = v->InternalDouble(); *kp = v->InternalDouble();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
} }
break; break;
case TYPE_INTERNAL_VOID: case TYPE_INTERNAL_VOID:
case TYPE_INTERNAL_OTHER: case TYPE_INTERNAL_OTHER:
{ {
switch ( v->GetType()->Tag() ) { switch ( v->GetType()->Tag() )
{
case TYPE_FUNC: case TYPE_FUNC:
{ {
uint32_t* kp = AlignAndPadType<uint32_t>(kp0); uint32_t* kp = AlignAndPadType<uint32_t>(kp0);
*kp = v->AsFunc()->GetUniqueFuncID(); *kp = v->AsFunc()->GetUniqueFuncID();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
break; break;
} }
case TYPE_PATTERN: case TYPE_PATTERN:
{ {
const char* texts[2] = { const char* texts[2] = {v->AsPattern()->PatternText(),
v->AsPattern()->PatternText(), v->AsPattern()->AnywherePatternText()};
v->AsPattern()->AnywherePatternText()
};
uint64_t* kp; uint64_t* kp;
for ( int i = 0; i < 2; i++ ) for ( int i = 0; i < 2; i++ )
{ {
kp = AlignAndPadType<uint64_t>(kp0+i); kp = AlignAndPadType<uint64_t>(kp0 + i);
*kp = strlen(texts[i]) + 1; *kp = strlen(texts[i]) + 1;
} }
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
for ( int i = 0; i < 2; i++ ) for ( int i = 0; i < 2; i++ )
{ {
memcpy(kp1, texts[i], strlen(texts[i]) + 1); memcpy(kp1, texts[i], strlen(texts[i]) + 1);
@ -193,8 +192,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
if ( ! (rv_i || optional_attr) ) if ( ! (rv_i || optional_attr) )
return nullptr; return nullptr;
if ( ! (kp = SingleValHash(type_check, kp, if ( ! (kp =
rt->GetFieldType(i).get(), SingleValHash(type_check, kp, rt->GetFieldType(i).get(),
rv_i.get(), optional_attr)) ) rv_i.get(), optional_attr)) )
return nullptr; return nullptr;
} }
@ -208,13 +207,15 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
int* kp = AlignAndPadType<int>(kp0); int* kp = AlignAndPadType<int>(kp0);
TableVal* tv = v->AsTableVal(); TableVal* tv = v->AsTableVal();
*kp = tv->Size(); *kp = tv->Size();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
auto tbl = tv->AsTable(); auto tbl = tv->AsTable();
auto lv = make_intrusive<ListVal>(TYPE_ANY); auto lv = make_intrusive<ListVal>(TYPE_ANY);
struct HashKeyComparer { struct HashKeyComparer
bool operator()(const std::unique_ptr<HashKey>& a, const std::unique_ptr<HashKey>& b) const {
bool operator()(const std::unique_ptr<HashKey>& a,
const std::unique_ptr<HashKey>& b) const
{ {
if ( a->Hash() != b->Hash() ) if ( a->Hash() != b->Hash() )
return a->Hash() < b->Hash(); return a->Hash() < b->Hash();
@ -249,7 +250,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
{ {
auto val = tv->FindOrDefault(key); auto val = tv->FindOrDefault(key);
if ( ! (kp1 = SingleValHash(type_check, kp1, val->GetType().get(), if ( ! (kp1 =
SingleValHash(type_check, kp1, val->GetType().get(),
val.get(), false)) ) val.get(), false)) )
return nullptr; return nullptr;
} }
@ -263,22 +265,21 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
VectorVal* vv = v->AsVectorVal(); VectorVal* vv = v->AsVectorVal();
VectorType* vt = v->GetType()->AsVectorType(); VectorType* vt = v->GetType()->AsVectorType();
*kp = vv->Size(); *kp = vv->Size();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
for ( unsigned int i = 0; i < vv->Size(); ++i ) for ( unsigned int i = 0; i < vv->Size(); ++i )
{ {
auto val = vv->ValAt(i); auto val = vv->ValAt(i);
unsigned int* kp = AlignAndPadType<unsigned int>(kp1); unsigned int* kp = AlignAndPadType<unsigned int>(kp1);
*kp = i; *kp = i;
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
kp = AlignAndPadType<unsigned int>(kp1); kp = AlignAndPadType<unsigned int>(kp1);
*kp = val ? 1 : 0; *kp = val ? 1 : 0;
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
if ( val ) if ( val )
{ {
if ( ! (kp1 = SingleValHash(type_check, kp1, if ( ! (kp1 = SingleValHash(type_check, kp1, vt->Yield().get(),
vt->Yield().get(), val.get(), val.get(), false)) )
false)) )
return nullptr; return nullptr;
} }
} }
@ -290,12 +291,13 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
int* kp = AlignAndPadType<int>(kp0); int* kp = AlignAndPadType<int>(kp0);
ListVal* lv = v->AsListVal(); ListVal* lv = v->AsListVal();
*kp = lv->Length(); *kp = lv->Length();
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
for ( int i = 0; i < lv->Length(); ++i ) for ( int i = 0; i < lv->Length(); ++i )
{ {
Val* entry_val = lv->Idx(i).get(); Val* entry_val = lv->Idx(i).get();
if ( ! (kp1 = SingleValHash(type_check, kp1, entry_val->GetType().get(), if ( ! (kp1 = SingleValHash(type_check, kp1,
entry_val, false)) ) entry_val->GetType().get(), entry_val,
false)) )
return nullptr; return nullptr;
} }
} }
@ -303,7 +305,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
default: default:
{ {
reporter->InternalError("bad index type in CompositeHash::SingleValHash"); reporter->InternalError(
"bad index type in CompositeHash::SingleValHash");
return nullptr; return nullptr;
} }
} }
@ -319,7 +322,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
*kp = sval->Len(); // so we can recover the value *kp = sval->Len(); // so we can recover the value
kp1 = reinterpret_cast<char*>(kp+1); kp1 = reinterpret_cast<char*>(kp + 1);
memcpy(kp1, sval->Bytes(), sval->Len()); memcpy(kp1, sval->Bytes(), sval->Len());
kp1 += sval->Len(); kp1 += sval->Len();
@ -333,7 +336,6 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
return kp1; return kp1;
} }
std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_check) const std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_check) const
{ {
auto v = &argv; auto v = &argv;
@ -348,7 +350,7 @@ std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_c
// Cast away const to use ListVal - but since we // Cast away const to use ListVal - but since we
// re-introduce const on the recursive call, it should // re-introduce const on the recursive call, it should
// be okay; the only thing is that the ListVal unref's it. // be okay; the only thing is that the ListVal unref's it.
Val* ncv = (Val*) v; Val* ncv = (Val*)v;
lv.Append({NewRef{}, ncv}); lv.Append({NewRef{}, ncv});
return MakeHashKey(lv, type_check); return MakeHashKey(lv, type_check);
} }
@ -361,7 +363,7 @@ std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_c
if ( sz == 0 ) if ( sz == 0 )
return nullptr; return nullptr;
k = reinterpret_cast<char*>(new double[sz/sizeof(double) + 1]); k = reinterpret_cast<char*>(new double[sz / sizeof(double) + 1]);
type_check = false; // no need to type-check again. type_check = false; // no need to type-check again.
} }
@ -383,7 +385,7 @@ std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_c
return nullptr; return nullptr;
} }
return std::make_unique<HashKey>((k == key), (void*) k, kp - k); return std::make_unique<HashKey>((k == key), (void*)k, kp - k);
} }
std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) const std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) const
@ -401,7 +403,8 @@ std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool
if ( type_check && v->GetType()->InternalType() != singleton_tag ) if ( type_check && v->GetType()->InternalType() != singleton_tag )
return nullptr; return nullptr;
switch ( singleton_tag ) { switch ( singleton_tag )
{
case TYPE_INTERNAL_INT: case TYPE_INTERNAL_INT:
return std::make_unique<HashKey>(v->AsInt()); return std::make_unique<HashKey>(v->AsInt());
@ -424,10 +427,8 @@ std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool
if ( v->GetType()->Tag() == TYPE_PATTERN ) if ( v->GetType()->Tag() == TYPE_PATTERN )
{ {
const char* texts[2] = { const char* texts[2] = {v->AsPattern()->PatternText(),
v->AsPattern()->PatternText(), v->AsPattern()->AnywherePatternText()};
v->AsPattern()->AnywherePatternText()
};
int n = strlen(texts[0]) + strlen(texts[1]) + 2; // 2 for null int n = strlen(texts[0]) + strlen(texts[1]) + 2; // 2 for null
char* key = new char[n]; char* key = new char[n];
std::memcpy(key, texts[0], strlen(texts[0]) + 1); std::memcpy(key, texts[0], strlen(texts[0]) + 1);
@ -450,8 +451,7 @@ std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool
} }
} }
int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v, int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v, bool type_check, int sz, bool optional,
bool type_check, int sz, bool optional,
bool calc_static_size) const bool calc_static_size) const
{ {
InternalTypeTag t = bt->InternalType(); InternalTypeTag t = bt->InternalType();
@ -466,7 +466,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
return 0; return 0;
} }
switch ( t ) { switch ( t )
{
case TYPE_INTERNAL_INT: case TYPE_INTERNAL_INT:
case TYPE_INTERNAL_UNSIGNED: case TYPE_INTERNAL_UNSIGNED:
sz = SizeAlign(sz, sizeof(bro_int_t)); sz = SizeAlign(sz, sizeof(bro_int_t));
@ -489,7 +490,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
case TYPE_INTERNAL_VOID: case TYPE_INTERNAL_VOID:
case TYPE_INTERNAL_OTHER: case TYPE_INTERNAL_OTHER:
{ {
switch ( bt->Tag() ) { switch ( bt->Tag() )
{
case TYPE_FUNC: case TYPE_FUNC:
{ {
sz = SizeAlign(sz, sizeof(uint32_t)); sz = SizeAlign(sz, sizeof(uint32_t));
@ -502,8 +504,9 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
return (optional && ! calc_static_size) ? sz : 0; return (optional && ! calc_static_size) ? sz : 0;
sz = SizeAlign(sz, 2 * sizeof(uint64_t)); sz = SizeAlign(sz, 2 * sizeof(uint64_t));
sz += strlen(v->AsPattern()->PatternText()) sz += strlen(v->AsPattern()->PatternText()) +
+ strlen(v->AsPattern()->AnywherePatternText()) + 2; // 2 for null terminators strlen(v->AsPattern()->AnywherePatternText()) +
2; // 2 for null terminators
break; break;
} }
@ -522,8 +525,7 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
bool optional_attr = (a && a->Find(ATTR_OPTIONAL)); bool optional_attr = (a && a->Find(ATTR_OPTIONAL));
auto rv_v = rv ? rv->GetField(i) : nullptr; auto rv_v = rv ? rv->GetField(i) : nullptr;
sz = SingleTypeKeySize(rt->GetFieldType(i).get(), sz = SingleTypeKeySize(rt->GetFieldType(i).get(), rv_v.get(),
rv_v.get(),
type_check, sz, optional_attr, type_check, sz, optional_attr,
calc_static_size); calc_static_size);
if ( ! sz ) if ( ! sz )
@ -544,16 +546,16 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
for ( int i = 0; i < tv->Size(); ++i ) for ( int i = 0; i < tv->Size(); ++i )
{ {
const auto& key = lv->Idx(i); const auto& key = lv->Idx(i);
sz = SingleTypeKeySize(key->GetType().get(), key.get(), type_check, sz, false, sz = SingleTypeKeySize(key->GetType().get(), key.get(), type_check,
calc_static_size); sz, false, calc_static_size);
if ( ! sz ) if ( ! sz )
return 0; return 0;
if ( ! bt->IsSet() ) if ( ! bt->IsSet() )
{ {
auto val = tv->FindOrDefault(key); auto val = tv->FindOrDefault(key);
sz = SingleTypeKeySize(val->GetType().get(), val.get(), type_check, sz, sz = SingleTypeKeySize(val->GetType().get(), val.get(),
false, calc_static_size); type_check, sz, false, calc_static_size);
if ( ! sz ) if ( ! sz )
return 0; return 0;
} }
@ -578,7 +580,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
sz = SingleTypeKeySize(bt->AsVectorType()->Yield().get(), sz = SingleTypeKeySize(bt->AsVectorType()->Yield().get(),
val.get(), type_check, sz, false, val.get(), type_check, sz, false,
calc_static_size); calc_static_size);
if ( ! sz ) return 0; if ( ! sz )
return 0;
} }
break; break;
@ -593,9 +596,11 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
ListVal* lv = const_cast<ListVal*>(v->AsListVal()); ListVal* lv = const_cast<ListVal*>(v->AsListVal());
for ( int i = 0; i < lv->Length(); ++i ) for ( int i = 0; i < lv->Length(); ++i )
{ {
sz = SingleTypeKeySize(lv->Idx(i)->GetType().get(), lv->Idx(i).get(), sz =
SingleTypeKeySize(lv->Idx(i)->GetType().get(), lv->Idx(i).get(),
type_check, sz, false, calc_static_size); type_check, sz, false, calc_static_size);
if ( ! sz) return 0; if ( ! sz )
return 0;
} }
break; break;
@ -603,7 +608,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
default: default:
{ {
reporter->InternalError("bad index type in CompositeHash::CompositeHash"); reporter->InternalError(
"bad index type in CompositeHash::CompositeHash");
return 0; return 0;
} }
} }
@ -645,8 +651,8 @@ int CompositeHash::ComputeKeySize(const Val* v, bool type_check, bool calc_stati
int sz = 0; int sz = 0;
for ( auto i = 0u; i < tl.size(); ++i ) for ( auto i = 0u; i < tl.size(); ++i )
{ {
sz = SingleTypeKeySize(tl[i].get(), v ? v->AsListVal()->Idx(i).get() : nullptr, sz = SingleTypeKeySize(tl[i].get(), v ? v->AsListVal()->Idx(i).get() : nullptr, type_check,
type_check, sz, false, calc_static_size); sz, false, calc_static_size);
if ( ! sz ) if ( ! sz )
return 0; return 0;
} }
@ -656,7 +662,7 @@ int CompositeHash::ComputeKeySize(const Val* v, bool type_check, bool calc_stati
namespace namespace
{ {
inline bool is_power_of_2(bro_uint_t x) inline bool is_power_of_2(bro_uint_t x)
{ {
return ((x - 1) & x) == 0; return ((x - 1) & x) == 0;
} }
@ -691,7 +697,7 @@ void* CompositeHash::AlignAndPad(char* ptr, unsigned int size) const
// Not aligned - zero pad. // Not aligned - zero pad.
*ptr++ = '\0'; *ptr++ = '\0';
return reinterpret_cast<void *>(ptr); return reinterpret_cast<void*>(ptr);
} }
int CompositeHash::SizeAlign(int offset, unsigned int size) const int CompositeHash::SizeAlign(int offset, unsigned int size) const
@ -717,7 +723,7 @@ ListValPtr CompositeHash::RecoverVals(const HashKey& k) const
{ {
auto l = make_intrusive<ListVal>(TYPE_ANY); auto l = make_intrusive<ListVal>(TYPE_ANY);
const auto& tl = type->GetTypes(); const auto& tl = type->GetTypes();
const char* kp = (const char*) k.Key(); const char* kp = (const char*)k.Key();
const char* const k_end = kp + k.Size(); const char* const k_end = kp + k.Size();
for ( const auto& type : tl ) for ( const auto& type : tl )
@ -734,10 +740,8 @@ ListValPtr CompositeHash::RecoverVals(const HashKey& k) const
return l; return l;
} }
const char* CompositeHash::RecoverOneVal( const char* CompositeHash::RecoverOneVal(const HashKey& k, const char* kp0, const char* const k_end,
const HashKey& k, const char* kp0, Type* t, ValPtr* pval, bool optional) const
const char* const k_end, Type* t,
ValPtr* pval, bool optional) const
{ {
// k->Size() == 0 for a single empty string. // k->Size() == 0 for a single empty string.
if ( kp0 >= k_end && k.Size() > 0 ) if ( kp0 >= k_end && k.Size() > 0 )
@ -750,7 +754,7 @@ const char* CompositeHash::RecoverOneVal(
if ( optional ) if ( optional )
{ {
const char* kp = AlignType<char>(kp0); const char* kp = AlignType<char>(kp0);
kp0 = kp1 = reinterpret_cast<const char*>(kp+1); kp0 = kp1 = reinterpret_cast<const char*>(kp + 1);
if ( ! *kp ) if ( ! *kp )
{ {
@ -759,11 +763,12 @@ const char* CompositeHash::RecoverOneVal(
} }
} }
switch ( it ) { switch ( it )
{
case TYPE_INTERNAL_INT: case TYPE_INTERNAL_INT:
{ {
const bro_int_t* const kp = AlignType<bro_int_t>(kp0); const bro_int_t* const kp = AlignType<bro_int_t>(kp0);
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
if ( tag == TYPE_ENUM ) if ( tag == TYPE_ENUM )
*pval = t->AsEnumType()->GetEnumVal(*kp); *pval = t->AsEnumType()->GetEnumVal(*kp);
@ -773,7 +778,8 @@ const char* CompositeHash::RecoverOneVal(
*pval = val_mgr->Int(*kp); *pval = val_mgr->Int(*kp);
else else
{ {
reporter->InternalError("bad internal unsigned int in CompositeHash::RecoverOneVal()"); reporter->InternalError(
"bad internal unsigned int in CompositeHash::RecoverOneVal()");
*pval = nullptr; *pval = nullptr;
} }
} }
@ -782,9 +788,10 @@ const char* CompositeHash::RecoverOneVal(
case TYPE_INTERNAL_UNSIGNED: case TYPE_INTERNAL_UNSIGNED:
{ {
const bro_uint_t* const kp = AlignType<bro_uint_t>(kp0); const bro_uint_t* const kp = AlignType<bro_uint_t>(kp0);
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
switch ( tag ) { switch ( tag )
{
case TYPE_COUNT: case TYPE_COUNT:
*pval = val_mgr->Count(*kp); *pval = val_mgr->Count(*kp);
break; break;
@ -794,7 +801,8 @@ const char* CompositeHash::RecoverOneVal(
break; break;
default: default:
reporter->InternalError("bad internal unsigned int in CompositeHash::RecoverOneVal()"); reporter->InternalError(
"bad internal unsigned int in CompositeHash::RecoverOneVal()");
*pval = nullptr; *pval = nullptr;
break; break;
} }
@ -804,7 +812,7 @@ const char* CompositeHash::RecoverOneVal(
case TYPE_INTERNAL_DOUBLE: case TYPE_INTERNAL_DOUBLE:
{ {
const double* const kp = AlignType<double>(kp0); const double* const kp = AlignType<double>(kp0);
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
if ( tag == TYPE_INTERVAL ) if ( tag == TYPE_INTERVAL )
*pval = make_intrusive<IntervalVal>(*kp, 1.0); *pval = make_intrusive<IntervalVal>(*kp, 1.0);
@ -818,17 +826,19 @@ const char* CompositeHash::RecoverOneVal(
case TYPE_INTERNAL_ADDR: case TYPE_INTERNAL_ADDR:
{ {
const uint32_t* const kp = AlignType<uint32_t>(kp0); const uint32_t* const kp = AlignType<uint32_t>(kp0);
kp1 = reinterpret_cast<const char*>(kp+4); kp1 = reinterpret_cast<const char*>(kp + 4);
IPAddr addr(IPv6, kp, IPAddr::Network); IPAddr addr(IPv6, kp, IPAddr::Network);
switch ( tag ) { switch ( tag )
{
case TYPE_ADDR: case TYPE_ADDR:
*pval = make_intrusive<AddrVal>(addr); *pval = make_intrusive<AddrVal>(addr);
break; break;
default: default:
reporter->InternalError("bad internal address in CompositeHash::RecoverOneVal()"); reporter->InternalError(
"bad internal address in CompositeHash::RecoverOneVal()");
*pval = nullptr; *pval = nullptr;
break; break;
} }
@ -838,7 +848,7 @@ const char* CompositeHash::RecoverOneVal(
case TYPE_INTERNAL_SUBNET: case TYPE_INTERNAL_SUBNET:
{ {
const uint32_t* const kp = AlignType<uint32_t>(kp0); const uint32_t* const kp = AlignType<uint32_t>(kp0);
kp1 = reinterpret_cast<const char*>(kp+5); kp1 = reinterpret_cast<const char*>(kp + 5);
*pval = make_intrusive<SubNetVal>(kp, kp[4]); *pval = make_intrusive<SubNetVal>(kp, kp[4]);
} }
break; break;
@ -846,31 +856,38 @@ const char* CompositeHash::RecoverOneVal(
case TYPE_INTERNAL_VOID: case TYPE_INTERNAL_VOID:
case TYPE_INTERNAL_OTHER: case TYPE_INTERNAL_OTHER:
{ {
switch ( t->Tag() ) { switch ( t->Tag() )
{
case TYPE_FUNC: case TYPE_FUNC:
{ {
const uint32_t* const kp = AlignType<uint32_t>(kp0); const uint32_t* const kp = AlignType<uint32_t>(kp0);
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
const auto& f = Func::GetFuncPtrByID(*kp); const auto& f = Func::GetFuncPtrByID(*kp);
if ( ! f ) if ( ! f )
reporter->InternalError("failed to look up unique function id %" PRIu32 " in CompositeHash::RecoverOneVal()", *kp); reporter->InternalError(
"failed to look up unique function id %" PRIu32
" in CompositeHash::RecoverOneVal()",
*kp);
*pval = make_intrusive<FuncVal>(f); *pval = make_intrusive<FuncVal>(f);
const auto& pvt = (*pval)->GetType(); const auto& pvt = (*pval)->GetType();
if ( ! pvt ) if ( ! pvt )
reporter->InternalError("bad aggregate Val in CompositeHash::RecoverOneVal()"); reporter->InternalError(
"bad aggregate Val in CompositeHash::RecoverOneVal()");
else if ( t->Tag() != TYPE_FUNC && ! same_type(pvt, t) ) else if ( t->Tag() != TYPE_FUNC && ! same_type(pvt, t) )
// ### Maybe fix later, but may be fundamentally // ### Maybe fix later, but may be fundamentally
// un-checkable --US // un-checkable --US
reporter->InternalError("inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); reporter->InternalError(
"inconsistent aggregate Val in CompositeHash::RecoverOneVal()");
// ### A crude approximation for now. // ### A crude approximation for now.
else if ( t->Tag() == TYPE_FUNC && pvt->Tag() != TYPE_FUNC ) else if ( t->Tag() == TYPE_FUNC && pvt->Tag() != TYPE_FUNC )
reporter->InternalError("inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); reporter->InternalError(
"inconsistent aggregate Val in CompositeHash::RecoverOneVal()");
} }
break; break;
@ -888,13 +905,14 @@ const char* CompositeHash::RecoverOneVal(
{ {
const uint64_t* const len = AlignType<uint64_t>(kp0); const uint64_t* const len = AlignType<uint64_t>(kp0);
kp1 = reinterpret_cast<const char*>(len+2); kp1 = reinterpret_cast<const char*>(len + 2);
re = new RE_Matcher(kp1, kp1 + len[0]); re = new RE_Matcher(kp1, kp1 + len[0]);
kp1 += len[0] + len[1]; kp1 += len[0] + len[1];
} }
if ( ! re->Compile() ) if ( ! re->Compile() )
reporter->InternalError("failed compiling table/set key pattern: %s", reporter->InternalError(
"failed compiling table/set key pattern: %s",
re->PatternText()); re->PatternText());
*pval = make_intrusive<PatternVal>(re); *pval = make_intrusive<PatternVal>(re);
@ -916,15 +934,17 @@ const char* CompositeHash::RecoverOneVal(
Attributes* a = rt->FieldDecl(i)->attrs.get(); Attributes* a = rt->FieldDecl(i)->attrs.get();
bool optional = (a && a->Find(ATTR_OPTIONAL)); bool optional = (a && a->Find(ATTR_OPTIONAL));
kp = RecoverOneVal(k, kp, k_end, kp = RecoverOneVal(k, kp, k_end, rt->GetFieldType(i).get(), &v,
rt->GetFieldType(i).get(), &v, optional); optional);
// An earlier call to reporter->InternalError would have called abort() and broken the // An earlier call to reporter->InternalError would have called
// call tree that clang-tidy is relying on to get the error described. // abort() and broken the call tree that clang-tidy is relying on to
// get the error described.
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Branch) // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Branch)
if ( ! (v || optional) ) if ( ! (v || optional) )
{ {
reporter->InternalError("didn't recover expected number of fields from HashKey"); reporter->InternalError(
"didn't recover expected number of fields from HashKey");
pval = nullptr; pval = nullptr;
break; break;
} }
@ -949,14 +969,15 @@ const char* CompositeHash::RecoverOneVal(
int n; int n;
const int* const kp = AlignType<int>(kp0); const int* const kp = AlignType<int>(kp0);
n = *kp; n = *kp;
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
TableType* tt = t->AsTableType(); TableType* tt = t->AsTableType();
auto tv = make_intrusive<TableVal>(IntrusivePtr{NewRef{}, tt}); auto tv = make_intrusive<TableVal>(IntrusivePtr{NewRef{}, tt});
for ( int i = 0; i < n; ++i ) for ( int i = 0; i < n; ++i )
{ {
ValPtr key; ValPtr key;
kp1 = RecoverOneVal(k, kp1, k_end, tt->GetIndices().get(), &key, false); kp1 = RecoverOneVal(k, kp1, k_end, tt->GetIndices().get(), &key,
false);
if ( t->IsSet() ) if ( t->IsSet() )
tv->Assign(std::move(key), nullptr); tv->Assign(std::move(key), nullptr);
@ -978,7 +999,7 @@ const char* CompositeHash::RecoverOneVal(
unsigned int n; unsigned int n;
const unsigned int* kp = AlignType<unsigned int>(kp0); const unsigned int* kp = AlignType<unsigned int>(kp0);
n = *kp; n = *kp;
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
VectorType* vt = t->AsVectorType(); VectorType* vt = t->AsVectorType();
auto vv = make_intrusive<VectorVal>(IntrusivePtr{NewRef{}, vt}); auto vv = make_intrusive<VectorVal>(IntrusivePtr{NewRef{}, vt});
@ -986,10 +1007,10 @@ const char* CompositeHash::RecoverOneVal(
{ {
kp = AlignType<unsigned int>(kp1); kp = AlignType<unsigned int>(kp1);
unsigned int index = *kp; unsigned int index = *kp;
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
kp = AlignType<unsigned int>(kp1); kp = AlignType<unsigned int>(kp1);
unsigned int have_val = *kp; unsigned int have_val = *kp;
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
ValPtr value; ValPtr value;
if ( have_val ) if ( have_val )
@ -1008,7 +1029,7 @@ const char* CompositeHash::RecoverOneVal(
int n; int n;
const int* const kp = AlignType<int>(kp0); const int* const kp = AlignType<int>(kp0);
n = *kp; n = *kp;
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
TypeList* tl = t->AsTypeList(); TypeList* tl = t->AsTypeList();
auto lv = make_intrusive<ListVal>(TYPE_ANY); auto lv = make_intrusive<ListVal>(TYPE_ANY);
@ -1047,10 +1068,10 @@ const char* CompositeHash::RecoverOneVal(
{ {
const int* const kp = AlignType<int>(kp0); const int* const kp = AlignType<int>(kp0);
n = *kp; n = *kp;
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp + 1);
} }
*pval = make_intrusive<StringVal>(new String((const byte_vec) kp1, n, true)); *pval = make_intrusive<StringVal>(new String((const byte_vec)kp1, n, true));
kp1 += n; kp1 += n;
} }
break; break;
@ -1062,4 +1083,4 @@ const char* CompositeHash::RecoverOneVal(
return kp1; return kp1;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -4,21 +4,24 @@
#include <memory> #include <memory>
#include "zeek/Type.h"
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
#include "zeek/Type.h"
namespace zeek { namespace zeek
{
class ListVal; class ListVal;
using ListValPtr = zeek::IntrusivePtr<ListVal>; using ListValPtr = zeek::IntrusivePtr<ListVal>;
} // namespace zeek } // namespace zeek
namespace zeek::detail { namespace zeek::detail
{
class HashKey; class HashKey;
class CompositeHash { class CompositeHash
{
public: public:
explicit CompositeHash(TypeListPtr composite_type); explicit CompositeHash(TypeListPtr composite_type);
~CompositeHash(); ~CompositeHash();
@ -30,24 +33,26 @@ public:
// Given a hash key, recover the values used to create it. // Given a hash key, recover the values used to create it.
ListValPtr RecoverVals(const HashKey& k) const; ListValPtr RecoverVals(const HashKey& k) const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const { return padded_sizeof(*this) + util::pad_size(size); } "GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this) + util::pad_size(size);
}
protected: protected:
std::unique_ptr<HashKey> ComputeSingletonHash(const Val* v, bool type_check) const; std::unique_ptr<HashKey> ComputeSingletonHash(const Val* v, bool type_check) const;
// Computes the piece of the hash for Val*, returning the new kp. // Computes the piece of the hash for Val*, returning the new kp.
// Used as a helper for ComputeHash in the non-singleton case. // Used as a helper for ComputeHash in the non-singleton case.
char* SingleValHash(bool type_check, char* kp, Type* bt, Val* v, char* SingleValHash(bool type_check, char* kp, Type* bt, Val* v, bool optional) const;
bool optional) const;
// Recovers just one Val of possibly many; called from RecoverVals. // Recovers just one Val of possibly many; called from RecoverVals.
// Upon return, pval will point to the recovered Val of type t. // Upon return, pval will point to the recovered Val of type t.
// Returns and updated kp for the next Val. Calls reporter->InternalError() // Returns and updated kp for the next Val. Calls reporter->InternalError()
// upon errors, so there is no return value for invalid input. // upon errors, so there is no return value for invalid input.
const char* RecoverOneVal( const char* RecoverOneVal(const HashKey& k, const char* kp, const char* const k_end, Type* t,
const HashKey& k, const char* kp, const char* const k_end, ValPtr* pval, bool optional) const;
Type* t, ValPtr* pval, bool optional) const;
// Rounds the given pointer up to the nearest multiple of the // Rounds the given pointer up to the nearest multiple of the
// given size, if not already a multiple. // given size, if not already a multiple.
@ -61,33 +66,25 @@ protected:
// of the given size. // of the given size.
int SizeAlign(int offset, unsigned int size) const; int SizeAlign(int offset, unsigned int size) const;
template<class T> template <class T> T* AlignAndPadType(char* ptr) const
T* AlignAndPadType(char* ptr) const
{ {
return reinterpret_cast<T*>(AlignAndPad(ptr, sizeof(T))); return reinterpret_cast<T*>(AlignAndPad(ptr, sizeof(T)));
} }
template<class T> template <class T> const T* AlignType(const char* ptr) const
const T* AlignType(const char* ptr) const
{ {
return reinterpret_cast<const T*>(Align(ptr, sizeof(T))); return reinterpret_cast<const T*>(Align(ptr, sizeof(T)));
} }
template<class T> template <class T> int SizeAlignType(int offset) const { return SizeAlign(offset, sizeof(T)); }
int SizeAlignType(int offset) const
{
return SizeAlign(offset, sizeof(T));
}
// Compute the size of the composite key. If v is non-nil then // Compute the size of the composite key. If v is non-nil then
// the value is computed for the particular list of values. // the value is computed for the particular list of values.
// Returns 0 if the key has an indeterminant size (if v not given), // Returns 0 if the key has an indeterminant size (if v not given),
// or if v doesn't match the index type (if given). // or if v doesn't match the index type (if given).
int ComputeKeySize(const Val* v, bool type_check, int ComputeKeySize(const Val* v, bool type_check, bool calc_static_size) const;
bool calc_static_size) const;
int SingleTypeKeySize(Type*, const Val*, int SingleTypeKeySize(Type*, const Val*, bool type_check, int sz, bool optional,
bool type_check, int sz, bool optional,
bool calc_static_size) const; bool calc_static_size) const;
TypeListPtr type; TypeListPtr type;
@ -99,6 +96,6 @@ protected:
bool is_complex_type; bool is_complex_type;
InternalTypeTag singleton_tag; InternalTypeTag singleton_tag;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,34 +1,34 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Conn.h" #include "zeek/Conn.h"
#include <ctype.h>
#include <binpac.h> #include <binpac.h>
#include <ctype.h>
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/RunState.h"
#include "zeek/NetVar.h"
#include "zeek/Event.h" #include "zeek/Event.h"
#include "zeek/session/Manager.h" #include "zeek/NetVar.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/RunState.h"
#include "zeek/Timer.h" #include "zeek/Timer.h"
#include "zeek/iosource/IOSource.h"
#include "zeek/analyzer/protocol/pia/PIA.h"
#include "zeek/TunnelEncapsulation.h" #include "zeek/TunnelEncapsulation.h"
#include "zeek/analyzer/Analyzer.h" #include "zeek/analyzer/Analyzer.h"
#include "zeek/analyzer/Manager.h" #include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/protocol/pia/PIA.h"
#include "zeek/iosource/IOSource.h" #include "zeek/iosource/IOSource.h"
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" #include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
#include "zeek/packet_analysis/protocol/tcp/TCP.h" #include "zeek/packet_analysis/protocol/tcp/TCP.h"
#include "zeek/session/Manager.h"
#include "zeek/zeek-config.h"
namespace zeek { namespace zeek
{
uint64_t Connection::total_connections = 0; uint64_t Connection::total_connections = 0;
uint64_t Connection::current_connections = 0; uint64_t Connection::current_connections = 0;
Connection::Connection(const detail::ConnKey& k, double t, Connection::Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow,
const ConnTuple* id, uint32_t flow, const Packet* pkt) const Packet* pkt)
: Session(t, connection_timeout, connection_status_update, : Session(t, connection_timeout, connection_status_update,
detail::connection_status_update_interval), detail::connection_status_update_interval),
key(k) key(k)
@ -96,8 +96,7 @@ void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& a
if ( *encapsulation != *arg_encap ) if ( *encapsulation != *arg_encap )
{ {
if ( tunnel_changed ) if ( tunnel_changed )
EnqueueEvent(tunnel_changed, nullptr, GetVal(), EnqueueEvent(tunnel_changed, nullptr, GetVal(), arg_encap->ToVal());
arg_encap->ToVal());
encapsulation = std::make_shared<EncapsulationStack>(*arg_encap); encapsulation = std::make_shared<EncapsulationStack>(*arg_encap);
} }
@ -144,12 +143,10 @@ void Connection::Done()
} }
} }
void Connection::NextPacket(double t, bool is_orig, void Connection::NextPacket(double t, bool is_orig, const IP_Hdr* ip, int len, int caplen,
const IP_Hdr* ip, int len, int caplen, const u_char*& data, int& record_packet, int& record_content,
const u_char*& data,
int& record_packet, int& record_content,
// arguments for reproducing packets // arguments for reproducing packets
const Packet *pkt) const Packet* pkt)
{ {
run_state::current_timestamp = t; run_state::current_timestamp = t;
run_state::current_pkt = pkt; run_state::current_pkt = pkt;
@ -177,8 +174,7 @@ bool Connection::IsReuse(double t, const u_char* pkt)
return adapter && adapter->IsReuse(t, pkt); return adapter && adapter->IsReuse(t, pkt);
} }
bool Connection::ScaledHistoryEntry(char code, uint32_t& counter, bool Connection::ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold,
uint32_t& scaling_threshold,
uint32_t scaling_base) uint32_t scaling_base)
{ {
if ( ++counter == scaling_threshold ) if ( ++counter == scaling_threshold )
@ -202,8 +198,7 @@ bool Connection::ScaledHistoryEntry(char code, uint32_t& counter,
return false; return false;
} }
void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold)
uint32_t threshold)
{ {
if ( ! e ) if ( ! e )
return; return;
@ -213,11 +208,7 @@ void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig,
// and at this stage it's not a *multiple* instance. // and at this stage it's not a *multiple* instance.
return; return;
EnqueueEvent(e, nullptr, EnqueueEvent(e, nullptr, GetVal(), val_mgr->Bool(is_orig), val_mgr->Count(threshold));
GetVal(),
val_mgr->Bool(is_orig),
val_mgr->Count(threshold)
);
} }
const RecordValPtr& Connection::GetVal() const RecordValPtr& Connection::GetVal()
@ -273,7 +264,6 @@ const RecordValPtr& Connection::GetVal()
if ( inner_vlan != 0 ) if ( inner_vlan != 0 )
conn_val->Assign(10, inner_vlan); conn_val->Assign(10, inner_vlan);
} }
if ( adapter ) if ( adapter )
@ -320,14 +310,13 @@ static inline bool is_version_sep(const char* s, const char* end)
// foo-1.2.3 // foo-1.2.3
(s < end - 1 && ispunct(s[0]) && isdigit(s[1])) || (s < end - 1 && ispunct(s[0]) && isdigit(s[1])) ||
// foo-v1.2.3 // foo-v1.2.3
(s < end - 2 && ispunct(s[0]) && (s < end - 2 && ispunct(s[0]) && tolower(s[1]) == 'v' && isdigit(s[2])) ||
tolower(s[1]) == 'v' && isdigit(s[2])) ||
// foo 1.2.3 // foo 1.2.3
isspace(s[0]); isspace(s[0]);
} }
void Connection::Match(detail::Rule::PatternType type, const u_char* data, int len, void Connection::Match(detail::Rule::PatternType type, const u_char* data, int len, bool is_orig,
bool is_orig, bool bol, bool eol, bool clear_state) bool bol, bool eol, bool clear_state)
{ {
if ( primary_PIA ) if ( primary_PIA )
primary_PIA->Match(type, data, len, is_orig, bol, eol, clear_state); primary_PIA->Match(type, data, len, is_orig, bol, eol, clear_state);
@ -383,10 +372,10 @@ unsigned int Connection::MemoryAllocation() const
{ {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return session::Session::MemoryAllocation() + padded_sizeof(*this) return session::Session::MemoryAllocation() + padded_sizeof(*this) +
+ (timers.MemoryAllocation() - padded_sizeof(timers)) (timers.MemoryAllocation() - padded_sizeof(timers)) +
+ (conn_val ? conn_val->MemoryAllocation() : 0) (conn_val ? conn_val->MemoryAllocation() : 0) +
+ (adapter ? adapter->MemoryAllocation(): 0) (adapter ? adapter->MemoryAllocation() : 0)
// primary_PIA is already contained in the analyzer tree. // primary_PIA is already contained in the analyzer tree.
; ;
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
@ -404,7 +393,8 @@ void Connection::Describe(ODesc* d) const
{ {
session::Session::Describe(d); session::Session::Describe(d);
switch ( proto ) { switch ( proto )
{
case TRANSPORT_TCP: case TRANSPORT_TCP:
d->Add("TCP"); d->Add("TCP");
break; break;
@ -419,14 +409,12 @@ void Connection::Describe(ODesc* d) const
case TRANSPORT_UNKNOWN: case TRANSPORT_UNKNOWN:
d->Add("unknown"); d->Add("unknown");
reporter->InternalWarning( reporter->InternalWarning("unknown transport in Connction::Describe()");
"unknown transport in Connction::Describe()");
break; break;
default: default:
reporter->InternalError( reporter->InternalError("unhandled transport type in Connection::Describe");
"unhandled transport type in Connection::Describe");
} }
d->SP(); d->SP();
@ -455,8 +443,7 @@ void Connection::IDString(ODesc* d) const
d->Add(ntohs(resp_port)); d->Add(ntohs(resp_port));
} }
void Connection::SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, void Connection::SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, analyzer::pia::PIA* pia)
analyzer::pia::PIA* pia)
{ {
adapter = aa; adapter = aa;
primary_PIA = pia; primary_PIA = pia;
@ -477,12 +464,8 @@ void Connection::CheckFlowLabel(bool is_orig, uint32_t flow_label)
if ( connection_flow_label_changed && if ( connection_flow_label_changed &&
(is_orig ? saw_first_orig_packet : saw_first_resp_packet) ) (is_orig ? saw_first_orig_packet : saw_first_resp_packet) )
{ {
EnqueueEvent(connection_flow_label_changed, nullptr, EnqueueEvent(connection_flow_label_changed, nullptr, GetVal(), val_mgr->Bool(is_orig),
GetVal(), val_mgr->Count(my_flow_label), val_mgr->Count(flow_label));
val_mgr->Bool(is_orig),
val_mgr->Count(my_flow_label),
val_mgr->Count(flow_label)
);
} }
my_flow_label = flow_label; my_flow_label = flow_label;
@ -494,10 +477,9 @@ void Connection::CheckFlowLabel(bool is_orig, uint32_t flow_label)
saw_first_resp_packet = 1; saw_first_resp_packet = 1;
} }
bool Connection::PermitWeird(const char* name, uint64_t threshold, uint64_t rate, bool Connection::PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration)
double duration)
{ {
return detail::PermitWeird(weird_state, name, threshold, rate, duration); return detail::PermitWeird(weird_state, name, threshold, rate, duration);
} }
} // namespace zeek } // namespace zeek

View file

@ -3,26 +3,25 @@
#pragma once #pragma once
#include <sys/types.h> #include <sys/types.h>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include "zeek/Dict.h" #include "zeek/Dict.h"
#include "zeek/Timer.h"
#include "zeek/Rule.h"
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/Rule.h"
#include "zeek/Timer.h"
#include "zeek/UID.h" #include "zeek/UID.h"
#include "zeek/WeirdState.h" #include "zeek/WeirdState.h"
#include "zeek/ZeekArgs.h" #include "zeek/ZeekArgs.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/session/Session.h"
#include "zeek/iosource/Packet.h"
#include "zeek/analyzer/Tag.h"
#include "zeek/analyzer/Analyzer.h" #include "zeek/analyzer/Analyzer.h"
#include "zeek/analyzer/Tag.h"
#include "zeek/iosource/Packet.h"
#include "zeek/session/Session.h"
namespace zeek { namespace zeek
{
class Connection; class Connection;
class EncapsulationStack; class EncapsulationStack;
@ -32,47 +31,59 @@ class RecordVal;
using ValPtr = IntrusivePtr<Val>; using ValPtr = IntrusivePtr<Val>;
using RecordValPtr = IntrusivePtr<RecordVal>; using RecordValPtr = IntrusivePtr<RecordVal>;
namespace session { class Manager; } namespace session
namespace detail { {
class Manager;
}
namespace detail
{
class Specific_RE_Matcher; class Specific_RE_Matcher;
class RuleEndpointState; class RuleEndpointState;
class RuleHdrTest; class RuleHdrTest;
} // namespace detail } // namespace detail
namespace analyzer { class Analyzer; } namespace analyzer
namespace packet_analysis::IP { class SessionAdapter; } {
class Analyzer;
}
namespace packet_analysis::IP
{
class SessionAdapter;
}
enum ConnEventToFlag { enum ConnEventToFlag
{
NUL_IN_LINE, NUL_IN_LINE,
SINGULAR_CR, SINGULAR_CR,
SINGULAR_LF, SINGULAR_LF,
NUM_EVENTS_TO_FLAG, NUM_EVENTS_TO_FLAG,
}; };
struct ConnTuple { struct ConnTuple
{
IPAddr src_addr; IPAddr src_addr;
IPAddr dst_addr; IPAddr dst_addr;
uint32_t src_port; uint32_t src_port;
uint32_t dst_port; uint32_t dst_port;
bool is_one_way; // if true, don't canonicalize order bool is_one_way; // if true, don't canonicalize order
TransportProto proto; TransportProto proto;
}; };
using ConnID [[deprecated("Remove in v5.1. Use zeek::ConnTuple.")]] = ConnTuple; using ConnID [[deprecated("Remove in v5.1. Use zeek::ConnTuple.")]] = ConnTuple;
static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1, static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1, const IPAddr& addr2,
const IPAddr& addr2, uint32_t p2) uint32_t p2)
{ {
return addr1 < addr2 || (addr1 == addr2 && p1 < p2); return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
} }
class Connection final : public session::Session { class Connection final : public session::Session
{
public: public:
Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow,
Connection(const detail::ConnKey& k, double t, const ConnTuple* id, const Packet* pkt);
uint32_t flow, const Packet* pkt);
~Connection() override; ~Connection() override;
/** /**
@ -101,12 +112,10 @@ public:
// If record_content is true, then its entire contents should // If record_content is true, then its entire contents should
// be recorded, otherwise just up through the transport header. // be recorded, otherwise just up through the transport header.
// Both are assumed set to true when called. // Both are assumed set to true when called.
void NextPacket(double t, bool is_orig, void NextPacket(double t, bool is_orig, const IP_Hdr* ip, int len, int caplen,
const IP_Hdr* ip, int len, int caplen, const u_char*& data, int& record_packet, int& record_content,
const u_char*& data,
int& record_packet, int& record_content,
// arguments for reproducing packets // arguments for reproducing packets
const Packet *pkt); const Packet* pkt);
// Keys are only considered valid for a connection when a // Keys are only considered valid for a connection when a
// connection is in the session map. If it is removed, the key // connection is in the session map. If it is removed, the key
@ -114,8 +123,8 @@ public:
const detail::ConnKey& Key() const { return key; } const detail::ConnKey& Key() const { return key; }
session::detail::Key SessionKey(bool copy) const override session::detail::Key SessionKey(bool copy) const override
{ {
return session::detail::Key{ return session::detail::Key{&key, sizeof(key), session::detail::Key::CONNECTION_KEY_TYPE,
&key, sizeof(key), session::detail::Key::CONNECTION_KEY_TYPE, copy}; copy};
} }
const IPAddr& OrigAddr() const { return orig_addr; } const IPAddr& OrigAddr() const { return orig_addr; }
@ -158,8 +167,8 @@ public:
*/ */
void AppendAddl(const char* str); void AppendAddl(const char* str);
void Match(detail::Rule::PatternType type, const u_char* data, int len, void Match(detail::Rule::PatternType type, const u_char* data, int len, bool is_orig, bool bol,
bool is_orig, bool bol, bool eol, bool clear_state); bool eol, bool clear_state);
/** /**
* Generates connection removal event(s). * Generates connection removal event(s).
@ -187,15 +196,15 @@ public:
// Statistics. // Statistics.
// Just a lower bound. // Just a lower bound.
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const override; "GHI-572.")]] unsigned int
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] MemoryAllocation() const override;
unsigned int MemoryAllocationVal() const override; [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocationVal() const override;
static uint64_t TotalConnections() static uint64_t TotalConnections() { return total_connections; }
{ return total_connections; } static uint64_t CurrentConnections() { return current_connections; }
static uint64_t CurrentConnections()
{ return current_connections; }
// Returns true if the history was already seen, false otherwise. // Returns true if the history was already seen, false otherwise.
bool CheckHistory(uint32_t mask, char code) bool CheckHistory(uint32_t mask, char code)
@ -214,12 +223,10 @@ public:
// code if it has crossed the next scaling threshold. Scaling // code if it has crossed the next scaling threshold. Scaling
// is done in terms of powers of the third argument. // is done in terms of powers of the third argument.
// Returns true if the threshold was crossed, false otherwise. // Returns true if the threshold was crossed, false otherwise.
bool ScaledHistoryEntry(char code, uint32_t& counter, bool ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold,
uint32_t& scaling_threshold,
uint32_t scaling_base = 10); uint32_t scaling_base = 10);
void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold);
uint32_t threshold);
void AddHistory(char code) { history += code; } void AddHistory(char code) { history += code; }
@ -231,23 +238,20 @@ public:
// Sets the transport protocol in use. // Sets the transport protocol in use.
void SetTransport(TransportProto arg_proto) { proto = arg_proto; } void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
void SetUID(const UID &arg_uid) { uid = arg_uid; } void SetUID(const UID& arg_uid) { uid = arg_uid; }
UID GetUID() const { return uid; } UID GetUID() const { return uid; }
std::shared_ptr<EncapsulationStack> GetEncapsulation() const std::shared_ptr<EncapsulationStack> GetEncapsulation() const { return encapsulation; }
{ return encapsulation; }
void CheckFlowLabel(bool is_orig, uint32_t flow_label); void CheckFlowLabel(bool is_orig, uint32_t flow_label);
uint32_t GetOrigFlowLabel() { return orig_flow_label; } uint32_t GetOrigFlowLabel() { return orig_flow_label; }
uint32_t GetRespFlowLabel() { return resp_flow_label; } uint32_t GetRespFlowLabel() { return resp_flow_label; }
bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate, bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration);
double duration);
private: private:
friend class session::detail::Timer; friend class session::detail::Timer;
IPAddr orig_addr; IPAddr orig_addr;
@ -264,9 +268,9 @@ private:
detail::ConnKey key; detail::ConnKey key;
unsigned int weird:1; unsigned int weird : 1;
unsigned int finished:1; unsigned int finished : 1;
unsigned int saw_first_orig_packet:1, saw_first_resp_packet:1; unsigned int saw_first_orig_packet : 1, saw_first_resp_packet : 1;
uint32_t hist_seen; uint32_t hist_seen;
std::string history; std::string history;
@ -280,6 +284,6 @@ private:
// Count number of connections. // Count number of connections.
static uint64_t total_connections; static uint64_t total_connections;
static uint64_t current_connections; static uint64_t current_connections;
}; };
} // namespace zeek } // namespace zeek

View file

@ -1,18 +1,18 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/DFA.h"
#include "zeek/Desc.h"
#include "zeek/EquivClass.h"
#include "zeek/Hash.h"
#include "zeek/zeek-config.h" #include "zeek/zeek-config.h"
#include "zeek/DFA.h" namespace zeek::detail
#include "zeek/EquivClass.h" {
#include "zeek/Desc.h"
#include "zeek/Hash.h"
namespace zeek::detail {
unsigned int DFA_State::transition_counter = 0; unsigned int DFA_State::transition_counter = 0;
DFA_State::DFA_State(int arg_state_num, const EquivClass* ec, DFA_State::DFA_State(int arg_state_num, const EquivClass* ec, NFA_state_list* arg_nfa_states,
NFA_state_list* arg_nfa_states,
AcceptingSet* arg_accept) AcceptingSet* arg_accept)
{ {
state_num = arg_state_num; state_num = arg_state_num;
@ -31,7 +31,7 @@ DFA_State::DFA_State(int arg_state_num, const EquivClass* ec,
DFA_State::~DFA_State() DFA_State::~DFA_State()
{ {
delete [] xtions; delete[] xtions;
delete nfa_states; delete nfa_states;
delete accept; delete accept;
delete meta_ec; delete meta_ec;
@ -241,14 +241,13 @@ void DFA_State::Dump(FILE* f, DFA_Machine* m)
if ( i == sym + 1 ) if ( i == sym + 1 )
sprintf(xbuf, "'%c'", r); sprintf(xbuf, "'%c'", r);
else else
sprintf(xbuf, "'%c'-'%c'", r, m->Rep(i-1)); sprintf(xbuf, "'%c'-'%c'", r, m->Rep(i - 1));
if ( s == DFA_UNCOMPUTED_STATE_PTR ) if ( s == DFA_UNCOMPUTED_STATE_PTR )
fprintf(f, "%stransition on %s to <uncomputed>", fprintf(f, "%stransition on %s to <uncomputed>", ++num_trans == 1 ? "\t" : "\n\t",
++num_trans == 1 ? "\t" : "\n\t", xbuf); xbuf);
else else
fprintf(f, "%stransition on %s to state %d", fprintf(f, "%stransition on %s to state %d", ++num_trans == 1 ? "\t" : "\n\t", xbuf,
++num_trans == 1 ? "\t" : "\n\t", xbuf,
s->StateNum()); s->StateNum());
sym = i - 1; sym = i - 1;
@ -283,11 +282,10 @@ void DFA_State::Stats(unsigned int* computed, unsigned int* uncomputed)
unsigned int DFA_State::Size() unsigned int DFA_State::Size()
{ {
return sizeof(*this) return sizeof(*this) + util::pad_size(sizeof(DFA_State*) * num_sym) +
+ util::pad_size(sizeof(DFA_State*) * num_sym) (accept ? util::pad_size(sizeof(int) * accept->size()) : 0) +
+ (accept ? util::pad_size(sizeof(int) * accept->size()) : 0) (nfa_states ? util::pad_size(sizeof(NFA_State*) * nfa_states->length()) : 0) +
+ (nfa_states ? util::pad_size(sizeof(NFA_State*) * nfa_states->length()) : 0) (meta_ec ? meta_ec->Size() : 0);
+ (meta_ec ? meta_ec->Size() : 0);
} }
DFA_State_Cache::DFA_State_Cache() DFA_State_Cache::DFA_State_Cache()
@ -324,8 +322,7 @@ DFA_State* DFA_State_Cache::Lookup(const NFA_state_list& nfas, DigestStr* digest
{ {
*p++ = '0' + (char)(id % 10); *p++ = '0' + (char)(id % 10);
id /= 10; id /= 10;
} } while ( id > 0 );
while ( id > 0 );
*p++ = '&'; *p++ = '&';
} }
} }
@ -428,15 +425,12 @@ unsigned int DFA_Machine::MemoryAllocation() const
// FIXME: Count *ec? // FIXME: Count *ec?
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return padded_sizeof(*this) return padded_sizeof(*this) + s.mem + padded_sizeof(*start_state) + nfa->MemoryAllocation();
+ s.mem
+ padded_sizeof(*start_state)
+ nfa->MemoryAllocation();
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
bool DFA_Machine::StateSetToDFA_State(NFA_state_list* state_set, bool DFA_Machine::StateSetToDFA_State(NFA_state_list* state_set, DFA_State*& d,
DFA_State*& d, const EquivClass* ec) const EquivClass* ec)
{ {
DigestStr digest; DigestStr digest;
d = dfa_state_cache->Lookup(*state_set, &digest); d = dfa_state_cache->Lookup(*state_set, &digest);
@ -475,4 +469,4 @@ int DFA_Machine::Rep(int sym)
return -1; return -1;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,6 +1,5 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#pragma once #pragma once
#include <assert.h> #include <assert.h>
@ -9,10 +8,11 @@
#include <string> #include <string>
#include "zeek/NFA.h" #include "zeek/NFA.h"
#include "zeek/RE.h" // for typedef AcceptingSet
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/RE.h" // for typedef AcceptingSet
namespace zeek::detail { namespace zeek::detail
{
class DFA_State; class DFA_State;
class DFA_Machine; class DFA_Machine;
@ -20,12 +20,13 @@ class DFA_Machine;
// Transitions to the uncomputed state indicate that we haven't yet // Transitions to the uncomputed state indicate that we haven't yet
// computed the state to go to. // computed the state to go to.
#define DFA_UNCOMPUTED_STATE -2 #define DFA_UNCOMPUTED_STATE -2
#define DFA_UNCOMPUTED_STATE_PTR ((DFA_State*) DFA_UNCOMPUTED_STATE) #define DFA_UNCOMPUTED_STATE_PTR ((DFA_State*)DFA_UNCOMPUTED_STATE)
class DFA_State : public Obj { class DFA_State : public Obj
{
public: public:
DFA_State(int state_num, const EquivClass* ec, DFA_State(int state_num, const EquivClass* ec, NFA_state_list* nfa_states,
NFA_state_list* nfa_states, AcceptingSet* accept); AcceptingSet* accept);
~DFA_State() override; ~DFA_State() override;
int StateNum() const { return state_num; } int StateNum() const { return state_num; }
@ -69,11 +70,12 @@ protected:
DFA_State* mark; DFA_State* mark;
static unsigned int transition_counter; // see Xtion() static unsigned int transition_counter; // see Xtion()
}; };
using DigestStr = std::basic_string<u_char>; using DigestStr = std::basic_string<u_char>;
class DFA_State_Cache { class DFA_State_Cache
{
public: public:
DFA_State_Cache(); DFA_State_Cache();
~DFA_State_Cache(); ~DFA_State_Cache();
@ -86,7 +88,8 @@ public:
int NumEntries() const { return states.size(); } int NumEntries() const { return states.size(); }
struct Stats { struct Stats
{
// Sum of all NFA states // Sum of all NFA states
unsigned int nfa_states; unsigned int nfa_states;
unsigned int dfa_states; unsigned int dfa_states;
@ -105,9 +108,10 @@ private:
// Hash indexed by NFA states (MD5s of them, actually). // Hash indexed by NFA states (MD5s of them, actually).
std::map<DigestStr, DFA_State*> states; std::map<DigestStr, DFA_State*> states;
}; };
class DFA_Machine : public Obj { class DFA_Machine : public Obj
{
public: public:
DFA_Machine(NFA_Machine* n, EquivClass* ec); DFA_Machine(NFA_Machine* n, EquivClass* ec);
~DFA_Machine() override; ~DFA_Machine() override;
@ -123,8 +127,9 @@ public:
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
void Dump(FILE* f); void Dump(FILE* f);
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const; "GHI-572.")]] unsigned int
MemoryAllocation() const;
protected: protected:
friend class DFA_State; // for DFA_State::ComputeXtion friend class DFA_State; // for DFA_State::ComputeXtion
@ -133,8 +138,7 @@ protected:
int state_count; int state_count;
// The state list has to be sorted according to IDs. // The state list has to be sorted according to IDs.
bool StateSetToDFA_State(NFA_state_list* state_set, DFA_State*& d, bool StateSetToDFA_State(NFA_state_list* state_set, DFA_State*& d, const EquivClass* ec);
const EquivClass* ec);
const EquivClass* EC() const { return ec; } const EquivClass* EC() const { return ec; }
EquivClass* ec; // equivalence classes corresponding to NFAs EquivClass* ec; // equivalence classes corresponding to NFAs
@ -142,7 +146,7 @@ protected:
DFA_State_Cache* dfa_state_cache; DFA_State_Cache* dfa_state_cache;
NFA_Machine* nfa; NFA_Machine* nfa;
}; };
inline DFA_State* DFA_State::Xtion(int sym, DFA_Machine* machine) inline DFA_State* DFA_State::Xtion(int sym, DFA_Machine* machine)
{ {
@ -152,4 +156,4 @@ inline DFA_State* DFA_State::Xtion(int sym, DFA_Machine* machine)
return xtions[sym]; return xtions[sym];
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,70 +1,70 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/DNS_Mgr.h" #include "zeek/DNS_Mgr.h"
#include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h>
#include "zeek/zeek-config.h"
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
# include <sys/time.h> #include <sys/time.h>
# include <time.h> #include <time.h>
#else #else
# ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
# include <sys/time.h> #include <sys/time.h>
# else #else
# include <time.h> #include <time.h>
# endif #endif
#endif #endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h> #include <errno.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_MEMORY_H #ifdef HAVE_MEMORY_H
#include <memory.h> #include <memory.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <algorithm> #include <algorithm>
#include "zeek/ZeekString.h"
#include "zeek/Expr.h"
#include "zeek/Event.h" #include "zeek/Event.h"
#include "zeek/Expr.h"
#include "zeek/Hash.h"
#include "zeek/ID.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/NetVar.h"
#include "zeek/Reporter.h"
#include "zeek/RunState.h" #include "zeek/RunState.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/NetVar.h" #include "zeek/ZeekString.h"
#include "zeek/ID.h"
#include "zeek/Reporter.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/iosource/Manager.h" #include "zeek/iosource/Manager.h"
#include "zeek/Hash.h"
extern "C" { extern "C"
extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); {
extern int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
#include <netdb.h> #include <netdb.h>
#include "zeek/nb_dns.h" #include "zeek/nb_dns.h"
} }
using namespace std; using namespace std;
namespace zeek::detail { namespace zeek::detail
{
class DNS_Mgr_Request { class DNS_Mgr_Request
{
public: public:
DNS_Mgr_Request(const char* h, int af, bool is_txt) DNS_Mgr_Request(const char* h, int af, bool is_txt)
: host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr(), : host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr(), request_pending()
request_pending() {
{ } }
DNS_Mgr_Request(const IPAddr& a) DNS_Mgr_Request(const IPAddr& a) : host(), fam(), qtype(), addr(a), request_pending() { }
: host(), fam(), qtype(), addr(a), request_pending()
{ }
~DNS_Mgr_Request() { delete [] host; } ~DNS_Mgr_Request() { delete[] host; }
// Returns nil if this was an address request. // Returns nil if this was an address request.
const char* ReqHost() const { return host; } const char* ReqHost() const { return host; }
@ -75,14 +75,13 @@ public:
int RequestPending() const { return request_pending; } int RequestPending() const { return request_pending; }
void RequestDone() { request_pending = 0; } void RequestDone() { request_pending = 0; }
protected: protected:
char* host; // if non-nil, this is a host request char* host; // if non-nil, this is a host request
int fam; // address family query type for host requests int fam; // address family query type for host requests
int qtype; // Query type int qtype; // Query type
IPAddr addr; IPAddr addr;
int request_pending; int request_pending;
}; };
int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns) int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
{ {
@ -93,17 +92,18 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
char err[NB_DNS_ERRSIZE]; char err[NB_DNS_ERRSIZE];
if ( host ) if ( host )
return nb_dns_host_request2(nb_dns, host, fam, qtype, (void*) this, err) >= 0; return nb_dns_host_request2(nb_dns, host, fam, qtype, (void*)this, err) >= 0;
else else
{ {
const uint32_t* bytes; const uint32_t* bytes;
int len = addr.GetBytes(&bytes); int len = addr.GetBytes(&bytes);
return nb_dns_addr_request2(nb_dns, (char*) bytes, return nb_dns_addr_request2(nb_dns, (char*)bytes, len == 1 ? AF_INET : AF_INET6,
len == 1 ? AF_INET : AF_INET6, (void*) this, err) >= 0; (void*)this, err) >= 0;
} }
} }
class DNS_Mapping { class DNS_Mapping
{
public: public:
DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl); DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl);
DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl); DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl);
@ -117,10 +117,7 @@ public:
// Returns nil if this was an address request. // Returns nil if this was an address request.
const char* ReqHost() const { return req_host; } const char* ReqHost() const { return req_host; }
IPAddr ReqAddr() const { return req_addr; } IPAddr ReqAddr() const { return req_addr; }
string ReqStr() const string ReqStr() const { return req_host ? req_host : req_addr.AsString(); }
{
return req_host ? req_host : req_addr.AsString();
}
ListValPtr Addrs(); ListValPtr Addrs();
TableValPtr AddrsSet(); // addresses returned as a set TableValPtr AddrsSet(); // addresses returned as a set
@ -135,7 +132,7 @@ public:
bool Expired() const bool Expired() const
{ {
if ( req_host && num_addrs == 0) if ( req_host && num_addrs == 0 )
return false; // nothing to expire return false; // nothing to expire
return util::current_time() > (creation_time + req_ttl); return util::current_time() > (creation_time + req_ttl);
@ -166,11 +163,11 @@ protected:
bool no_mapping; // when initializing from a file, immediately hit EOF bool no_mapping; // when initializing from a file, immediately hit EOF
bool init_failed; bool init_failed;
bool failed; bool failed;
}; };
void DNS_Mgr_mapping_delete_func(void* v) void DNS_Mgr_mapping_delete_func(void* v)
{ {
delete (DNS_Mapping*) v; delete (DNS_Mapping*)v;
} }
static TableValPtr empty_addr_set() static TableValPtr empty_addr_set()
@ -217,13 +214,12 @@ DNS_Mapping::DNS_Mapping(FILE* f)
return; return;
} }
char req_buf[512+1], name_buf[512+1]; char req_buf[512 + 1], name_buf[512 + 1];
int is_req_host; int is_req_host;
int failed_local; int failed_local;
if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, &is_req_host, req_buf,
&is_req_host, req_buf, &failed_local, name_buf, &map_type, &num_addrs, &failed_local, name_buf, &map_type, &num_addrs, &req_ttl) != 8 )
&req_ttl) != 8 )
return; return;
failed = static_cast<bool>(failed_local); failed = static_cast<bool>(failed_local);
@ -264,16 +260,16 @@ DNS_Mapping::DNS_Mapping(FILE* f)
DNS_Mapping::~DNS_Mapping() DNS_Mapping::~DNS_Mapping()
{ {
delete [] req_host; delete[] req_host;
if ( names ) if ( names )
{ {
for ( int i = 0; i < num_names; ++i ) for ( int i = 0; i < num_names; ++i )
delete [] names[i]; delete[] names[i];
delete [] names; delete[] names;
} }
delete [] addrs; delete[] addrs;
} }
ListValPtr DNS_Mapping::Addrs() ListValPtr DNS_Mapping::Addrs()
@ -292,7 +288,8 @@ ListValPtr DNS_Mapping::Addrs()
return addrs_val; return addrs_val;
} }
TableValPtr DNS_Mapping::AddrsSet() { TableValPtr DNS_Mapping::AddrsSet()
{
auto l = Addrs(); auto l = Addrs();
if ( ! l ) if ( ! l )
@ -339,11 +336,9 @@ void DNS_Mapping::Init(struct hostent* h)
addrs = new IPAddr[num_addrs]; addrs = new IPAddr[num_addrs];
for ( int i = 0; i < num_addrs; ++i ) for ( int i = 0; i < num_addrs; ++i )
if ( h->h_addrtype == AF_INET ) if ( h->h_addrtype == AF_INET )
addrs[i] = IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], addrs[i] = IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], IPAddr::Network);
IPAddr::Network);
else if ( h->h_addrtype == AF_INET6 ) else if ( h->h_addrtype == AF_INET6 )
addrs[i] = IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], addrs[i] = IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], IPAddr::Network);
IPAddr::Network);
} }
else else
addrs = nullptr; addrs = nullptr;
@ -365,16 +360,14 @@ void DNS_Mapping::Clear()
void DNS_Mapping::Save(FILE* f) const void DNS_Mapping::Save(FILE* f) const
{ {
fprintf(f, "%.0f %d %s %d %s %d %d %" PRIu32"\n", creation_time, req_host != nullptr, fprintf(f, "%.0f %d %s %d %s %d %d %" PRIu32 "\n", creation_time, req_host != nullptr,
req_host ? req_host : req_addr.AsString().c_str(), req_host ? req_host : req_addr.AsString().c_str(), failed,
failed, (names && names[0]) ? names[0] : "*", (names && names[0]) ? names[0] : "*", map_type, num_addrs, req_ttl);
map_type, num_addrs, req_ttl);
for ( int i = 0; i < num_addrs; ++i ) for ( int i = 0; i < num_addrs; ++i )
fprintf(f, "%s\n", addrs[i].AsString().c_str()); fprintf(f, "%s\n", addrs[i].AsString().c_str());
} }
DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode)
{ {
did_init = false; did_init = false;
@ -395,8 +388,8 @@ DNS_Mgr::~DNS_Mgr()
if ( nb_dns ) if ( nb_dns )
nb_dns_finish(nb_dns); nb_dns_finish(nb_dns);
delete [] cache_name; delete[] cache_name;
delete [] dir; delete[] dir;
} }
void DNS_Mgr::InitSource() void DNS_Mgr::InitSource()
@ -480,8 +473,7 @@ static const char* fake_text_lookup_result(const char* name)
static const char* fake_addr_lookup_result(const IPAddr& addr) static const char* fake_addr_lookup_result(const IPAddr& addr)
{ {
static char tmp[128]; static char tmp[128];
snprintf(tmp, sizeof(tmp), "fake_addr_lookup_result_%s", snprintf(tmp, sizeof(tmp), "fake_addr_lookup_result_%s", addr.AsString().c_str());
addr.AsString().c_str());
return tmp; return tmp;
} }
@ -520,7 +512,8 @@ TableValPtr DNS_Mgr::LookupHost(const char* name)
} }
// Not found, or priming. // Not found, or priming.
switch ( mode ) { switch ( mode )
{
case DNS_PRIME: case DNS_PRIME:
requests.push_back(new DNS_Mgr_Request(name, AF_INET, false)); requests.push_back(new DNS_Mgr_Request(name, AF_INET, false));
requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false)); requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false));
@ -565,14 +558,14 @@ ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr)
} }
// Not found, or priming. // Not found, or priming.
switch ( mode ) { switch ( mode )
{
case DNS_PRIME: case DNS_PRIME:
requests.push_back(new DNS_Mgr_Request(addr)); requests.push_back(new DNS_Mgr_Request(addr));
return make_intrusive<StringVal>("<none>"); return make_intrusive<StringVal>("<none>");
case DNS_FORCE: case DNS_FORCE:
reporter->FatalError("can't find DNS entry for %s in cache", reporter->FatalError("can't find DNS entry for %s in cache", addr.AsString().c_str());
addr.AsString().c_str());
return nullptr; return nullptr;
case DNS_DEFAULT: case DNS_DEFAULT:
@ -586,9 +579,7 @@ ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr)
} }
} }
void DNS_Mgr::Verify() void DNS_Mgr::Verify() { }
{
}
#define MAX_PENDING_REQUESTS 20 #define MAX_PENDING_REQUESTS 20
@ -628,8 +619,7 @@ void DNS_Mgr::Resolve()
} }
first_req = last_req + 1; first_req = last_req + 1;
num_pending = min(requests.length() - first_req, num_pending = min(requests.length() - first_req, MAX_PENDING_REQUESTS);
MAX_PENDING_REQUESTS);
last_req = first_req + num_pending - 1; last_req = first_req + num_pending - 1;
for ( i = first_req; i <= last_req; ++i ) for ( i = first_req; i <= last_req; ++i )
@ -642,12 +632,10 @@ void DNS_Mgr::Resolve()
struct nb_dns_result r; struct nb_dns_result r;
status = nb_dns_activity(nb_dns, &r, err); status = nb_dns_activity(nb_dns, &r, err);
if ( status < 0 ) if ( status < 0 )
reporter->Warning( reporter->Warning("NB-DNS error in DNS_Mgr::WaitForReplies (%s)", err);
"NB-DNS error in DNS_Mgr::WaitForReplies (%s)",
err);
else if ( status > 0 ) else if ( status > 0 )
{ {
DNS_Mgr_Request* dr = (DNS_Mgr_Request*) r.cookie; DNS_Mgr_Request* dr = (DNS_Mgr_Request*)r.cookie;
if ( dr->RequestPending() ) if ( dr->RequestPending() )
{ {
AddResult(dr, &r); AddResult(dr, &r);
@ -697,8 +685,7 @@ void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm)
event_mgr.Enqueue(e, BuildMappingVal(dm)); event_mgr.Enqueue(e, BuildMappingVal(dm));
} }
void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2)
ListValPtr l1, ListValPtr l2)
{ {
if ( ! e ) if ( ! e )
return; return;
@ -767,11 +754,9 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r)
HostMap::iterator it = host_mappings.find(dr->ReqHost()); HostMap::iterator it = host_mappings.find(dr->ReqHost());
if ( it == host_mappings.end() ) if ( it == host_mappings.end() )
{ {
host_mappings[dr->ReqHost()].first = host_mappings[dr->ReqHost()].first = new_dm->Type() == AF_INET ? new_dm : nullptr;
new_dm->Type() == AF_INET ? new_dm : nullptr;
host_mappings[dr->ReqHost()].second = host_mappings[dr->ReqHost()].second = new_dm->Type() == AF_INET ? nullptr : new_dm;
new_dm->Type() == AF_INET ? nullptr : new_dm;
} }
else else
{ {
@ -1029,15 +1014,13 @@ const char* DNS_Mgr::LookupTextInCache(const string& name)
return d->names ? d->names[0] : "<\?\?\?>"; return d->names ? d->names[0] : "<\?\?\?>";
} }
static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, TableValPtr result)
TableValPtr result)
{ {
callback->Resolved(result.get()); callback->Resolved(result.get());
delete callback; delete callback;
} }
static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, const char* result)
const char* result)
{ {
callback->Resolved(result); callback->Resolved(result);
delete callback; delete callback;
@ -1184,15 +1167,16 @@ void DNS_Mgr::IssueAsyncRequests()
if ( req->IsAddrReq() ) if ( req->IsAddrReq() )
success = DoRequest(nb_dns, new DNS_Mgr_Request(req->host)); success = DoRequest(nb_dns, new DNS_Mgr_Request(req->host));
else if ( req->is_txt ) else if ( req->is_txt )
success = DoRequest(nb_dns, new DNS_Mgr_Request(req->name.c_str(), success =
AF_INET, req->is_txt)); DoRequest(nb_dns, new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt));
else else
{ {
// If only one request type succeeds, don't consider it a failure. // If only one request type succeeds, don't consider it a failure.
success = DoRequest(nb_dns, new DNS_Mgr_Request(req->name.c_str(), success =
AF_INET, req->is_txt)); DoRequest(nb_dns, new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt));
success = DoRequest(nb_dns, new DNS_Mgr_Request(req->name.c_str(), success =
AF_INET6, req->is_txt)) || success; DoRequest(nb_dns, new DNS_Mgr_Request(req->name.c_str(), AF_INET6, req->is_txt)) ||
success;
} }
if ( ! success ) if ( ! success )
@ -1241,7 +1225,6 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout)
// Don't delete the request. That will be done once it // Don't delete the request. That will be done once it
// eventually times out. // eventually times out.
} }
} }
void DNS_Mgr::CheckAsyncTextRequest(const char* host, bool timeout) void DNS_Mgr::CheckAsyncTextRequest(const char* host, bool timeout)
@ -1378,11 +1361,10 @@ void DNS_Mgr::Process()
else if ( status > 0 ) else if ( status > 0 )
{ {
DNS_Mgr_Request* dr = (DNS_Mgr_Request*) r.cookie; DNS_Mgr_Request* dr = (DNS_Mgr_Request*)r.cookie;
bool do_host_timeout = true; bool do_host_timeout = true;
if ( dr->ReqHost() && if ( dr->ReqHost() && host_mappings.find(dr->ReqHost()) == host_mappings.end() )
host_mappings.find(dr->ReqHost()) == host_mappings.end() )
// Don't timeout when this is the first result in an expected pair // Don't timeout when this is the first result in an expected pair
// (one result each for A and AAAA queries). // (one result each for A and AAAA queries).
do_host_timeout = false; do_host_timeout = false;
@ -1427,7 +1409,7 @@ int DNS_Mgr::AnswerAvailable(int timeout)
t.tv_sec = timeout; t.tv_sec = timeout;
t.tv_usec = 0; t.tv_usec = 0;
int status = select(fd+1, &read_fds, 0, 0, &t); int status = select(fd + 1, &read_fds, 0, 0, &t);
if ( status < 0 ) if ( status < 0 )
{ {
@ -1463,4 +1445,4 @@ void DNS_Mgr::Terminate()
iosource_mgr->UnregisterFd(nb_dns_fd(nb_dns), this); iosource_mgr->UnregisterFd(nb_dns_fd(nb_dns), this);
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,4 +1,4 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#pragma once #pragma once
@ -7,13 +7,14 @@
#include <queue> #include <queue>
#include <utility> #include <utility>
#include "zeek/List.h"
#include "zeek/EventHandler.h" #include "zeek/EventHandler.h"
#include "zeek/iosource/IOSource.h"
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/List.h"
#include "zeek/iosource/IOSource.h"
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek { namespace zeek
{
class EventHandler; class EventHandler;
class RecordType; class RecordType;
@ -26,30 +27,33 @@ using ValPtr = IntrusivePtr<Val>;
using ListValPtr = IntrusivePtr<ListVal>; using ListValPtr = IntrusivePtr<ListVal>;
using TableValPtr = IntrusivePtr<TableVal>; using TableValPtr = IntrusivePtr<TableVal>;
} // namespace zeek } // namespace zeek
// Defined in nb_dns.h // Defined in nb_dns.h
struct nb_dns_info; struct nb_dns_info;
struct nb_dns_result; struct nb_dns_result;
namespace zeek::detail { namespace zeek::detail
{
class DNS_Mgr_Request; class DNS_Mgr_Request;
using DNS_mgr_request_list = PList<DNS_Mgr_Request>; using DNS_mgr_request_list = PList<DNS_Mgr_Request>;
class DNS_Mapping; class DNS_Mapping;
enum DNS_MgrMode { enum DNS_MgrMode
{
DNS_PRIME, // used to prime the cache DNS_PRIME, // used to prime the cache
DNS_FORCE, // internal error if cache miss DNS_FORCE, // internal error if cache miss
DNS_DEFAULT, // lookup names as they're requested DNS_DEFAULT, // lookup names as they're requested
DNS_FAKE, // don't look up names, just return dummy results DNS_FAKE, // don't look up names, just return dummy results
}; };
// Number of seconds we'll wait for a reply. // Number of seconds we'll wait for a reply.
#define DNS_TIMEOUT 5 #define DNS_TIMEOUT 5
class DNS_Mgr final : public iosource::IOSource { class DNS_Mgr final : public iosource::IOSource
{
public: public:
explicit DNS_Mgr(DNS_MgrMode mode); explicit DNS_Mgr(DNS_MgrMode mode);
~DNS_Mgr() override; ~DNS_Mgr() override;
@ -75,13 +79,14 @@ public:
const char* LookupTextInCache(const std::string& name); const char* LookupTextInCache(const std::string& name);
// Support for async lookups. // Support for async lookups.
class LookupCallback { class LookupCallback
{
public: public:
LookupCallback() { } LookupCallback() { }
virtual ~LookupCallback() { } virtual ~LookupCallback() { }
virtual void Resolved(const char* name) { }; virtual void Resolved(const char* name){};
virtual void Resolved(TableVal* addrs) { }; virtual void Resolved(TableVal* addrs){};
virtual void Timeout() = 0; virtual void Timeout() = 0;
}; };
@ -89,7 +94,8 @@ public:
void AsyncLookupName(const std::string& name, LookupCallback* callback); void AsyncLookupName(const std::string& name, LookupCallback* callback);
void AsyncLookupNameText(const std::string& name, LookupCallback* callback); void AsyncLookupNameText(const std::string& name, LookupCallback* callback);
struct Stats { struct Stats
{
unsigned long requests; // These count only async requests. unsigned long requests; // These count only async requests.
unsigned long successful; unsigned long successful;
unsigned long failed; unsigned long failed;
@ -108,8 +114,7 @@ protected:
friend class DNS_Mgr_Request; friend class DNS_Mgr_Request;
void Event(EventHandlerPtr e, DNS_Mapping* dm); void Event(EventHandlerPtr e, DNS_Mapping* dm);
void Event(EventHandlerPtr e, DNS_Mapping* dm, void Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2);
ListValPtr l1, ListValPtr l2);
void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm); void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm);
ValPtr BuildMappingVal(DNS_Mapping* dm); ValPtr BuildMappingVal(DNS_Mapping* dm);
@ -119,7 +124,7 @@ protected:
ListValPtr AddrListDelta(ListVal* al1, ListVal* al2); ListValPtr AddrListDelta(ListVal* al1, ListVal* al2);
void DumpAddrList(FILE* f, ListVal* al); void DumpAddrList(FILE* f, ListVal* al);
typedef std::map<std::string, std::pair<DNS_Mapping*, DNS_Mapping*> > HostMap; typedef std::map<std::string, std::pair<DNS_Mapping*, DNS_Mapping*>> HostMap;
typedef std::map<IPAddr, DNS_Mapping*> AddrMap; typedef std::map<IPAddr, DNS_Mapping*> AddrMap;
typedef std::map<std::string, DNS_Mapping*> TextMap; typedef std::map<std::string, DNS_Mapping*> TextMap;
void LoadCache(FILE* f); void LoadCache(FILE* f);
@ -165,7 +170,8 @@ protected:
typedef std::list<LookupCallback*> CallbackList; typedef std::list<LookupCallback*> CallbackList;
struct AsyncRequest { struct AsyncRequest
{
double time; double time;
IPAddr host; IPAddr host;
std::string name; std::string name;
@ -179,8 +185,7 @@ protected:
void Resolved(const char* name) void Resolved(const char* name)
{ {
for ( CallbackList::iterator i = callbacks.begin(); for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i )
i != callbacks.end(); ++i )
{ {
(*i)->Resolved(name); (*i)->Resolved(name);
delete *i; delete *i;
@ -191,8 +196,7 @@ protected:
void Resolved(TableVal* addrs) void Resolved(TableVal* addrs)
{ {
for ( CallbackList::iterator i = callbacks.begin(); for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i )
i != callbacks.end(); ++i )
{ {
(*i)->Resolved(addrs); (*i)->Resolved(addrs);
delete *i; delete *i;
@ -203,8 +207,7 @@ protected:
void Timeout() void Timeout()
{ {
for ( CallbackList::iterator i = callbacks.begin(); for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i )
i != callbacks.end(); ++i )
{ {
(*i)->Timeout(); (*i)->Timeout();
delete *i; delete *i;
@ -212,7 +215,6 @@ protected:
callbacks.clear(); callbacks.clear();
processed = true; processed = true;
} }
}; };
typedef std::map<IPAddr, AsyncRequest*> AsyncRequestAddrMap; typedef std::map<IPAddr, AsyncRequest*> AsyncRequestAddrMap;
@ -227,21 +229,20 @@ protected:
typedef std::list<AsyncRequest*> QueuedList; typedef std::list<AsyncRequest*> QueuedList;
QueuedList asyncs_queued; QueuedList asyncs_queued;
struct AsyncRequestCompare { struct AsyncRequestCompare
bool operator()(const AsyncRequest* a, const AsyncRequest* b)
{ {
return a->time > b->time; bool operator()(const AsyncRequest* a, const AsyncRequest* b) { return a->time > b->time; }
}
}; };
typedef std::priority_queue<AsyncRequest*, std::vector<AsyncRequest*>, AsyncRequestCompare> TimeoutQueue; typedef std::priority_queue<AsyncRequest*, std::vector<AsyncRequest*>, AsyncRequestCompare>
TimeoutQueue;
TimeoutQueue asyncs_timeouts; TimeoutQueue asyncs_timeouts;
unsigned long num_requests; unsigned long num_requests;
unsigned long successful; unsigned long successful;
unsigned long failed; unsigned long failed;
}; };
extern DNS_Mgr* dns_mgr; extern DNS_Mgr* dns_mgr;
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,37 +1,39 @@
// Implementation of breakpoints. // Implementation of breakpoints.
#include "zeek/zeek-config.h"
#include "zeek/DbgBreakpoint.h" #include "zeek/DbgBreakpoint.h"
#include <assert.h> #include <assert.h>
#include "zeek/Desc.h"
#include "zeek/ID.h"
#include "zeek/Debug.h" #include "zeek/Debug.h"
#include "zeek/Scope.h" #include "zeek/Desc.h"
#include "zeek/Frame.h" #include "zeek/Frame.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/Val.h" #include "zeek/ID.h"
#include "zeek/Reporter.h"
#include "zeek/Scope.h"
#include "zeek/Stmt.h" #include "zeek/Stmt.h"
#include "zeek/Timer.h" #include "zeek/Timer.h"
#include "zeek/Reporter.h" #include "zeek/Val.h"
#include "zeek/module_util.h" #include "zeek/module_util.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
// BreakpointTimer used for time-based breakpoints // BreakpointTimer used for time-based breakpoints
class BreakpointTimer final : public Timer { class BreakpointTimer final : public Timer
{
public: public:
BreakpointTimer(DbgBreakpoint* arg_bp, double arg_t) BreakpointTimer(DbgBreakpoint* arg_bp, double arg_t) : Timer(arg_t, TIMER_BREAKPOINT)
: Timer(arg_t, TIMER_BREAKPOINT) {
{ bp = arg_bp; } bp = arg_bp;
}
void Dispatch(double t, bool is_expire) override; void Dispatch(double t, bool is_expire) override;
protected: protected:
DbgBreakpoint* bp; DbgBreakpoint* bp;
}; };
void BreakpointTimer::Dispatch(double t, bool is_expire) void BreakpointTimer::Dispatch(double t, bool is_expire)
{ {
@ -41,7 +43,6 @@ void BreakpointTimer::Dispatch(double t, bool is_expire)
bp->ShouldBreak(t); bp->ShouldBreak(t);
} }
DbgBreakpoint::DbgBreakpoint() DbgBreakpoint::DbgBreakpoint()
{ {
kind = BP_STMT; kind = BP_STMT;
@ -119,7 +120,6 @@ void DbgBreakpoint::RemoveFromStmt()
at_stmt->DecrBPCount(); at_stmt->DecrBPCount();
} }
bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str) bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str)
{ {
if ( plr.type == PLR_UNKNOWN ) if ( plr.type == PLR_UNKNOWN )
@ -141,8 +141,7 @@ bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str)
} }
at_stmt = plr.stmt; at_stmt = plr.stmt;
snprintf(description, sizeof(description), "%s:%d", snprintf(description, sizeof(description), "%s:%d", source_filename, source_line);
source_filename, source_line);
debug_msg("Breakpoint %d set at %s\n", GetID(), Description()); debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
} }
@ -151,12 +150,11 @@ bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str)
{ {
std::string loc_s(loc_str); std::string loc_s(loc_str);
kind = BP_FUNC; kind = BP_FUNC;
function_name = make_full_var_name(current_module.c_str(), function_name = make_full_var_name(current_module.c_str(), loc_s.c_str());
loc_s.c_str());
at_stmt = plr.stmt; at_stmt = plr.stmt;
const Location* loc = at_stmt->GetLocationInfo(); const Location* loc = at_stmt->GetLocationInfo();
snprintf(description, sizeof(description), "%s at %s:%d", snprintf(description, sizeof(description), "%s at %s:%d", function_name.c_str(),
function_name.c_str(), loc->filename, loc->last_line); loc->filename, loc->last_line);
debug_msg("Breakpoint %d set at %s\n", GetID(), Description()); debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
} }
@ -178,8 +176,7 @@ bool DbgBreakpoint::SetLocation(Stmt* stmt)
AddToGlobalMap(); AddToGlobalMap();
const Location* loc = stmt->GetLocationInfo(); const Location* loc = stmt->GetLocationInfo();
snprintf(description, sizeof(description), "%s:%d", snprintf(description, sizeof(description), "%s:%d", loc->filename, loc->last_line);
loc->filename, loc->last_line);
debug_msg("Breakpoint %d set at %s\n", GetID(), Description()); debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
@ -204,7 +201,8 @@ bool DbgBreakpoint::Reset()
{ {
ParseLocationRec plr; ParseLocationRec plr;
switch ( kind ) { switch ( kind )
{
case BP_TIME: case BP_TIME:
debug_msg("Time-based breakpoints not yet supported.\n"); debug_msg("Time-based breakpoints not yet supported.\n");
break; break;
@ -258,8 +256,7 @@ BreakCode DbgBreakpoint::HasHit()
return BC_HIT; return BC_HIT;
} }
if ( ! IsIntegral(yes->GetType()->Tag()) && if ( ! IsIntegral(yes->GetType()->Tag()) && ! IsBool(yes->GetType()->Tag()) )
! IsBool(yes->GetType()->Tag()) )
{ {
PrintHitMsg(); PrintHitMsg();
debug_msg("Breakpoint condition should return an integral type"); debug_msg("Breakpoint condition should return an integral type");
@ -295,7 +292,8 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
if ( ! IsEnabled() ) if ( ! IsEnabled() )
return BC_NO_HIT; return BC_NO_HIT;
switch ( kind ) { switch ( kind )
{
case BP_STMT: case BP_STMT:
case BP_FUNC: case BP_FUNC:
if ( at_stmt != s ) if ( at_stmt != s )
@ -324,7 +322,6 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
return code; return code;
} }
BreakCode DbgBreakpoint::ShouldBreak(double t) BreakCode DbgBreakpoint::ShouldBreak(double t)
{ {
if ( kind != BP_TIME ) if ( kind != BP_TIME )
@ -345,7 +342,8 @@ BreakCode DbgBreakpoint::ShouldBreak(double t)
void DbgBreakpoint::PrintHitMsg() void DbgBreakpoint::PrintHitMsg()
{ {
switch ( kind ) { switch ( kind )
{
case BP_STMT: case BP_STMT:
case BP_FUNC: case BP_FUNC:
case BP_LINE: case BP_LINE:
@ -355,13 +353,12 @@ void DbgBreakpoint::PrintHitMsg()
const ScriptFunc* func = f->GetFunction(); const ScriptFunc* func = f->GetFunction();
if ( func ) if ( func )
func->DescribeDebug (&d, f->GetFuncArgs()); func->DescribeDebug(&d, f->GetFuncArgs());
const Location* loc = at_stmt->GetLocationInfo(); const Location* loc = at_stmt->GetLocationInfo();
debug_msg("Breakpoint %d, %s at %s:%d\n", debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->filename,
GetID(), d.Description(), loc->first_line);
loc->filename, loc->first_line);
} }
return; return;
@ -373,4 +370,4 @@ void DbgBreakpoint::PrintHitMsg()
} }
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -3,16 +3,30 @@
#pragma once #pragma once
#include <string> #include <string>
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek::detail { namespace zeek::detail
{
class Stmt; class Stmt;
class ParseLocationRec; class ParseLocationRec;
enum BreakCode { BC_NO_HIT, BC_HIT, BC_HIT_AND_DELETE }; enum BreakCode
class DbgBreakpoint { {
enum Kind { BP_STMT = 0, BP_FUNC, BP_LINE, BP_TIME }; BC_NO_HIT,
BC_HIT,
BC_HIT_AND_DELETE
};
class DbgBreakpoint
{
enum Kind
{
BP_STMT = 0,
BP_FUNC,
BP_LINE,
BP_TIME
};
public: public:
DbgBreakpoint(); DbgBreakpoint();
@ -51,7 +65,7 @@ public:
bool SetEnable(bool do_enable); bool SetEnable(bool do_enable);
// e.g. "FooBar() at foo.c:23" // e.g. "FooBar() at foo.c:23"
const char * Description() const { return description; } const char* Description() const { return description; }
protected: protected:
void AddToGlobalMap(); void AddToGlobalMap();
@ -81,6 +95,6 @@ protected:
int32_t hit_count; // how many times it's been hit (w/o breaking) int32_t hit_count; // how many times it's been hit (w/o breaking)
std::string condition; // condition to evaluate; nil for none std::string condition; // condition to evaluate; nil for none
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,12 +2,14 @@
#pragma once #pragma once
namespace zeek::detail { namespace zeek::detail
{
class Expr; class Expr;
// Automatic displays: display these at each stoppage. // Automatic displays: display these at each stoppage.
class DbgDisplay { class DbgDisplay
{
public: public:
DbgDisplay(Expr* expr_to_display); DbgDisplay(Expr* expr_to_display);
@ -26,4 +28,4 @@ protected:
Expr* expression; Expr* expression;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,5 +1,4 @@
// Bro Debugger Help // Bro Debugger Help
#include "zeek/zeek-config.h"
#include "zeek/Debug.h" #include "zeek/Debug.h"
#include "zeek/zeek-config.h"

View file

@ -1,12 +1,13 @@
// Implementation of watches // Implementation of watches
#include "zeek/zeek-config.h"
#include "zeek/DbgWatch.h" #include "zeek/DbgWatch.h"
#include "zeek/Debug.h" #include "zeek/Debug.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
// Support classes // Support classes
DbgWatch::DbgWatch(zeek::Obj* var_to_watch) DbgWatch::DbgWatch(zeek::Obj* var_to_watch)
@ -19,4 +20,4 @@ DbgWatch::DbgWatch(Expr* expr_to_watch)
reporter->InternalError("DbgWatch unimplemented"); reporter->InternalError("DbgWatch unimplemented");
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -4,13 +4,18 @@
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek { class Obj; } namespace zeek
{
class Obj;
}
namespace zeek::detail { namespace zeek::detail
{
class Expr; class Expr;
class DbgWatch { class DbgWatch
{
public: public:
explicit DbgWatch(Obj* var_to_watch); explicit DbgWatch(Obj* var_to_watch);
explicit DbgWatch(Expr* expr_to_watch); explicit DbgWatch(Expr* expr_to_watch);
@ -19,6 +24,6 @@ public:
protected: protected:
Obj* var; Obj* var;
Expr* expr; Expr* expr;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,42 +1,41 @@
// Debugging support for Bro policy files. // Debugging support for Bro policy files.
#include "zeek/zeek-config.h"
#include "zeek/Debug.h" #include "zeek/Debug.h"
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <ctype.h> #include <ctype.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string> #include <string>
#include "zeek/zeek-config.h"
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
#include <readline/readline.h>
#endif #endif
#include "zeek/util.h"
#include "zeek/DebugCmds.h"
#include "zeek/DbgBreakpoint.h" #include "zeek/DbgBreakpoint.h"
#include "zeek/ID.h" #include "zeek/DebugCmds.h"
#include "zeek/IntrusivePtr.h" #include "zeek/Desc.h"
#include "zeek/Expr.h" #include "zeek/Expr.h"
#include "zeek/Stmt.h"
#include "zeek/Frame.h" #include "zeek/Frame.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/ID.h"
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
#include "zeek/Scope.h"
#include "zeek/PolicyFile.h" #include "zeek/PolicyFile.h"
#include "zeek/Desc.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/Scope.h"
#include "zeek/Stmt.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/module_util.h"
#include "zeek/input.h" #include "zeek/input.h"
#include "zeek/module_util.h"
#include "zeek/util.h"
extern "C" { extern "C"
{
#include "zeek/setsignal.h" #include "zeek/setsignal.h"
} }
using namespace std; using namespace std;
@ -67,7 +66,8 @@ extern YYLTYPE yylloc; // holds start line and column of token
extern int line_number; extern int line_number;
extern const char* filename; extern const char* filename;
namespace zeek::detail { namespace zeek::detail
{
DebuggerState::DebuggerState() DebuggerState::DebuggerState()
{ {
@ -92,11 +92,9 @@ bool StmtLocMapping::StartsAfter(const StmtLocMapping* m2)
reporter->InternalError("Assertion failed: m2 != 0"); reporter->InternalError("Assertion failed: m2 != 0");
return loc.first_line > m2->loc.first_line || return loc.first_line > m2->loc.first_line ||
(loc.first_line == m2->loc.first_line && (loc.first_line == m2->loc.first_line && loc.first_column > m2->loc.first_column);
loc.first_column > m2->loc.first_column);
} }
// Generic debug message output. // Generic debug message output.
int debug_msg(const char* fmt, ...) int debug_msg(const char* fmt, ...)
{ {
@ -110,7 +108,6 @@ int debug_msg(const char* fmt, ...)
return retval; return retval;
} }
// Trace message output // Trace message output
FILE* TraceState::SetTraceFile(const char* trace_filename) FILE* TraceState::SetTraceFile(const char* trace_filename)
@ -195,7 +192,6 @@ int TraceState::LogTrace(const char* fmt, ...)
return retval; return retval;
} }
// Helper functions. // Helper functions.
void get_first_statement(Stmt* list, Stmt*& first, Location& loc) void get_first_statement(Stmt* list, Stmt*& first, Location& loc)
{ {
@ -217,8 +213,8 @@ void get_first_statement(Stmt* list, Stmt*& first, Location& loc)
loc = *first->GetLocationInfo(); loc = *first->GetLocationInfo();
} }
static void parse_function_name(vector<ParseLocationRec>& result, static void parse_function_name(vector<ParseLocationRec>& result, ParseLocationRec& plr,
ParseLocationRec& plr, const string& s) const string& s)
{ // function name { // function name
const auto& id = lookup_ID(s.c_str(), current_module.c_str()); const auto& id = lookup_ID(s.c_str(), current_module.c_str());
@ -269,7 +265,7 @@ static void parse_function_name(vector<ParseLocationRec>& result,
Stmt* first; Stmt* first;
Location stmt_loc; Location stmt_loc;
get_first_statement(bodies[i].stmts.get(), first, stmt_loc); get_first_statement(bodies[i].stmts.get(), first, stmt_loc);
debug_msg("[%d] %s:%d\n", i+1, stmt_loc.filename, stmt_loc.first_line); debug_msg("[%d] %s:%d\n", i + 1, stmt_loc.filename, stmt_loc.first_line);
} }
debug_msg("[a] All of the above\n"); debug_msg("[a] All of the above\n");
@ -298,7 +294,7 @@ static void parse_function_name(vector<ParseLocationRec>& result,
} }
int option = atoi(input.c_str()); int option = atoi(input.c_str());
if ( option > 0 && option <= (int) bodies.size() ) if ( option > 0 && option <= (int)bodies.size() )
{ {
body = bodies[option - 1].stmts.get(); body = bodies[option - 1].stmts.get();
break; break;
@ -411,8 +407,7 @@ vector<ParseLocationRec> parse_location_string(const string& s)
if ( entry->Loc().first_line > plr.line ) if ( entry->Loc().first_line > plr.line )
break; break;
if ( plr.line >= entry->Loc().first_line && if ( plr.line >= entry->Loc().first_line && plr.line <= entry->Loc().last_line )
plr.line <= entry->Loc().last_line )
{ {
hit = entry; hit = entry;
break; break;
@ -428,7 +423,6 @@ vector<ParseLocationRec> parse_location_string(const string& s)
return result; return result;
} }
// Interactive debugging console. // Interactive debugging console.
static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args); static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args);
@ -486,7 +480,6 @@ int dbg_shutdown_debugger()
return 1; return 1;
} }
// Umesh: I stole this code from libedit; I modified it here to use // Umesh: I stole this code from libedit; I modified it here to use
// <string>s to avoid memory management problems. The main command is returned // <string>s to avoid memory management problems. The main command is returned
// by the operation argument; the additional arguments are put in the // by the operation argument; the additional arguments are put in the
@ -501,9 +494,9 @@ void tokenize(const char* cstr, string& operation, vector<string>& arguments)
char delim = '\0'; char delim = '\0';
const string str(cstr); const string str(cstr);
for ( int i = 0; i < (signed int) str.length(); ++i ) for ( int i = 0; i < (signed int)str.length(); ++i )
{ {
while ( isspace((unsigned char) str[i]) ) while ( isspace((unsigned char)str[i]) )
++i; ++i;
int start = i; int start = i;
@ -512,7 +505,7 @@ void tokenize(const char* cstr, string& operation, vector<string>& arguments)
{ {
if ( str[i] == '\\' ) if ( str[i] == '\\' )
{ {
if ( i < (signed int) str.length() ) if ( i < (signed int)str.length() )
++i; ++i;
} }
@ -544,7 +537,6 @@ void tokenize(const char* cstr, string& operation, vector<string>& arguments)
} }
} }
// Given a command string, parse it and send the command to be dispatched. // Given a command string, parse it and send the command to be dispatched.
int dbg_execute_command(const char* cmd) int dbg_execute_command(const char* cmd)
{ {
@ -563,8 +555,7 @@ int dbg_execute_command(const char* cmd)
if ( ! entry ) if ( ! entry )
return 0; return 0;
const DebugCmdInfo* info = const DebugCmdInfo* info = (const DebugCmdInfo*)entry->data;
(const DebugCmdInfo*) entry->data;
if ( info && info->Repeatable() ) if ( info && info->Repeatable() )
{ {
@ -585,7 +576,7 @@ int dbg_execute_command(const char* cmd)
vector<string> arguments; vector<string> arguments;
tokenize(localcmd, opstring, arguments); tokenize(localcmd, opstring, arguments);
delete [] localcmd; delete[] localcmd;
// Make sure we know this op name. // Make sure we know this op name.
auto matching_cmds_buf = std::make_unique<const char*[]>(num_debug_cmds()); auto matching_cmds_buf = std::make_unique<const char*[]>(num_debug_cmds());
@ -614,7 +605,7 @@ int dbg_execute_command(const char* cmd)
for ( int i = 0; i < num_debug_cmds(); ++i ) for ( int i = 0; i < num_debug_cmds(); ++i )
if ( matching_cmds[i] ) if ( matching_cmds[i] )
{ {
cmd_code = (DebugCmd) i; cmd_code = (DebugCmd)i;
break; break;
} }
@ -628,9 +619,9 @@ int dbg_execute_command(const char* cmd)
* http://tiswww.case.edu/php/chet/readline/history.html * http://tiswww.case.edu/php/chet/readline/history.html
* suggests that it's safe to assume it's really const char*. * suggests that it's safe to assume it's really const char*.
*/ */
add_history((char *) cmd); add_history((char*)cmd);
HISTORY_STATE* state = history_get_history_state(); HISTORY_STATE* state = history_get_history_state();
state->entries[state->length-1]->data = (histdata_t *) get_debug_cmd_info(cmd_code); state->entries[state->length - 1]->data = (histdata_t*)get_debug_cmd_info(cmd_code);
} }
#endif #endif
@ -655,7 +646,8 @@ int dbg_execute_command(const char* cmd)
// Call the appropriate function for the command. // Call the appropriate function for the command.
static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args) static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args)
{ {
switch ( cmd_code ) { switch ( cmd_code )
{
case dcHelp: case dcHelp:
dbg_cmd_help(cmd_code, args); dbg_cmd_help(cmd_code, args);
break; break;
@ -772,11 +764,10 @@ string get_context_description(const Stmt* stmt, const Frame* frame)
size_t buf_size = strlen(d.Description()) + strlen(loc.filename) + 1024; size_t buf_size = strlen(d.Description()) + strlen(loc.filename) + 1024;
char* buf = new char[buf_size]; char* buf = new char[buf_size];
snprintf(buf, buf_size, "In %s at %s:%d", snprintf(buf, buf_size, "In %s at %s:%d", d.Description(), loc.filename, loc.last_line);
d.Description(), loc.filename, loc.last_line);
string retval(buf); string retval(buf);
delete [] buf; delete[] buf;
return retval; return retval;
} }
@ -807,15 +798,13 @@ int dbg_handle_debug_input()
if ( ! step_or_next_pending || g_frame_stack.back() != last_frame ) if ( ! step_or_next_pending || g_frame_stack.back() != last_frame )
{ {
string context = string context = get_context_description(stmt, g_frame_stack.back());
get_context_description(stmt, g_frame_stack.back());
debug_msg("%s\n", context.c_str()); debug_msg("%s\n", context.c_str());
} }
step_or_next_pending = false; step_or_next_pending = false;
PrintLines(loc.filename, loc.first_line, PrintLines(loc.filename, loc.first_line, loc.last_line - loc.first_line + 1, true);
loc.last_line - loc.first_line + 1, true);
g_debugger_state.last_loc = loc; g_debugger_state.last_loc = loc;
do do
@ -825,11 +814,11 @@ int dbg_handle_debug_input()
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
input_line = readline(get_prompt()); input_line = readline(get_prompt());
#else #else
printf ("%s", get_prompt()); printf("%s", get_prompt());
// readline uses malloc, and we want to be consistent // readline uses malloc, and we want to be consistent
// with it. // with it.
input_line = (char*) util::safe_malloc(1024); input_line = (char*)util::safe_malloc(1024);
input_line[1023] = 0; input_line[1023] = 0;
// ### Maybe it's not always stdin. // ### Maybe it's not always stdin.
input_line = fgets(input_line, 1023, stdin); input_line = fgets(input_line, 1023, stdin);
@ -848,8 +837,7 @@ int dbg_handle_debug_input()
} }
else else
exit(0); exit(0);
} } while ( status == 0 );
while ( status == 0 );
// Clear out some state. ### Is there a better place? // Clear out some state. ### Is there a better place?
g_debugger_state.curr_frame_idx = 0; g_debugger_state.curr_frame_idx = 0;
@ -861,12 +849,10 @@ int dbg_handle_debug_input()
return 0; return 0;
} }
// Return true to continue execution, false to abort. // Return true to continue execution, false to abort.
bool pre_execute_stmt(Stmt* stmt, Frame* f) bool pre_execute_stmt(Stmt* stmt, Frame* f)
{ {
if ( ! g_policy_debug || if ( ! g_policy_debug || stmt->Tag() == STMT_LIST || stmt->Tag() == STMT_NULL )
stmt->Tag() == STMT_LIST || stmt->Tag() == STMT_NULL )
return true; return true;
if ( g_trace_state.DoTrace() ) if ( g_trace_state.DoTrace() )
@ -888,8 +874,7 @@ bool pre_execute_stmt(Stmt* stmt, Frame* f)
bool should_break = false; bool should_break = false;
if ( g_debugger_state.BreakBeforeNextStmt() || if ( g_debugger_state.BreakBeforeNextStmt() || f->BreakBeforeNextStmt() )
f->BreakBeforeNextStmt() )
{ {
if ( g_debugger_state.BreakBeforeNextStmt() ) if ( g_debugger_state.BreakBeforeNextStmt() )
g_debugger_state.BreakBeforeNextStmt(false); g_debugger_state.BreakBeforeNextStmt(false);
@ -960,11 +945,11 @@ ValPtr dbg_eval_expr(const char* expr)
// Push the current frame's associated scope. // Push the current frame's associated scope.
// Note: g_debugger_state.curr_frame_idx is the user-visible number, // Note: g_debugger_state.curr_frame_idx is the user-visible number,
// while the array index goes in the opposite direction // while the array index goes in the opposite direction
int frame_idx = int frame_idx = (g_frame_stack.size() - 1) - g_debugger_state.curr_frame_idx;
(g_frame_stack.size() - 1) - g_debugger_state.curr_frame_idx;
if ( ! (frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size()) ) if ( ! (frame_idx >= 0 && (unsigned)frame_idx < g_frame_stack.size()) )
reporter->InternalError("Assertion failed: frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size()"); reporter->InternalError(
"Assertion failed: frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size()");
Frame* frame = g_frame_stack[frame_idx]; Frame* frame = g_frame_stack[frame_idx];
if ( ! (frame) ) if ( ! (frame) )
@ -1009,11 +994,11 @@ ValPtr dbg_eval_expr(const char* expr)
delete g_curr_debug_expr; delete g_curr_debug_expr;
g_curr_debug_expr = nullptr; g_curr_debug_expr = nullptr;
delete [] g_curr_debug_error; delete[] g_curr_debug_error;
g_curr_debug_error = nullptr; g_curr_debug_error = nullptr;
in_debug = false; in_debug = false;
return result; return result;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,16 +2,17 @@
#pragma once #pragma once
#include <vector> #include <deque>
#include <map> #include <map>
#include <string> #include <string>
#include <deque> #include <vector>
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/StmtEnums.h" #include "zeek/StmtEnums.h"
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek { namespace zeek
{
class Val; class Val;
template <class T> class IntrusivePtr; template <class T> class IntrusivePtr;
@ -19,7 +20,8 @@ using ValPtr = zeek::IntrusivePtr<Val>;
extern std::string current_module; extern std::string current_module;
namespace detail { namespace detail
{
class Frame; class Frame;
class Stmt; class Stmt;
@ -28,14 +30,20 @@ class DbgWatch;
class DbgDisplay; class DbgDisplay;
// This needs to be defined before we do the includes that come after it. // This needs to be defined before we do the includes that come after it.
enum ParseLocationRecType { PLR_UNKNOWN, PLR_FILE_AND_LINE, PLR_FUNCTION }; enum ParseLocationRecType
class ParseLocationRec { {
PLR_UNKNOWN,
PLR_FILE_AND_LINE,
PLR_FUNCTION
};
class ParseLocationRec
{
public: public:
ParseLocationRecType type; ParseLocationRecType type;
int32_t line; int32_t line;
Stmt* stmt; Stmt* stmt;
const char* filename; const char* filename;
}; };
class StmtLocMapping; class StmtLocMapping;
using Filemap = std::deque<StmtLocMapping*>; // mapping for a single file using Filemap = std::deque<StmtLocMapping*>; // mapping for a single file
@ -43,9 +51,14 @@ using Filemap = std::deque<StmtLocMapping*>; // mapping for a single file
using BPIDMapType = std::map<int, DbgBreakpoint*>; using BPIDMapType = std::map<int, DbgBreakpoint*>;
using BPMapType = std::multimap<const Stmt*, DbgBreakpoint*>; using BPMapType = std::multimap<const Stmt*, DbgBreakpoint*>;
class TraceState { class TraceState
{
public: public:
TraceState() { dbgtrace = false; trace_file = stderr; } TraceState()
{
dbgtrace = false;
trace_file = stderr;
}
// Returns previous filename. // Returns previous filename.
FILE* SetTraceFile(const char* trace_filename); FILE* SetTraceFile(const char* trace_filename);
@ -54,16 +67,18 @@ public:
void TraceOn(); void TraceOn();
void TraceOff(); void TraceOff();
int LogTrace(const char* fmt, ...) __attribute__((format(printf, 2, 3)));; int LogTrace(const char* fmt, ...) __attribute__((format(printf, 2, 3)));
;
protected: protected:
bool dbgtrace; // print an execution trace bool dbgtrace; // print an execution trace
FILE* trace_file; FILE* trace_file;
}; };
extern TraceState g_trace_state; extern TraceState g_trace_state;
class DebuggerState { class DebuggerState
{
public: public:
DebuggerState(); DebuggerState();
~DebuggerState(); ~DebuggerState();
@ -78,7 +93,6 @@ public:
bool BreakFromSignal() { return break_from_signal; } bool BreakFromSignal() { return break_from_signal; }
void BreakFromSignal(bool dobrk) { break_from_signal = dobrk; } void BreakFromSignal(bool dobrk) { break_from_signal = dobrk; }
// Temporary state: vanishes when execution resumes. // Temporary state: vanishes when execution resumes.
//### Umesh, why do these all need to be public? -- Vern //### Umesh, why do these all need to be public? -- Vern
@ -103,14 +117,19 @@ protected:
private: private:
Frame* dbg_locals; // unused Frame* dbg_locals; // unused
}; };
// Source line -> statement mapping. // Source line -> statement mapping.
// (obj -> source line mapping available in object itself) // (obj -> source line mapping available in object itself)
class StmtLocMapping { class StmtLocMapping
{
public: public:
StmtLocMapping() { } StmtLocMapping() { }
StmtLocMapping(const Location* l, Stmt* s) { loc = *l; stmt = s; } StmtLocMapping(const Location* l, Stmt* s)
{
loc = *l;
stmt = s;
}
bool StartsAfter(const StmtLocMapping* m2); bool StartsAfter(const StmtLocMapping* m2);
const Location& Loc() const { return loc; } const Location& Loc() const { return loc; }
@ -119,7 +138,7 @@ public:
protected: protected:
Location loc; Location loc;
Stmt* stmt; Stmt* stmt;
}; };
extern bool g_policy_debug; // enable debugging facility extern bool g_policy_debug; // enable debugging facility
extern DebuggerState g_debugger_state; extern DebuggerState g_debugger_state;
@ -144,7 +163,6 @@ std::vector<ParseLocationRec> parse_location_string(const std::string& s);
// //
// Also add some hooks for UI? -- See GDB // Also add some hooks for UI? -- See GDB
// Debugging hooks. // Debugging hooks.
// Return true to continue execution, false to abort. // Return true to continue execution, false to abort.
@ -175,7 +193,7 @@ extern Frame* g_dbg_locals; // variables created within debugger context
extern std::map<std::string, Filemap*> g_dbgfilemaps; // filename => filemap extern std::map<std::string, Filemap*> g_dbgfilemaps; // filename => filemap
// Perhaps add a code/priority argument to do selective output. // Perhaps add a code/priority argument to do selective output.
int debug_msg(const char* fmt, ...) __attribute__ ((format (printf, 1, 2))); int debug_msg(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,32 +1,32 @@
// Support routines to help deal with Bro debugging commands and // Support routines to help deal with Bro debugging commands and
// implementation of most commands. // implementation of most commands.
#include "zeek/zeek-config.h"
#include "zeek/DebugCmds.h" #include "zeek/DebugCmds.h"
#include <sys/types.h> #include <assert.h>
#include <regex.h> #include <regex.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <sys/types.h>
#include "zeek/DebugCmdInfoConstants.cc"
#include "zeek/Debug.h"
#include "zeek/Desc.h"
#include "zeek/DbgBreakpoint.h" #include "zeek/DbgBreakpoint.h"
#include "zeek/ID.h" #include "zeek/Debug.h"
#include "zeek/DebugCmdInfoConstants.cc"
#include "zeek/Desc.h"
#include "zeek/Frame.h" #include "zeek/Frame.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/Stmt.h" #include "zeek/ID.h"
#include "zeek/Scope.h"
#include "zeek/Reporter.h"
#include "zeek/PolicyFile.h" #include "zeek/PolicyFile.h"
#include "zeek/Reporter.h"
#include "zeek/Scope.h"
#include "zeek/Stmt.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/util.h" #include "zeek/util.h"
#include "zeek/zeek-config.h"
using namespace std; using namespace std;
namespace zeek::detail { namespace zeek::detail
{
DebugCmdInfoQueue g_DebugCmdInfos; DebugCmdInfoQueue g_DebugCmdInfos;
@ -55,7 +55,7 @@ static void lookup_global_symbols_regex(const string& orig_regex, vector<ID*>& m
regex.push_back('$'); regex.push_back('$');
regex_t re; regex_t re;
if ( regcomp(&re, regex.c_str(), REG_EXTENDED|REG_NOSUB) ) if ( regcomp(&re, regex.c_str(), REG_EXTENDED | REG_NOSUB) )
{ {
debug_msg("Invalid regular expression: %s\n", regex.c_str()); debug_msg("Invalid regular expression: %s\n", regex.c_str());
return; return;
@ -69,7 +69,7 @@ static void lookup_global_symbols_regex(const string& orig_regex, vector<ID*>& m
{ {
ID* nextid = sym.second.get(); ID* nextid = sym.second.get();
if ( ! func_only || nextid->GetType()->Tag() == TYPE_FUNC ) if ( ! func_only || nextid->GetType()->Tag() == TYPE_FUNC )
if ( ! regexec (&re, nextid->Name(), 0, 0, 0) ) if ( ! regexec(&re, nextid->Name(), 0, 0, 0) )
matches.push_back(nextid); matches.push_back(nextid);
} }
} }
@ -87,7 +87,7 @@ static void choose_global_symbols_regex(const string& regex, vector<ID*>& choice
debug_msg("There were multiple matches, please choose:\n"); debug_msg("There were multiple matches, please choose:\n");
for ( size_t i = 0; i < choices.size(); i++ ) for ( size_t i = 0; i < choices.size(); i++ )
debug_msg("[%zu] %s\n", i+1, choices[i]->Name()); debug_msg("[%zu] %s\n", i + 1, choices[i]->Name());
debug_msg("[a] All of the above\n"); debug_msg("[a] All of the above\n");
debug_msg("[n] None of the above\n"); debug_msg("[n] None of the above\n");
@ -112,7 +112,7 @@ static void choose_global_symbols_regex(const string& regex, vector<ID*>& choice
return; return;
} }
int option = atoi(input.c_str()); int option = atoi(input.c_str());
if ( option > 0 && option <= (int) choices.size() ) if ( option > 0 && option <= (int)choices.size() )
{ {
ID* choice = choices[option - 1]; ID* choice = choices[option - 1];
choices.clear(); choices.clear();
@ -122,13 +122,11 @@ static void choose_global_symbols_regex(const string& regex, vector<ID*>& choice
} }
} }
// //
// DebugCmdInfo implementation // DebugCmdInfo implementation
// //
DebugCmdInfo::DebugCmdInfo(const DebugCmdInfo& info) DebugCmdInfo::DebugCmdInfo(const DebugCmdInfo& info) : cmd(info.cmd), helpstring(nullptr)
: cmd(info.cmd), helpstring(nullptr)
{ {
num_names = info.num_names; num_names = info.num_names;
names = info.names; names = info.names;
@ -136,11 +134,10 @@ DebugCmdInfo::DebugCmdInfo(const DebugCmdInfo& info)
repeatable = info.repeatable; repeatable = info.repeatable;
} }
DebugCmdInfo::DebugCmdInfo(DebugCmd arg_cmd, const char* const* arg_names, DebugCmdInfo::DebugCmdInfo(DebugCmd arg_cmd, const char* const* arg_names, int arg_num_names,
int arg_num_names, bool arg_resume_execution, bool arg_resume_execution, const char* const arg_helpstring,
const char* const arg_helpstring,
bool arg_repeatable) bool arg_repeatable)
: cmd(arg_cmd), helpstring(arg_helpstring) : cmd(arg_cmd), helpstring(arg_helpstring)
{ {
num_names = arg_num_names; num_names = arg_num_names;
resume_execution = arg_resume_execution; resume_execution = arg_resume_execution;
@ -150,11 +147,10 @@ DebugCmdInfo::DebugCmdInfo(DebugCmd arg_cmd, const char* const* arg_names,
names.push_back(arg_names[i]); names.push_back(arg_names[i]);
} }
const DebugCmdInfo* get_debug_cmd_info(DebugCmd cmd) const DebugCmdInfo* get_debug_cmd_info(DebugCmd cmd)
{ {
if ( (int) cmd < g_DebugCmdInfos.size() ) if ( (int)cmd < g_DebugCmdInfos.size() )
return g_DebugCmdInfos[(int) cmd]; return g_DebugCmdInfos[(int)cmd];
else else
return nullptr; return nullptr;
} }
@ -198,13 +194,11 @@ int find_all_matching_cmds(const string& prefix, const char* array_of_matches[])
// ------------------------------------------------------------ // ------------------------------------------------------------
// Implementation of some debugger commands // Implementation of some debugger commands
// Start, end bounds of which frame numbers to print // Start, end bounds of which frame numbers to print
static int dbg_backtrace_internal(int start, int end) static int dbg_backtrace_internal(int start, int end)
{ {
if ( start < 0 || end < 0 || if ( start < 0 || end < 0 || (unsigned)start >= g_frame_stack.size() ||
(unsigned) start >= g_frame_stack.size() || (unsigned)end >= g_frame_stack.size() )
(unsigned) end >= g_frame_stack.size() )
reporter->InternalError("Invalid stack frame index in DbgBacktraceInternal\n"); reporter->InternalError("Invalid stack frame index in DbgBacktraceInternal\n");
if ( start < end ) if ( start < end )
@ -220,14 +214,12 @@ static int dbg_backtrace_internal(int start, int end)
const Stmt* stmt = f ? f->GetNextStmt() : nullptr; const Stmt* stmt = f ? f->GetNextStmt() : nullptr;
string context = get_context_description(stmt, f); string context = get_context_description(stmt, f);
debug_msg("#%d %s\n", debug_msg("#%d %s\n", int(g_frame_stack.size() - 1 - i), context.c_str());
int(g_frame_stack.size() - 1 - i), context.c_str());
}; };
return 1; return 1;
} }
// Returns 0 for illegal arguments, or 1 on success. // Returns 0 for illegal arguments, or 1 on success.
int dbg_cmd_backtrace(DebugCmd cmd, const vector<string>& args) int dbg_cmd_backtrace(DebugCmd cmd, const vector<string>& args)
{ {
@ -271,7 +263,6 @@ int dbg_cmd_backtrace(DebugCmd cmd, const vector<string>& args)
return dbg_backtrace_internal(start_iter, end_iter); return dbg_backtrace_internal(start_iter, end_iter);
} }
// Returns 0 if invalid args, else 1. // Returns 0 if invalid args, else 1.
int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args) int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args)
{ {
@ -295,8 +286,7 @@ int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args)
return 0; return 0;
} }
if ( idx < 0 || if ( idx < 0 || (unsigned int)idx >= g_frame_stack.size() )
(unsigned int) idx >= g_frame_stack.size() )
{ {
debug_msg("No frame %d", idx); debug_msg("No frame %d", idx);
return 0; return 0;
@ -319,8 +309,7 @@ int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args)
else if ( cmd == dcUp ) else if ( cmd == dcUp )
{ {
if ( (unsigned int)(g_debugger_state.curr_frame_idx + 1) == if ( (unsigned int)(g_debugger_state.curr_frame_idx + 1) == g_frame_stack.size() )
g_frame_stack.size() )
{ {
debug_msg("Outermost frame already selected\n"); debug_msg("Outermost frame already selected\n");
return 0; return 0;
@ -329,8 +318,7 @@ int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args)
++g_debugger_state.curr_frame_idx; ++g_debugger_state.curr_frame_idx;
} }
int user_frame_number = int user_frame_number = g_frame_stack.size() - 1 - g_debugger_state.curr_frame_idx;
g_frame_stack.size() - 1 - g_debugger_state.curr_frame_idx;
// Set the current location to the new frame being looked at // Set the current location to the new frame being looked at
// for 'list', 'break', etc. // for 'list', 'break', etc.
@ -352,14 +340,13 @@ int dbg_cmd_help(DebugCmd cmd, const vector<string>& args)
debug_msg("Help summary: \n\n"); debug_msg("Help summary: \n\n");
for ( int i = 1; i < num_debug_cmds(); ++i ) for ( int i = 1; i < num_debug_cmds(); ++i )
{ {
const DebugCmdInfo* info = get_debug_cmd_info (DebugCmd(i)); const DebugCmdInfo* info = get_debug_cmd_info(DebugCmd(i));
debug_msg("%s -- %s\n", info->Names()[0], info->Helpstring()); debug_msg("%s -- %s\n", info->Names()[0], info->Helpstring());
} }
return -1; return -1;
} }
int dbg_cmd_break(DebugCmd cmd, const vector<string>& args) int dbg_cmd_break(DebugCmd cmd, const vector<string>& args)
{ {
assert(cmd == dcBreak); assert(cmd == dcBreak);
@ -370,9 +357,7 @@ int dbg_cmd_break(DebugCmd cmd, const vector<string>& args)
if ( args.empty() || args[0] == "if" ) if ( args.empty() || args[0] == "if" )
{ // break on next stmt { // break on next stmt
int user_frame_number = int user_frame_number = g_frame_stack.size() - 1 - g_debugger_state.curr_frame_idx;
g_frame_stack.size() - 1 -
g_debugger_state.curr_frame_idx;
Stmt* stmt = g_frame_stack[user_frame_number]->GetNextStmt(); Stmt* stmt = g_frame_stack[user_frame_number]->GetNextStmt();
if ( ! stmt ) if ( ! stmt )
@ -407,13 +392,10 @@ int dbg_cmd_break(DebugCmd cmd, const vector<string>& args)
else else
locstrings.push_back(args[0].c_str()); locstrings.push_back(args[0].c_str());
for ( unsigned int strindex = 0; strindex < locstrings.size(); for ( unsigned int strindex = 0; strindex < locstrings.size(); ++strindex )
++strindex )
{ {
debug_msg("Setting breakpoint on %s:\n", debug_msg("Setting breakpoint on %s:\n", locstrings[strindex].c_str());
locstrings[strindex].c_str()); vector<ParseLocationRec> plrs = parse_location_string(locstrings[strindex]);
vector<ParseLocationRec> plrs =
parse_location_string(locstrings[strindex]);
for ( const auto& plr : plrs ) for ( const auto& plr : plrs )
{ {
DbgBreakpoint* bp = new DbgBreakpoint(); DbgBreakpoint* bp = new DbgBreakpoint();
@ -482,9 +464,8 @@ int dbg_cmd_break_condition(DebugCmd cmd, const vector<string>& args)
// Change the state of a breakpoint. // Change the state of a breakpoint.
int dbg_cmd_break_set_state(DebugCmd cmd, const vector<string>& args) int dbg_cmd_break_set_state(DebugCmd cmd, const vector<string>& args)
{ {
assert(cmd == dcDeleteBreak || cmd == dcClearBreak || assert(cmd == dcDeleteBreak || cmd == dcClearBreak || cmd == dcDisableBreak ||
cmd == dcDisableBreak || cmd == dcEnableBreak || cmd == dcEnableBreak || cmd == dcIgnoreBreak);
cmd == dcIgnoreBreak);
if ( cmd == dcClearBreak || cmd == dcIgnoreBreak ) if ( cmd == dcClearBreak || cmd == dcIgnoreBreak )
{ {
@ -494,7 +475,7 @@ int dbg_cmd_break_set_state(DebugCmd cmd, const vector<string>& args)
if ( g_debugger_state.breakpoints.empty() ) if ( g_debugger_state.breakpoints.empty() )
{ {
debug_msg ("No breakpoints currently set.\n"); debug_msg("No breakpoints currently set.\n");
return -1; return -1;
} }
@ -516,12 +497,12 @@ int dbg_cmd_break_set_state(DebugCmd cmd, const vector<string>& args)
for ( auto bp_change : bps_to_change ) for ( auto bp_change : bps_to_change )
{ {
BPIDMapType::iterator result = BPIDMapType::iterator result = g_debugger_state.breakpoints.find(bp_change);
g_debugger_state.breakpoints.find(bp_change);
if ( result != g_debugger_state.breakpoints.end() ) if ( result != g_debugger_state.breakpoints.end() )
{ {
switch ( cmd ) { switch ( cmd )
{
case dcDisableBreak: case dcDisableBreak:
g_debugger_state.breakpoints[bp_change]->SetEnable(false); g_debugger_state.breakpoints[bp_change]->SetEnable(false);
debug_msg("Breakpoint %d disabled\n", bp_change); debug_msg("Breakpoint %d disabled\n", bp_change);
@ -582,7 +563,6 @@ int dbg_cmd_print(DebugCmd cmd, const vector<string>& args)
return 1; return 1;
} }
// Get the debugger's state. // Get the debugger's state.
// Allowed arguments are: break (breakpoints), watch, display, source. // Allowed arguments are: break (breakpoints), watch, display, source.
int dbg_cmd_info(DebugCmd cmd, const vector<string>& args) int dbg_cmd_info(DebugCmd cmd, const vector<string>& args)
@ -604,15 +584,11 @@ int dbg_cmd_info(DebugCmd cmd, const vector<string>& args)
BPIDMapType::iterator iter; BPIDMapType::iterator iter;
for ( iter = g_debugger_state.breakpoints.begin(); for ( iter = g_debugger_state.breakpoints.begin();
iter != g_debugger_state.breakpoints.end(); iter != g_debugger_state.breakpoints.end(); ++iter )
++iter )
{ {
DbgBreakpoint* bp = (*iter).second; DbgBreakpoint* bp = (*iter).second;
debug_msg("%-4d%-15s%-5s%-4s%s\n", debug_msg("%-4d%-15s%-5s%-4s%s\n", bp->GetID(), "breakpoint",
bp->GetID(), bp->IsTemporary() ? "del" : "keep", bp->IsEnabled() ? "y" : "n",
"breakpoint",
bp->IsTemporary() ? "del" : "keep",
bp->IsEnabled() ? "y" : "n",
bp->Description()); bp->Description());
} }
} }
@ -676,22 +652,18 @@ int dbg_cmd_list(DebugCmd cmd, const vector<string>& args)
pre_offset = 0; pre_offset = 0;
} }
if ( (int) pre_offset + if ( (int)pre_offset + (int)g_debugger_state.last_loc.first_line - (int)CENTER_IDX < 0 )
(int) g_debugger_state.last_loc.first_line -
(int) CENTER_IDX < 0 )
pre_offset = CENTER_IDX - g_debugger_state.last_loc.first_line; pre_offset = CENTER_IDX - g_debugger_state.last_loc.first_line;
g_debugger_state.last_loc.first_line += pre_offset; g_debugger_state.last_loc.first_line += pre_offset;
int last_line_in_file = int last_line_in_file = how_many_lines_in(g_debugger_state.last_loc.filename);
how_many_lines_in(g_debugger_state.last_loc.filename);
if ( g_debugger_state.last_loc.first_line > last_line_in_file ) if ( g_debugger_state.last_loc.first_line > last_line_in_file )
g_debugger_state.last_loc.first_line = last_line_in_file; g_debugger_state.last_loc.first_line = last_line_in_file;
PrintLines(g_debugger_state.last_loc.filename, PrintLines(g_debugger_state.last_loc.filename,
g_debugger_state.last_loc.first_line - CENTER_IDX, g_debugger_state.last_loc.first_line - CENTER_IDX, 10, true);
10, true);
g_debugger_state.already_did_list = true; g_debugger_state.already_did_list = true;
@ -704,8 +676,7 @@ int dbg_cmd_trace(DebugCmd cmd, const vector<string>& args)
if ( args.empty() ) if ( args.empty() )
{ {
debug_msg("Execution tracing is %s.\n", debug_msg("Execution tracing is %s.\n", g_trace_state.DoTrace() ? "on" : "off");
g_trace_state.DoTrace() ? "on" : "off" );
return 1; return 1;
} }
@ -725,4 +696,4 @@ int dbg_cmd_trace(DebugCmd cmd, const vector<string>& args)
return 0; return 0;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -4,28 +4,29 @@
#pragma once #pragma once
#include <stdlib.h> #include <stdlib.h>
#include <deque>
#include <string> #include <string>
#include <vector> #include <vector>
#include <deque>
// This file is generated during the build. // This file is generated during the build.
#include "DebugCmdConstants.h" #include "DebugCmdConstants.h"
namespace zeek::detail { namespace zeek::detail
{
class DebugCmdInfo { class DebugCmdInfo
{
public: public:
DebugCmdInfo(const DebugCmdInfo& info); DebugCmdInfo(const DebugCmdInfo& info);
DebugCmdInfo(DebugCmd cmd, const char* const* names, int num_names, DebugCmdInfo(DebugCmd cmd, const char* const* names, int num_names, bool resume_execution,
bool resume_execution, const char* const helpstring, const char* const helpstring, bool repeatable);
bool repeatable);
DebugCmdInfo() : helpstring(nullptr) {} DebugCmdInfo() : helpstring(nullptr) { }
int Cmd() const { return cmd; } int Cmd() const { return cmd; }
int NumNames() const { return num_names; } int NumNames() const { return num_names; }
const std::vector<const char *>& Names() const { return names; } const std::vector<const char*>& Names() const { return names; }
bool ResumeExecution() const { return resume_execution; } bool ResumeExecution() const { return resume_execution; }
const char* Helpstring() const { return helpstring; } const char* Helpstring() const { return helpstring; }
bool Repeatable() const { return repeatable; } bool Repeatable() const { return repeatable; }
@ -42,12 +43,12 @@ protected:
// Does entering a blank line repeat this command? // Does entering a blank line repeat this command?
bool repeatable; bool repeatable;
}; };
using DebugCmdInfoQueue = std::deque<DebugCmdInfo*>; using DebugCmdInfoQueue = std::deque<DebugCmdInfo*>;
extern DebugCmdInfoQueue g_DebugCmdInfos; extern DebugCmdInfoQueue g_DebugCmdInfos;
void init_global_dbg_constants (); void init_global_dbg_constants();
#define num_debug_cmds() (static_cast<int>(g_DebugCmdInfos.size())) #define num_debug_cmds() (static_cast<int>(g_DebugCmdInfos.size()))
@ -79,4 +80,4 @@ DbgCmdFn dbg_cmd_info;
DbgCmdFn dbg_cmd_list; DbgCmdFn dbg_cmd_list;
DbgCmdFn dbg_cmd_trace; DbgCmdFn dbg_cmd_trace;
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -11,29 +11,17 @@
zeek::detail::DebugLogger zeek::detail::debug_logger; zeek::detail::DebugLogger zeek::detail::debug_logger;
zeek::detail::DebugLogger& debug_logger = zeek::detail::debug_logger; zeek::detail::DebugLogger& debug_logger = zeek::detail::debug_logger;
namespace zeek::detail { namespace zeek::detail
{
// Same order here as in DebugStream. // Same order here as in DebugStream.
DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = { DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = {
{ "serial", 0, false }, {"serial", 0, false}, {"rules", 0, false}, {"string", 0, false},
{ "rules", 0, false }, {"notifiers", 0, false}, {"main-loop", 0, false}, {"dpd", 0, false},
{ "string", 0, false }, {"packet_analysis", 0, false}, {"file_analysis", 0, false}, {"tm", 0, false},
{ "notifiers", 0, false }, {"logging", 0, false}, {"input", 0, false}, {"threading", 0, false},
{ "main-loop", 0, false }, {"plugins", 0, false}, {"zeekygen", 0, false}, {"pktio", 0, false},
{ "dpd", 0, false }, {"broker", 0, false}, {"scripts", 0, false}, {"supervisor", 0, false}};
{ "packet_analysis", 0, false },
{ "file_analysis", 0, false },
{ "tm", 0, false },
{ "logging", 0, false },
{ "input", 0, false },
{ "threading", 0, false },
{ "plugins", 0, false },
{ "zeekygen", 0, false },
{ "pktio", 0, false },
{ "broker", 0, false },
{ "scripts", 0, false },
{ "supervisor", 0, false }
};
DebugLogger::DebugLogger() DebugLogger::DebugLogger()
{ {
@ -81,10 +69,11 @@ void DebugLogger::ShowStreamsHelp()
fprintf(stderr, "Available streams:\n"); fprintf(stderr, "Available streams:\n");
for ( int i = 0; i < NUM_DBGS; ++i ) for ( int i = 0; i < NUM_DBGS; ++i )
fprintf(stderr," %s\n", streams[i].prefix); fprintf(stderr, " %s\n", streams[i].prefix);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, " plugin-<plugin-name> (replace '::' in name with '-'; e.g., '-B plugin-Zeek-Netmap')\n"); fprintf(stderr, " plugin-<plugin-name> (replace '::' in name with '-'; e.g., '-B "
"plugin-Zeek-Netmap')\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Pseudo streams\n"); fprintf(stderr, "Pseudo streams\n");
fprintf(stderr, " verbose Increase verbosity.\n"); fprintf(stderr, " verbose Increase verbosity.\n");
@ -146,11 +135,11 @@ void DebugLogger::EnableStreams(const char* s)
reporter->FatalError("unknown debug stream '%s', try -B help.\n", tok); reporter->FatalError("unknown debug stream '%s', try -B help.\n", tok);
next: next:
tok = strtok(0, ","); tok = strtok(0, ",");
} }
delete [] tmp; delete[] tmp;
} }
void DebugLogger::Log(DebugStream stream, const char* fmt, ...) void DebugLogger::Log(DebugStream stream, const char* fmt, ...)
@ -160,8 +149,8 @@ void DebugLogger::Log(DebugStream stream, const char* fmt, ...)
if ( ! g->enabled ) if ( ! g->enabled )
return; return;
fprintf(file, "%17.06f/%17.06f [%s] ", fprintf(file, "%17.06f/%17.06f [%s] ", run_state::network_time, util::current_time(true),
run_state::network_time, util::current_time(true), g->prefix); g->prefix);
for ( int i = g->indent; i > 0; --i ) for ( int i = g->indent; i > 0; --i )
fputs(" ", file); fputs(" ", file);
@ -183,8 +172,8 @@ void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...)
if ( enabled_streams.find(tok) == enabled_streams.end() ) if ( enabled_streams.find(tok) == enabled_streams.end() )
return; return;
fprintf(file, "%17.06f/%17.06f [plugin %s] ", fprintf(file, "%17.06f/%17.06f [plugin %s] ", run_state::network_time, util::current_time(true),
run_state::network_time, util::current_time(true), plugin.Name().c_str()); plugin.Name().c_str());
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@ -195,6 +184,6 @@ void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...)
fflush(file); fflush(file);
} }
} // namespace zeek::detail } // namespace zeek::detail
#endif #endif

View file

@ -5,31 +5,37 @@
#ifdef DEBUG #ifdef DEBUG
#include "zeek/zeek-config.h"
#include <stdio.h> #include <stdio.h>
#include <string>
#include <set> #include <set>
#include <string>
#include "zeek/zeek-config.h"
#define DBG_LOG(stream, args...) \ #define DBG_LOG(stream, args...) \
if ( ::zeek::detail::debug_logger.IsEnabled(stream) ) \ if ( ::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args) ::zeek::detail::debug_logger.Log(stream, args)
#define DBG_LOG_VERBOSE(stream, args...) \ #define DBG_LOG_VERBOSE(stream, args...) \
if ( ::zeek::detail::debug_logger.IsVerbose() && ::zeek::detail::debug_logger.IsEnabled(stream) ) \ if ( ::zeek::detail::debug_logger.IsVerbose() && \
::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args) ::zeek::detail::debug_logger.Log(stream, args)
#define DBG_PUSH(stream) ::zeek::detail::debug_logger.PushIndent(stream) #define DBG_PUSH(stream) ::zeek::detail::debug_logger.PushIndent(stream)
#define DBG_POP(stream) ::zeek::detail::debug_logger.PopIndent(stream) #define DBG_POP(stream) ::zeek::detail::debug_logger.PopIndent(stream)
#define PLUGIN_DBG_LOG(plugin, args...) ::zeek::detail::debug_logger.Log(plugin, args) #define PLUGIN_DBG_LOG(plugin, args...) ::zeek::detail::debug_logger.Log(plugin, args)
namespace zeek { namespace zeek
{
namespace plugin { class Plugin; } namespace plugin
{
class Plugin;
}
// To add a new debugging stream, add a constant here as well as // To add a new debugging stream, add a constant here as well as
// an entry to DebugLogger::streams in DebugLogger.cc. // an entry to DebugLogger::streams in DebugLogger.cc.
enum DebugStream { enum DebugStream
{
DBG_SERIAL, // Serialization DBG_SERIAL, // Serialization
DBG_RULES, // Signature matching DBG_RULES, // Signature matching
DBG_STRING, // String code DBG_STRING, // String code
@ -50,11 +56,13 @@ enum DebugStream {
DBG_SUPERVISOR, // Process supervisor DBG_SUPERVISOR, // Process supervisor
NUM_DBGS // Has to be last NUM_DBGS // Has to be last
}; };
namespace detail { namespace detail
{
class DebugLogger { class DebugLogger
{
public: public:
// Output goes to stderr per default. // Output goes to stderr per default.
DebugLogger(); DebugLogger();
@ -63,23 +71,19 @@ public:
void OpenDebugLog(const char* filename = 0); void OpenDebugLog(const char* filename = 0);
void Log(DebugStream stream, const char* fmt, ...) __attribute__((format(printf, 3, 4))); void Log(DebugStream stream, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
void Log(const plugin::Plugin& plugin, const char* fmt, ...) __attribute__((format(printf, 3, 4))); void Log(const plugin::Plugin& plugin, const char* fmt, ...)
__attribute__((format(printf, 3, 4)));
void PushIndent(DebugStream stream) void PushIndent(DebugStream stream) { ++streams[int(stream)].indent; }
{ ++streams[int(stream)].indent; } void PopIndent(DebugStream stream) { --streams[int(stream)].indent; }
void PopIndent(DebugStream stream)
{ --streams[int(stream)].indent; }
void EnableStream(DebugStream stream) void EnableStream(DebugStream stream) { streams[int(stream)].enabled = true; }
{ streams[int(stream)].enabled = true; } void DisableStream(DebugStream stream) { streams[int(stream)].enabled = false; }
void DisableStream(DebugStream stream)
{ streams[int(stream)].enabled = false; }
// Takes comma-seperated list of stream prefixes. // Takes comma-seperated list of stream prefixes.
void EnableStreams(const char* streams); void EnableStreams(const char* streams);
bool IsEnabled(DebugStream stream) const bool IsEnabled(DebugStream stream) const { return streams[int(stream)].enabled; }
{ return streams[int(stream)].enabled; }
void SetVerbose(bool arg_verbose) { verbose = arg_verbose; } void SetVerbose(bool arg_verbose) { verbose = arg_verbose; }
bool IsVerbose() const { return verbose; } bool IsVerbose() const { return verbose; }
@ -90,7 +94,8 @@ private:
FILE* file; FILE* file;
bool verbose; bool verbose;
struct Stream { struct Stream
{
const char* prefix; const char* prefix;
int indent; int indent;
bool enabled; bool enabled;
@ -99,12 +104,12 @@ private:
std::set<std::string> enabled_streams; std::set<std::string> enabled_streams;
static Stream streams[NUM_DBGS]; static Stream streams[NUM_DBGS];
}; };
extern DebugLogger debug_logger; extern DebugLogger debug_logger;
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek
#else #else
#define DBG_LOG(args...) #define DBG_LOG(args...)

View file

@ -1,22 +1,23 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#include <math.h> #include <math.h>
#include <stdlib.h>
#include <string.h>
#include "zeek/File.h"
#include "zeek/Reporter.h"
#include "zeek/ConvertUTF.h" #include "zeek/ConvertUTF.h"
#include "zeek/File.h"
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/Reporter.h"
#include "zeek/zeek-config.h"
#define DEFAULT_SIZE 128 #define DEFAULT_SIZE 128
#define SLOP 10 #define SLOP 10
namespace zeek { namespace zeek
{
ODesc::ODesc(DescType t, File* arg_f) ODesc::ODesc(DescType t, File* arg_f)
{ {
@ -28,7 +29,7 @@ ODesc::ODesc(DescType t, File* arg_f)
{ {
size = DEFAULT_SIZE; size = DEFAULT_SIZE;
base = util::safe_malloc(size); base = util::safe_malloc(size);
((char*) base)[0] = '\0'; ((char*)base)[0] = '\0';
offset = 0; offset = 0;
} }
else else
@ -64,7 +65,7 @@ void ODesc::EnableEscaping()
escape = true; escape = true;
} }
void ODesc::EnableUTF8 () void ODesc::EnableUTF8()
{ {
utf8 = true; utf8 = true;
} }
@ -93,12 +94,11 @@ void ODesc::Add(const char* s, int do_indent)
{ {
unsigned int n = strlen(s); unsigned int n = strlen(s);
if ( do_indent && IsReadable() && offset > 0 && if ( do_indent && IsReadable() && offset > 0 && ((const char*)base)[offset - 1] == '\n' )
((const char*) base)[offset - 1] == '\n' )
Indent(); Indent();
if ( IsBinary() ) if ( IsBinary() )
AddBytes(s, n+1); AddBytes(s, n + 1);
else else
AddBytes(s, n); AddBytes(s, n);
} }
@ -174,8 +174,7 @@ void ODesc::Add(double d, bool no_exp)
return v < 0 ? -v < tolerance : v < tolerance; return v < 0 ? -v < tolerance : v < tolerance;
}; };
if ( approx_equal(d, nearbyint(d), 1e-9) && if ( approx_equal(d, nearbyint(d), 1e-9) && isfinite(d) && ! strchr(tmp, 'e') )
isfinite(d) && ! strchr(tmp, 'e') )
// disambiguate from integer // disambiguate from integer
Add(".0"); Add(".0");
} }
@ -210,7 +209,7 @@ void ODesc::AddBytes(const String* s)
{ {
const char* str = s->Render(String::EXPANDED_STRING); const char* str = s->Render(String::EXPANDED_STRING);
Add(str); Add(str);
delete [] str; delete[] str;
} }
} }
else else
@ -299,12 +298,12 @@ void ODesc::AddBytes(const void* bytes, unsigned int n)
return; return;
} }
const char* s = (const char*) bytes; const char* s = (const char*)bytes;
const char* e = (const char*) bytes + n; const char* e = (const char*)bytes + n;
while ( s < e ) while ( s < e )
{ {
auto [ esc_start, esc_len ] = FirstEscapeLoc(s, e - s); auto [esc_start, esc_len] = FirstEscapeLoc(s, e - s);
if ( esc_start != nullptr ) if ( esc_start != nullptr )
{ {
@ -343,7 +342,7 @@ void ODesc::AddBytesRaw(const void* bytes, unsigned int n)
{ {
static bool write_failed = false; static bool write_failed = false;
if ( ! f->Write((const char*) bytes, n) ) if ( ! f->Write((const char*)bytes, n) )
{ {
if ( ! write_failed ) if ( ! write_failed )
// Most likely it's a "disk full" so report // Most likely it's a "disk full" so report
@ -364,10 +363,10 @@ void ODesc::AddBytesRaw(const void* bytes, unsigned int n)
// The following casting contortions are necessary because // The following casting contortions are necessary because
// simply using &base[offset] generates complaints about // simply using &base[offset] generates complaints about
// using a void* for pointer arithemtic. // using a void* for pointer arithemtic.
memcpy((void*) &((char*) base)[offset], bytes, n); memcpy((void*)&((char*)base)[offset], bytes, n);
offset += n; offset += n;
((char*) base)[offset] = '\0'; // ensure that always NUL-term. ((char*)base)[offset] = '\0'; // ensure that always NUL-term.
} }
} }
@ -389,7 +388,7 @@ void ODesc::Clear()
free(base); free(base);
size = DEFAULT_SIZE; size = DEFAULT_SIZE;
base = util::safe_malloc(size); base = util::safe_malloc(size);
((char*) base)[0] = '\0'; ((char*)base)[0] = '\0';
} }
} }
@ -415,7 +414,6 @@ bool ODesc::FindType(const Type* type)
return false; return false;
} }
std::string obj_desc(const Obj* o) std::string obj_desc(const Obj* o)
{ {
static ODesc d; static ODesc d;
@ -428,4 +426,4 @@ std::string obj_desc(const Obj* o)
return std::string(d.Description()); return std::string(d.Description());
} }
} // namespace zeek } // namespace zeek

View file

@ -3,35 +3,38 @@
#pragma once #pragma once
#include <sys/types.h> // for u_char #include <sys/types.h> // for u_char
#include <set> #include <set>
#include <utility>
#include <string> #include <string>
#include <utility>
#include "zeek/ZeekString.h" // for byte_vec #include "zeek/ZeekString.h" // for byte_vec
#include "zeek/util.h" // for bro_int_t #include "zeek/util.h" // for bro_int_t
namespace zeek { namespace zeek
{
class IPAddr; class IPAddr;
class IPPrefix; class IPPrefix;
class File; class File;
class Type; class Type;
enum DescType { enum DescType
{
DESC_READABLE, DESC_READABLE,
DESC_PORTABLE, DESC_PORTABLE,
DESC_BINARY, DESC_BINARY,
}; };
enum DescStyle { enum DescStyle
{
STANDARD_STYLE, STANDARD_STYLE,
RAW_STYLE, RAW_STYLE,
}; };
class ODesc { class ODesc
{
public: public:
explicit ODesc(DescType t=DESC_READABLE, File* f=nullptr); explicit ODesc(DescType t = DESC_READABLE, File* f = nullptr);
~ODesc(); ~ODesc();
@ -65,15 +68,14 @@ public:
void EnableEscaping(); void EnableEscaping();
void EnableUTF8(); void EnableUTF8();
void AddEscapeSequence(const char* s) { escape_sequences.insert(s); } void AddEscapeSequence(const char* s) { escape_sequences.insert(s); }
void AddEscapeSequence(const char* s, size_t n) void AddEscapeSequence(const char* s, size_t n) { escape_sequences.insert(std::string(s, n)); }
{ escape_sequences.insert(std::string(s, n)); } void AddEscapeSequence(const std::string& s) { escape_sequences.insert(s); }
void AddEscapeSequence(const std::string & s)
{ escape_sequences.insert(s); }
void RemoveEscapeSequence(const char* s) { escape_sequences.erase(s); } void RemoveEscapeSequence(const char* s) { escape_sequences.erase(s); }
void RemoveEscapeSequence(const char* s, size_t n) void RemoveEscapeSequence(const char* s, size_t n)
{ escape_sequences.erase(std::string(s, n)); } {
void RemoveEscapeSequence(const std::string & s) escape_sequences.erase(std::string(s, n));
{ escape_sequences.erase(s); } }
void RemoveEscapeSequence(const std::string& s) { escape_sequences.erase(s); }
void PushIndent(); void PushIndent();
void PopIndent(); void PopIndent();
@ -84,14 +86,14 @@ public:
int IndentSpaces() const { return indent_with_spaces; } int IndentSpaces() const { return indent_with_spaces; }
void SetIndentSpaces(int i) { indent_with_spaces = i; } void SetIndentSpaces(int i) { indent_with_spaces = i; }
void Add(const char* s, int do_indent=1); void Add(const char* s, int do_indent = 1);
void AddN(const char* s, int len) { AddBytes(s, len); } void AddN(const char* s, int len) { AddBytes(s, len); }
void Add(const std::string& s) { AddBytes(s.data(), s.size()); } void Add(const std::string& s) { AddBytes(s.data(), s.size()); }
void Add(int i); void Add(int i);
void Add(uint32_t u); void Add(uint32_t u);
void Add(int64_t i); void Add(int64_t i);
void Add(uint64_t u); void Add(uint64_t u);
void Add(double d, bool no_exp=false); void Add(double d, bool no_exp = false);
void Add(const IPAddr& addr); void Add(const IPAddr& addr);
void Add(const IPPrefix& prefix); void Add(const IPPrefix& prefix);
@ -101,13 +103,22 @@ public:
void AddBytes(const String* s); void AddBytes(const String* s);
void Add(const char* s1, const char* s2) void Add(const char* s1, const char* s2)
{ Add(s1); Add(s2); } {
Add(s1);
Add(s2);
}
void AddSP(const char* s1, const char* s2) void AddSP(const char* s1, const char* s2)
{ Add(s1); AddSP(s2); } {
Add(s1);
AddSP(s2);
}
void AddSP(const char* s ) void AddSP(const char* s)
{ Add(s); SP(); } {
Add(s);
SP();
}
void AddCount(bro_int_t n) void AddCount(bro_int_t n)
{ {
@ -118,23 +129,25 @@ public:
} }
} }
void SP() { void SP()
{
if ( ! IsBinary() ) if ( ! IsBinary() )
Add(" ", 0); Add(" ", 0);
} }
void NL() { void NL()
{
if ( ! IsBinary() && ! is_short ) if ( ! IsBinary() && ! is_short )
Add("\n", 0); Add("\n", 0);
} }
// Bypasses the escaping enabled via EnableEscaping(). // Bypasses the escaping enabled via EnableEscaping().
void AddRaw(const char* s, int len) { AddBytesRaw(s, len); } void AddRaw(const char* s, int len) { AddBytesRaw(s, len); }
void AddRaw(const std::string &s) { AddBytesRaw(s.data(), s.size()); } void AddRaw(const std::string& s) { AddBytesRaw(s.data(), s.size()); }
// Returns the description as a string. // Returns the description as a string.
const char* Description() const { return (const char*) base; } const char* Description() const { return (const char*)base; }
const u_char* Bytes() const { return (const u_char *) base; } const u_char* Bytes() const { return (const u_char*)base; }
byte_vec TakeBytes() byte_vec TakeBytes()
{ {
const void* t = base; const void* t = base;
@ -212,7 +225,7 @@ protected:
File* f; // or the file we're using. File* f; // or the file we're using.
std::set<const Type*> encountered_types; std::set<const Type*> encountered_types;
}; };
// Returns a string representation of an object's description. Used for // Returns a string representation of an object's description. Used for
// debugging and error messages. takes a bare pointer rather than an // debugging and error messages. takes a bare pointer rather than an
@ -221,4 +234,4 @@ protected:
class Obj; class Obj;
extern std::string obj_desc(const Obj* o); extern std::string obj_desc(const Obj* o);
} // namespace zeek } // namespace zeek

File diff suppressed because it is too large Load diff

View file

@ -3,31 +3,37 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <vector>
#include <memory> #include <memory>
#include <vector>
#include "zeek/Hash.h" #include "zeek/Hash.h"
// Type for function to be called when deleting elements. // Type for function to be called when deleting elements.
typedef void (*dict_delete_func)(void*); typedef void (*dict_delete_func)(void*);
namespace zeek { namespace zeek
{
class IterCookie; class IterCookie;
class Dictionary; class Dictionary;
enum DictOrder { ORDERED, UNORDERED }; enum DictOrder
{
ORDERED,
UNORDERED
};
// A dict_delete_func that just calls delete. // A dict_delete_func that just calls delete.
extern void generic_delete_func(void*); extern void generic_delete_func(void*);
namespace detail { namespace detail
{
class DictEntry; class DictEntry;
// Default number of hash buckets in dictionary. The dictionary will increase the size // Default number of hash buckets in dictionary. The dictionary will increase the size
// of the hash table as needed. // of the hash table as needed.
constexpr uint32_t HASH_MASK = 0xFFFFFFFF; //only lower 32 bits. constexpr uint32_t HASH_MASK = 0xFFFFFFFF; // only lower 32 bits.
// These four variables can be used to build different targets with -Dxxx for performance // These four variables can be used to build different targets with -Dxxx for performance
// or for debugging purposes. // or for debugging purposes.
@ -54,9 +60,9 @@ constexpr uint16_t TOO_FAR_TO_REACH = 0xFFFF;
/** /**
* An entry stored in the dictionary. * An entry stored in the dictionary.
*/ */
class DictEntry { class DictEntry
{
public: public:
#ifdef DEBUG #ifdef DEBUG
int bucket = 0; int bucket = 0;
#endif #endif
@ -73,7 +79,7 @@ public:
void* value = nullptr; void* value = nullptr;
union { union {
char key_here[8]; //hold key len<=8. when over 8, it's a pointer to real keys. char key_here[8]; // hold key len<=8. when over 8, it's a pointer to real keys.
char* key; char* key;
}; };
@ -88,7 +94,7 @@ public:
{ {
memcpy(key_here, arg_key, key_size); memcpy(key_here, arg_key, key_size);
if ( ! copy_key ) if ( ! copy_key )
delete [] (char*)arg_key; //own the arg_key, now don't need it. delete[](char*) arg_key; // own the arg_key, now don't need it.
} }
else else
{ {
@ -115,13 +121,13 @@ public:
value = nullptr; value = nullptr;
key_size = 0; key_size = 0;
bucket = 0; bucket = 0;
#endif//DEBUG #endif // DEBUG
} }
void Clear() void Clear()
{ {
if( key_size > 8 ) if ( key_size > 8 )
delete [] key; delete[] key;
SetEmpty(); SetEmpty();
} }
@ -131,27 +137,21 @@ public:
return std::make_unique<detail::HashKey>(GetKey(), key_size, hash); return std::make_unique<detail::HashKey>(GetKey(), key_size, hash);
} }
template <typename T> template <typename T> T GetValue() const { return static_cast<T>(value); }
T GetValue() const { return static_cast<T>(value); }
bool Equal(const char* arg_key, int arg_key_size, hash_t arg_hash) const bool Equal(const char* arg_key, int arg_key_size, hash_t arg_hash) const
{//only 40-bit hash comparison. { // only 40-bit hash comparison.
return ( 0 == ((hash ^ arg_hash) & HASH_MASK) ) return (0 == ((hash ^ arg_hash) & HASH_MASK)) && key_size == arg_key_size &&
&& key_size == arg_key_size && 0 == memcmp(GetKey(), arg_key, key_size); 0 == memcmp(GetKey(), arg_key, key_size);
} }
bool operator==(const DictEntry& r) const bool operator==(const DictEntry& r) const { return Equal(r.GetKey(), r.key_size, r.hash); }
{ bool operator!=(const DictEntry& r) const { return ! Equal(r.GetKey(), r.key_size, r.hash); }
return Equal(r.GetKey(), r.key_size, r.hash); };
}
bool operator!=(const DictEntry& r) const
{
return ! Equal(r.GetKey(), r.key_size, r.hash);
}
};
} // namespace detail } // namespace detail
class DictIterator { class DictIterator
{
public: public:
using value_type = detail::DictEntry; using value_type = detail::DictEntry;
using reference = detail::DictEntry&; using reference = detail::DictEntry&;
@ -171,13 +171,17 @@ public:
pointer operator->() { return curr; } pointer operator->() { return curr; }
DictIterator& operator++(); DictIterator& operator++();
DictIterator operator++(int) { auto temp(*this); ++*this; return temp; } DictIterator operator++(int)
{
auto temp(*this);
++*this;
return temp;
}
bool operator==( const DictIterator& that ) const { return curr == that.curr; } bool operator==(const DictIterator& that) const { return curr == that.curr; }
bool operator!=( const DictIterator& that ) const { return !(*this == that); } bool operator!=(const DictIterator& that) const { return ! (*this == that); }
private: private:
friend class Dictionary; friend class Dictionary;
DictIterator(const Dictionary* d, detail::DictEntry* begin, detail::DictEntry* end); DictIterator(const Dictionary* d, detail::DictEntry* begin, detail::DictEntry* end);
@ -185,9 +189,10 @@ private:
Dictionary* dict = nullptr; Dictionary* dict = nullptr;
detail::DictEntry* curr = nullptr; detail::DictEntry* curr = nullptr;
detail::DictEntry* end = nullptr; detail::DictEntry* end = nullptr;
}; };
class RobustDictIterator { class RobustDictIterator
{
public: public:
using value_type = detail::DictEntry; using value_type = detail::DictEntry;
using reference = detail::DictEntry&; using reference = detail::DictEntry&;
@ -195,7 +200,7 @@ public:
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using iterator_category = std::forward_iterator_tag; using iterator_category = std::forward_iterator_tag;
RobustDictIterator() : curr(nullptr) {} RobustDictIterator() : curr(nullptr) { }
RobustDictIterator(Dictionary* d); RobustDictIterator(Dictionary* d);
RobustDictIterator(const RobustDictIterator& other); RobustDictIterator(const RobustDictIterator& other);
RobustDictIterator(RobustDictIterator&& other); RobustDictIterator(RobustDictIterator&& other);
@ -205,10 +210,15 @@ public:
pointer operator->() { return &curr; } pointer operator->() { return &curr; }
RobustDictIterator& operator++(); RobustDictIterator& operator++();
RobustDictIterator operator++(int) { auto temp(*this); ++*this; return temp; } RobustDictIterator operator++(int)
{
auto temp(*this);
++*this;
return temp;
}
bool operator==( const RobustDictIterator& that ) const { return curr == that.curr; } bool operator==(const RobustDictIterator& that) const { return curr == that.curr; }
bool operator!=( const RobustDictIterator& that ) const { return !(*this == that); } bool operator!=(const RobustDictIterator& that) const { return ! (*this == that); }
private: private:
friend class Dictionary; friend class Dictionary;
@ -225,7 +235,7 @@ private:
detail::DictEntry curr; detail::DictEntry curr;
Dictionary* dict = nullptr; Dictionary* dict = nullptr;
int next = -1; int next = -1;
}; };
/** /**
* A dictionary type that uses clustered hashing, a variation of Robinhood/Open Addressing * A dictionary type that uses clustered hashing, a variation of Robinhood/Open Addressing
@ -239,16 +249,18 @@ private:
* the keys but not the values. The dictionary size will be bounded at around 100K. 1M * the keys but not the values. The dictionary size will be bounded at around 100K. 1M
* entries is the absolute limit. Only Connections use that many entries, and that is rare. * entries is the absolute limit. Only Connections use that many entries, and that is rare.
*/ */
class Dictionary { class Dictionary
{
public: public:
explicit Dictionary(DictOrder ordering = UNORDERED, int initial_size = detail::DEFAULT_DICT_SIZE); explicit Dictionary(DictOrder ordering = UNORDERED,
int initial_size = detail::DEFAULT_DICT_SIZE);
~Dictionary(); ~Dictionary();
// Member functions for looking up a key, inserting/changing its // Member functions for looking up a key, inserting/changing its
// contents, and deleting it. These come in two flavors: one // contents, and deleting it. These come in two flavors: one
// which takes a zeek::detail::HashKey, and the other which takes a raw key, // which takes a zeek::detail::HashKey, and the other which takes a raw key,
// its size, and its (unmodulated) hash. // its size, and its (unmodulated) hash.
//lookup may move the key to right place if in the old zone to speed up the next lookup. // lookup may move the key to right place if in the old zone to speed up the next lookup.
void* Lookup(const detail::HashKey* key) const; void* Lookup(const detail::HashKey* key) const;
void* Lookup(const void* key, int key_size, detail::hash_t h) const; void* Lookup(const void* key, int key_size, detail::hash_t h) const;
@ -256,14 +268,17 @@ public:
// If iterators_invalidated is supplied, its value is set to true // If iterators_invalidated is supplied, its value is set to true
// if the removal may have invalidated any existing iterators. // if the removal may have invalidated any existing iterators.
void* Insert(detail::HashKey* key, void* val, bool* iterators_invalidated = nullptr) void* Insert(detail::HashKey* key, void* val, bool* iterators_invalidated = nullptr)
{ return Insert(key->TakeKey(), key->Size(), key->Hash(), val, false, iterators_invalidated); } {
return Insert(key->TakeKey(), key->Size(), key->Hash(), val, false, iterators_invalidated);
}
// If copy_key is true, then the key is copied, otherwise it's assumed // If copy_key is true, then the key is copied, otherwise it's assumed
// that it's a heap pointer that now belongs to the Dictionary to // that it's a heap pointer that now belongs to the Dictionary to
// manage as needed. // manage as needed.
// If iterators_invalidated is supplied, its value is set to true // If iterators_invalidated is supplied, its value is set to true
// if the removal may have invalidated any existing iterators. // if the removal may have invalidated any existing iterators.
void* Insert(void* key, int key_size, detail::hash_t hash, void* val, bool copy_key, bool* iterators_invalidated = nullptr); void* Insert(void* key, int key_size, detail::hash_t hash, void* val, bool copy_key,
bool* iterators_invalidated = nullptr);
// Removes the given element. Returns a pointer to the element in // Removes the given element. Returns a pointer to the element in
// case it needs to be deleted. Returns 0 if no such element exists. // case it needs to be deleted. Returns 0 if no such element exists.
@ -271,20 +286,20 @@ public:
// If iterators_invalidated is supplied, its value is set to true // If iterators_invalidated is supplied, its value is set to true
// if the removal may have invalidated any existing iterators. // if the removal may have invalidated any existing iterators.
void* Remove(const detail::HashKey* key, bool* iterators_invalidated = nullptr) void* Remove(const detail::HashKey* key, bool* iterators_invalidated = nullptr)
{ return Remove(key->Key(), key->Size(), key->Hash(), false, iterators_invalidated); } {
void* Remove(const void* key, int key_size, detail::hash_t hash, bool dont_delete = false, bool* iterators_invalidated = nullptr); return Remove(key->Key(), key->Size(), key->Hash(), false, iterators_invalidated);
}
void* Remove(const void* key, int key_size, detail::hash_t hash, bool dont_delete = false,
bool* iterators_invalidated = nullptr);
// Number of entries. // Number of entries.
int Length() const int Length() const { return num_entries; }
{ return num_entries; }
// Largest it's ever been. // Largest it's ever been.
int MaxLength() const int MaxLength() const { return max_entries; }
{ return max_entries; }
// Total number of entries ever. // Total number of entries ever.
uint64_t NumCumulativeInserts() const uint64_t NumCumulativeInserts() const { return cum_entries; }
{ return cum_entries; }
// True if the dictionary is ordered, false otherwise. // True if the dictionary is ordered, false otherwise.
int IsOrdered() const { return order != nullptr; } int IsOrdered() const { return order != nullptr; }
@ -316,12 +331,15 @@ public:
// //
// If return_hash is true, a HashKey for the entry is returned in h, // If return_hash is true, a HashKey for the entry is returned in h,
// which should be delete'd when no longer needed. // which should be delete'd when no longer needed.
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]] [[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
IterCookie* InitForIteration() const; "iteration.")]] IterCookie*
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]] InitForIteration() const;
void* NextEntry(detail::HashKey*& h, IterCookie*& cookie, bool return_hash) const; [[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]] "iteration.")]] void*
void StopIteration(IterCookie* cookie) const; NextEntry(detail::HashKey*& h, IterCookie*& cookie, bool return_hash) const;
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
"iteration.")]] void
StopIteration(IterCookie* cookie) const;
void SetDeleteFunc(dict_delete_func f) { delete_func = f; } void SetDeleteFunc(dict_delete_func f) { delete_func = f; }
@ -331,23 +349,25 @@ public:
// and (ii) we won't visit any still-unseen entries which are getting // and (ii) we won't visit any still-unseen entries which are getting
// removed. (We don't get this for free, so only use it if // removed. (We don't get this for free, so only use it if
// necessary.) // necessary.)
[[deprecated("Remove in v5.1. Use begin_robust() and the standard-library-compatible version of iteration.")]] [[deprecated("Remove in v5.1. Use begin_robust() and the standard-library-compatible version "
void MakeRobustCookie(IterCookie* cookie); "of iteration.")]] void
MakeRobustCookie(IterCookie* cookie);
// Remove all entries. // Remove all entries.
void Clear(); void Clear();
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
size_t MemoryAllocation() const; "GHI-572.")]] size_t
MemoryAllocation() const;
/// The capacity of the table, Buckets + Overflow Size. /// The capacity of the table, Buckets + Overflow Size.
int Capacity(bool expected = false) const; int Capacity(bool expected = false) const;
//Debugging // Debugging
#ifdef DEBUG #ifdef DEBUG
void AssertValid() const; void AssertValid() const;
#endif//DEBUG #endif // DEBUG
void Dump(int level=0) const; void Dump(int level = 0) const;
void DistanceStats(int& max_distance, int* distances = 0, int num_distances = 0) const; void DistanceStats(int& max_distance, int* distances = 0, int num_distances = 0) const;
void DumpKeys() const; void DumpKeys() const;
@ -362,12 +382,12 @@ public:
using reverse_iterator = std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
iterator begin() { return { this, table, table + Capacity() }; } iterator begin() { return {this, table, table + Capacity()}; }
iterator end() { return { this, table + Capacity(), table + Capacity() }; } iterator end() { return {this, table + Capacity(), table + Capacity()}; }
const_iterator begin() const { return { this, table, table + Capacity() }; } const_iterator begin() const { return {this, table, table + Capacity()}; }
const_iterator end() const { return { this, table + Capacity(), table + Capacity() }; } const_iterator end() const { return {this, table + Capacity(), table + Capacity()}; }
const_iterator cbegin() { return { this, table, table + Capacity() }; } const_iterator cbegin() { return {this, table, table + Capacity()}; }
const_iterator cend() { return { this, table + Capacity(), table + Capacity() }; } const_iterator cend() { return {this, table + Capacity(), table + Capacity()}; }
RobustDictIterator begin_robust() { return MakeRobustIterator(); } RobustDictIterator begin_robust() { return MakeRobustIterator(); }
RobustDictIterator end_robust() { return RobustDictIterator(); } RobustDictIterator end_robust() { return RobustDictIterator(); }
@ -380,7 +400,7 @@ private:
/// Buckets of the table, not including overflow size. /// Buckets of the table, not including overflow size.
int Buckets(bool expected = false) const; int Buckets(bool expected = false) const;
//bucket math // bucket math
int Log2(int num) const; int Log2(int num) const;
int ThresholdEntries() const; int ThresholdEntries() const;
@ -419,17 +439,20 @@ private:
void Init(); void Init();
// Iteration // Iteration
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]] [[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
IterCookie* InitForIterationNonConst(); "iteration.")]] IterCookie*
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]] InitForIterationNonConst();
void* NextEntryNonConst(detail::HashKey*& h, IterCookie*& cookie, bool return_hash); [[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]] "iteration.")]] void*
void StopIterationNonConst(IterCookie* cookie); NextEntryNonConst(detail::HashKey*& h, IterCookie*& cookie, bool return_hash);
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
"iteration.")]] void
StopIterationNonConst(IterCookie* cookie);
//Lookup // Lookup
int LinearLookupIndex(const void* key, int key_size, detail::hash_t hash) const; int LinearLookupIndex(const void* key, int key_size, detail::hash_t hash) const;
int LookupIndex(const void* key, int key_size, detail::hash_t hash, int* insert_position = nullptr, int LookupIndex(const void* key, int key_size, detail::hash_t hash,
int* insert_distance = nullptr); int* insert_position = nullptr, int* insert_distance = nullptr);
int LookupIndex(const void* key, int key_size, detail::hash_t hash, int begin, int end, int LookupIndex(const void* key, int key_size, detail::hash_t hash, int begin, int end,
int* insert_position = nullptr, int* insert_distance = nullptr); int* insert_position = nullptr, int* insert_distance = nullptr);
@ -437,29 +460,34 @@ private:
void InsertRelocateAndAdjust(detail::DictEntry& entry, int insert_position); void InsertRelocateAndAdjust(detail::DictEntry& entry, int insert_position);
/// insert entry into position, relocate other entries when necessary. /// insert entry into position, relocate other entries when necessary.
void InsertAndRelocate(detail::DictEntry& entry, int insert_position, int* last_affected_position = nullptr); void InsertAndRelocate(detail::DictEntry& entry, int insert_position,
int* last_affected_position = nullptr);
/// Adjust Cookies on Insert. /// Adjust Cookies on Insert.
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration and the version that takes a RobustDictIterator.")]] [[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration and the "
void AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, int insert_position, int last_affected_position); "version that takes a RobustDictIterator.")]] void
void AdjustOnInsert(RobustDictIterator* c, const detail::DictEntry& entry, AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, int insert_position,
int insert_position, int last_affected_position); int last_affected_position);
void AdjustOnInsert(RobustDictIterator* c, const detail::DictEntry& entry, int insert_position,
int last_affected_position);
///Remove, Relocate & Adjust cookies. /// Remove, Relocate & Adjust cookies.
detail::DictEntry RemoveRelocateAndAdjust(int position); detail::DictEntry RemoveRelocateAndAdjust(int position);
///Remove & Relocate /// Remove & Relocate
detail::DictEntry RemoveAndRelocate(int position, int* last_affected_position = nullptr); detail::DictEntry RemoveAndRelocate(int position, int* last_affected_position = nullptr);
///Adjust safe cookies after Removal of entry at position. /// Adjust safe cookies after Removal of entry at position.
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration and the version that takes a RobustDictIterator.")]] [[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration and the "
void AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, int position, int last_affected_position); "version that takes a RobustDictIterator.")]] void
void AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& entry, AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, int position,
int position, int last_affected_position); int last_affected_position);
void AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& entry, int position,
int last_affected_position);
bool Remapping() const { return remap_end >= 0;} //remap in reverse order. bool Remapping() const { return remap_end >= 0; } // remap in reverse order.
///One round of remap. /// One round of remap.
void Remap(); void Remap();
// Remap an item in position to a new position. Returns true if the relocation was // Remap an item in position to a new position. Returns true if the relocation was
@ -471,7 +499,9 @@ private:
bool HaveOnlyRobustIterators() const bool HaveOnlyRobustIterators() const
{ {
return (num_iterators == 0) || ((cookies ? cookies->size() : 0) + (iterators ? iterators->size() : 0) == num_iterators); return (num_iterators == 0) ||
((cookies ? cookies->size() : 0) + (iterators ? iterators->size() : 0) ==
num_iterators);
} }
RobustDictIterator MakeRobustIterator(); RobustDictIterator MakeRobustIterator();
@ -480,7 +510,7 @@ private:
void IncrIters() { ++num_iterators; } void IncrIters() { ++num_iterators; }
void DecrIters() { --num_iterators; } void DecrIters() { --num_iterators; }
//alligned on 8-bytes with 4-leading bytes. 7*8=56 bytes a dictionary. // alligned on 8-bytes with 4-leading bytes. 7*8=56 bytes a dictionary.
// when sizeup but the current mapping is in progress. the current mapping will be ignored // when sizeup but the current mapping is in progress. the current mapping will be ignored
// as it will be remapped to new dict size anyway. however, the missed count is recorded // as it will be remapped to new dict size anyway. however, the missed count is recorded
@ -507,58 +537,64 @@ private:
// Order means the order of insertion. means no deletion until exit. will be inefficient. // Order means the order of insertion. means no deletion until exit. will be inefficient.
std::vector<detail::DictEntry>* order = nullptr; std::vector<detail::DictEntry>* order = nullptr;
}; };
/* /*
* Template specialization of Dictionary that stores pointers for values. * Template specialization of Dictionary that stores pointers for values.
*/ */
template<typename T> template <typename T> class PDict : public Dictionary
class PDict : public Dictionary { {
public: public:
explicit PDict(DictOrder ordering = UNORDERED, int initial_size = 0) : explicit PDict(DictOrder ordering = UNORDERED, int initial_size = 0)
Dictionary(ordering, initial_size) {} : Dictionary(ordering, initial_size)
{
}
T* Lookup(const char* key) const T* Lookup(const char* key) const
{ {
detail::HashKey h(key); detail::HashKey h(key);
return (T*) Dictionary::Lookup(&h); return (T*)Dictionary::Lookup(&h);
} }
T* Lookup(const detail::HashKey* key) const T* Lookup(const detail::HashKey* key) const { return (T*)Dictionary::Lookup(key); }
{ return (T*) Dictionary::Lookup(key); }
T* Insert(const char* key, T* val, bool* iterators_invalidated = nullptr) T* Insert(const char* key, T* val, bool* iterators_invalidated = nullptr)
{ {
detail::HashKey h(key); detail::HashKey h(key);
return (T*) Dictionary::Insert(&h, (void*) val, iterators_invalidated); return (T*)Dictionary::Insert(&h, (void*)val, iterators_invalidated);
} }
T* Insert(detail::HashKey* key, T* val, bool* iterators_invalidated = nullptr) T* Insert(detail::HashKey* key, T* val, bool* iterators_invalidated = nullptr)
{ return (T*) Dictionary::Insert(key, (void*) val, iterators_invalidated); } {
T* NthEntry(int n) const return (T*)Dictionary::Insert(key, (void*)val, iterators_invalidated);
{ return (T*) Dictionary::NthEntry(n); } }
T* NthEntry(int n) const { return (T*)Dictionary::NthEntry(n); }
T* NthEntry(int n, const char*& key) const T* NthEntry(int n, const char*& key) const
{ {
int key_len; int key_len;
return (T*) Dictionary::NthEntry(n, (const void*&) key, key_len); return (T*)Dictionary::NthEntry(n, (const void*&)key, key_len);
} }
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] [[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] T*
T* NextEntry(IterCookie*& cookie) const NextEntry(IterCookie*& cookie) const
{ {
detail::HashKey* h; detail::HashKey* h;
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return (T*) Dictionary::NextEntry(h, cookie, false); return (T*)Dictionary::NextEntry(h, cookie, false);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] [[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] T*
T* NextEntry(detail::HashKey*& h, IterCookie*& cookie) const NextEntry(detail::HashKey*& h, IterCookie*& cookie) const
{ {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return (T*) Dictionary::NextEntry(h, cookie, true); return (T*)Dictionary::NextEntry(h, cookie, true);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
T* RemoveEntry(const detail::HashKey* key, bool* iterators_invalidated = nullptr) T* RemoveEntry(const detail::HashKey* key, bool* iterators_invalidated = nullptr)
{ return (T*) Remove(key->Key(), key->Size(), key->Hash(), false, iterators_invalidated); } {
return (T*)Remove(key->Key(), key->Size(), key->Hash(), false, iterators_invalidated);
}
T* RemoveEntry(const detail::HashKey& key, bool* iterators_invalidated = nullptr) T* RemoveEntry(const detail::HashKey& key, bool* iterators_invalidated = nullptr)
{ return (T*) Remove(key.Key(), key.Size(), key.Hash(), false, iterators_invalidated); } {
}; return (T*)Remove(key.Key(), key.Size(), key.Hash(), false, iterators_invalidated);
}
};
} // namespace zeek } // namespace zeek

View file

@ -1,20 +1,20 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Discard.h" #include "zeek/Discard.h"
#include <algorithm> #include <algorithm>
#include "zeek/ZeekString.h"
#include "zeek/RunState.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/Var.h"
#include "zeek/Val.h"
#include "zeek/IP.h" #include "zeek/IP.h"
#include "zeek/Reporter.h" // for InterpreterException #include "zeek/Reporter.h" // for InterpreterException
#include "zeek/RunState.h"
#include "zeek/Val.h"
#include "zeek/Var.h"
#include "zeek/ZeekString.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
Discarder::Discarder() Discarder::Discarder()
{ {
@ -26,9 +26,7 @@ Discarder::Discarder()
discarder_maxlen = static_cast<int>(id::find_val("discarder_maxlen")->AsCount()); discarder_maxlen = static_cast<int>(id::find_val("discarder_maxlen")->AsCount());
} }
Discarder::~Discarder() Discarder::~Discarder() { }
{
}
bool Discarder::IsActive() bool Discarder::IsActive()
{ {
@ -58,8 +56,7 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
} }
int proto = ip->NextProto(); int proto = ip->NextProto();
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && proto != IPPROTO_ICMP )
proto != IPPROTO_ICMP )
// This is not a protocol we understand. // This is not a protocol we understand.
return false; return false;
@ -74,9 +71,8 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
bool is_tcp = (proto == IPPROTO_TCP); bool is_tcp = (proto == IPPROTO_TCP);
bool is_udp = (proto == IPPROTO_UDP); bool is_udp = (proto == IPPROTO_UDP);
int min_hdr_len = is_tcp ? int min_hdr_len =
sizeof(struct tcphdr) : is_tcp ? sizeof(struct tcphdr) : (is_udp ? sizeof(struct udphdr) : sizeof(struct icmp));
(is_udp ? sizeof(struct udphdr) : sizeof(struct icmp));
if ( len < min_hdr_len || caplen < min_hdr_len ) if ( len < min_hdr_len || caplen < min_hdr_len )
// we don't have a complete protocol header // we don't have a complete protocol header
@ -90,7 +86,7 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
{ {
if ( check_tcp ) if ( check_tcp )
{ {
const struct tcphdr* tp = (const struct tcphdr*) data; const struct tcphdr* tp = (const struct tcphdr*)data;
int th_len = tp->th_off * 4; int th_len = tp->th_off * 4;
zeek::Args args{ zeek::Args args{
@ -114,8 +110,8 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
{ {
if ( check_udp ) if ( check_udp )
{ {
const struct udphdr* up = (const struct udphdr*) data; const struct udphdr* up = (const struct udphdr*)data;
int uh_len = sizeof (struct udphdr); int uh_len = sizeof(struct udphdr);
zeek::Args args{ zeek::Args args{
ip->ToPktHdrVal(), ip->ToPktHdrVal(),
@ -138,7 +134,7 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
{ {
if ( check_icmp ) if ( check_icmp )
{ {
const struct icmp* ih = (const struct icmp*) data; const struct icmp* ih = (const struct icmp*)data;
zeek::Args args{ip->ToPktHdrVal()}; zeek::Args args{ip->ToPktHdrVal()};
@ -168,4 +164,4 @@ Val* Discarder::BuildData(const u_char* data, int hdrlen, int len, int caplen)
return new StringVal(new String(data, len, true)); return new StringVal(new String(data, len, true));
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -7,16 +7,19 @@
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
namespace zeek { namespace zeek
{
class IP_Hdr; class IP_Hdr;
class Val; class Val;
class Func; class Func;
using FuncPtr = IntrusivePtr<Func>; using FuncPtr = IntrusivePtr<Func>;
namespace detail { namespace detail
{
class Discarder { class Discarder
{
public: public:
Discarder(); Discarder();
~Discarder(); ~Discarder();
@ -35,7 +38,7 @@ protected:
// Maximum amount of application data passed to filtering functions. // Maximum amount of application data passed to filtering functions.
int discarder_maxlen; int discarder_maxlen;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,12 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/EquivClass.h" #include "zeek/EquivClass.h"
#include "zeek/CCL.h" #include "zeek/CCL.h"
#include "zeek/util.h" #include "zeek/util.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
EquivClass::EquivClass(int arg_size) EquivClass::EquivClass(int arg_size)
{ {
@ -38,11 +39,11 @@ EquivClass::EquivClass(int arg_size)
EquivClass::~EquivClass() EquivClass::~EquivClass()
{ {
delete [] fwd; delete[] fwd;
delete [] bck; delete[] bck;
delete [] equiv_class; delete[] equiv_class;
delete [] rep; delete[] rep;
delete [] ccl_flags; delete[] ccl_flags;
} }
void EquivClass::ConvertCCL(CCL* ccl) void EquivClass::ConvertCCL(CCL* ccl)
@ -163,7 +164,6 @@ void EquivClass::CCL_Use(CCL* ccl)
} }
} }
void EquivClass::UniqueChar(int sym) void EquivClass::UniqueChar(int sym)
{ {
// If until now the character has been a proper subset of // If until now the character has been a proper subset of
@ -192,4 +192,4 @@ int EquivClass::Size() const
return padded_sizeof(*this) + util::pad_size(sizeof(int) * size * (ccl_flags ? 5 : 4)); return padded_sizeof(*this) + util::pad_size(sizeof(int) * size * (ccl_flags ? 5 : 4));
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -4,11 +4,13 @@
#include <stdio.h> #include <stdio.h>
namespace zeek::detail { namespace zeek::detail
{
class CCL; class CCL;
class EquivClass { class EquivClass
{
public: public:
explicit EquivClass(int size); explicit EquivClass(int size);
~EquivClass(); ~EquivClass();
@ -42,6 +44,6 @@ protected:
int* rep; // representative for symbol's equivalence class int* rep; // representative for symbol's equivalence class
int* ccl_flags; int* ccl_flags;
int ec_nil, no_class, no_rep; int ec_nil, no_class, no_rep;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,31 +1,27 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Event.h" #include "zeek/Event.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/RunState.h"
#include "zeek/Trigger.h" #include "zeek/Trigger.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/plugin/Manager.h"
#include "zeek/iosource/Manager.h" #include "zeek/iosource/Manager.h"
#include "zeek/iosource/PktSrc.h" #include "zeek/iosource/PktSrc.h"
#include "zeek/RunState.h" #include "zeek/plugin/Manager.h"
#include "zeek/zeek-config.h"
zeek::EventMgr zeek::event_mgr; zeek::EventMgr zeek::event_mgr;
zeek::EventMgr& mgr = zeek::event_mgr; zeek::EventMgr& mgr = zeek::event_mgr;
namespace zeek { namespace zeek
{
Event::Event(EventHandlerPtr arg_handler, zeek::Args arg_args, Event::Event(EventHandlerPtr arg_handler, zeek::Args arg_args, util::detail::SourceID arg_src,
util::detail::SourceID arg_src, analyzer::ID arg_aid, analyzer::ID arg_aid, Obj* arg_obj)
Obj* arg_obj) : handler(arg_handler), args(std::move(arg_args)), src(arg_src), aid(arg_aid), obj(arg_obj),
: handler(arg_handler),
args(std::move(arg_args)),
src(arg_src),
aid(arg_aid),
obj(arg_obj),
next_event(nullptr) next_event(nullptr)
{ {
if ( obj ) if ( obj )
@ -94,8 +90,7 @@ EventMgr::~EventMgr()
Unref(src_val); Unref(src_val);
} }
void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl, void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl, util::detail::SourceID src,
util::detail::SourceID src,
analyzer::ID aid, Obj* obj) analyzer::ID aid, Obj* obj)
{ {
QueueEvent(new Event(h, std::move(vl), src, aid, obj)); QueueEvent(new Event(h, std::move(vl), src, aid, obj));
@ -219,4 +214,4 @@ void EventMgr::InitPostScript()
reporter->FatalError("Failed to register event manager FD with iosource_mgr"); reporter->FatalError("Failed to register event manager FD with iosource_mgr");
} }
} // namespace zeek } // namespace zeek

View file

@ -5,18 +5,20 @@
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include "zeek/Flare.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/ZeekArgs.h"
#include "zeek/ZeekList.h" #include "zeek/ZeekList.h"
#include "zeek/analyzer/Analyzer.h" #include "zeek/analyzer/Analyzer.h"
#include "zeek/iosource/IOSource.h" #include "zeek/iosource/IOSource.h"
#include "zeek/Flare.h"
#include "zeek/ZeekArgs.h"
#include "zeek/IntrusivePtr.h"
namespace zeek { namespace zeek
{
class EventMgr; class EventMgr;
class Event final : public Obj { class Event final : public Obj
{
public: public:
Event(EventHandlerPtr handler, zeek::Args args, Event(EventHandlerPtr handler, zeek::Args args,
util::detail::SourceID src = util::detail::SOURCE_LOCAL, analyzer::ID aid = 0, util::detail::SourceID src = util::detail::SOURCE_LOCAL, analyzer::ID aid = 0,
@ -45,9 +47,10 @@ protected:
analyzer::ID aid; analyzer::ID aid;
Obj* obj; Obj* obj;
Event* next_event; Event* next_event;
}; };
class EventMgr final : public Obj, public iosource::IOSource { class EventMgr final : public Obj, public iosource::IOSource
{
public: public:
EventMgr(); EventMgr();
~EventMgr() override; ~EventMgr() override;
@ -72,11 +75,11 @@ public:
* A version of Enqueue() taking a variable number of arguments. * A version of Enqueue() taking a variable number of arguments.
*/ */
template <class... Args> template <class... Args>
std::enable_if_t< std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>>
std::is_convertible_v<
std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>>
Enqueue(const EventHandlerPtr& h, Args&&... args) Enqueue(const EventHandlerPtr& h, Args&&... args)
{ return Enqueue(h, zeek::Args{std::forward<Args>(args)...}); } {
return Enqueue(h, zeek::Args{std::forward<Args>(args)...});
}
void Dispatch(Event* event, bool no_remote = false); void Dispatch(Event* event, bool no_remote = false);
@ -92,8 +95,7 @@ public:
// non-analyzer event. // non-analyzer event.
analyzer::ID CurrentAnalyzer() const { return current_aid; } analyzer::ID CurrentAnalyzer() const { return current_aid; }
int Size() const int Size() const { return num_events_queued - num_events_dispatched; }
{ return num_events_queued - num_events_dispatched; }
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
@ -115,8 +117,8 @@ protected:
RecordVal* src_val; RecordVal* src_val;
bool draining; bool draining;
detail::Flare queue_flare; detail::Flare queue_flare;
}; };
extern EventMgr event_mgr; extern EventMgr event_mgr;
} // namespace zeek } // namespace zeek

View file

@ -1,17 +1,17 @@
#include "zeek/EventHandler.h" #include "zeek/EventHandler.h"
#include "zeek/Event.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Event.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/Scope.h"
#include "zeek/NetVar.h"
#include "zeek/ID.h" #include "zeek/ID.h"
#include "zeek/NetVar.h"
#include "zeek/Scope.h"
#include "zeek/Var.h" #include "zeek/Var.h"
#include "zeek/broker/Manager.h"
#include "zeek/broker/Data.h" #include "zeek/broker/Data.h"
#include "zeek/broker/Manager.h"
namespace zeek { namespace zeek
{
EventHandler::EventHandler(std::string arg_name) EventHandler::EventHandler(std::string arg_name)
{ {
@ -24,9 +24,7 @@ EventHandler::EventHandler(std::string arg_name)
EventHandler::operator bool() const EventHandler::operator bool() const
{ {
return enabled && ((local && local->HasBodies()) return enabled && ((local && local->HasBodies()) || generate_always || ! auto_publish.empty());
|| generate_always
|| ! auto_publish.empty());
} }
const FuncTypePtr& EventHandler::GetType(bool check_export) const FuncTypePtr& EventHandler::GetType(bool check_export)
@ -34,8 +32,8 @@ const FuncTypePtr& EventHandler::GetType(bool check_export)
if ( type ) if ( type )
return type; return type;
const auto& id = detail::lookup_ID(name.data(), detail::current_module.c_str(), const auto& id =
false, false, check_export); detail::lookup_ID(name.data(), detail::current_module.c_str(), false, false, check_export);
if ( ! id ) if ( ! id )
return FuncType::nil; return FuncType::nil;
@ -48,7 +46,9 @@ const FuncTypePtr& EventHandler::GetType(bool check_export)
} }
void EventHandler::SetFunc(FuncPtr f) void EventHandler::SetFunc(FuncPtr f)
{ local = std::move(f); } {
local = std::move(f);
}
void EventHandler::Call(Args* vl, bool no_remote) void EventHandler::Call(Args* vl, bool no_remote)
{ {
@ -85,7 +85,7 @@ void EventHandler::Call(Args* vl, bool no_remote)
if ( valid_args ) if ( valid_args )
{ {
for ( auto it = auto_publish.begin(); ; ) for ( auto it = auto_publish.begin();; )
{ {
const auto& topic = *it; const auto& topic = *it;
++it; ++it;
@ -125,4 +125,4 @@ void EventHandler::NewEvent(Args* vl)
event_mgr.Dispatch(ev); event_mgr.Dispatch(ev);
} }
} // namespace zeek } // namespace zeek

View file

@ -2,40 +2,35 @@
#pragma once #pragma once
#include <unordered_set>
#include <string> #include <string>
#include <unordered_set>
#include "zeek/ZeekList.h"
#include "zeek/ZeekArgs.h"
#include "zeek/Type.h" #include "zeek/Type.h"
#include "zeek/ZeekArgs.h"
#include "zeek/ZeekList.h"
namespace zeek { namespace zeek
{
class Func; class Func;
using FuncPtr = IntrusivePtr<Func>; using FuncPtr = IntrusivePtr<Func>;
class EventHandler { class EventHandler
{
public: public:
explicit EventHandler(std::string name); explicit EventHandler(std::string name);
const char* Name() { return name.data(); } const char* Name() { return name.data(); }
const FuncPtr& GetFunc() const FuncPtr& GetFunc() { return local; }
{ return local; }
const FuncTypePtr& GetType(bool check_export = true); const FuncTypePtr& GetType(bool check_export = true);
void SetFunc(FuncPtr f); void SetFunc(FuncPtr f);
void AutoPublish(std::string topic) void AutoPublish(std::string topic) { auto_publish.insert(std::move(topic)); }
{
auto_publish.insert(std::move(topic));
}
void AutoUnpublish(const std::string& topic) void AutoUnpublish(const std::string& topic) { auto_publish.erase(topic); }
{
auto_publish.erase(topic);
}
void Call(zeek::Args* vl, bool no_remote = false); void Call(zeek::Args* vl, bool no_remote = false);
@ -69,21 +64,27 @@ private:
bool generate_always; bool generate_always;
std::unordered_set<std::string> auto_publish; std::unordered_set<std::string> auto_publish;
}; };
// Encapsulates a ptr to an event handler to overload the boolean operator. // Encapsulates a ptr to an event handler to overload the boolean operator.
class EventHandlerPtr { class EventHandlerPtr
{
public: public:
EventHandlerPtr(EventHandler* p = nullptr) { handler = p; } EventHandlerPtr(EventHandler* p = nullptr) { handler = p; }
EventHandlerPtr(const EventHandlerPtr& h) { handler = h.handler; } EventHandlerPtr(const EventHandlerPtr& h) { handler = h.handler; }
const EventHandlerPtr& operator=(EventHandler* p) const EventHandlerPtr& operator=(EventHandler* p)
{ handler = p; return *this; } {
handler = p;
return *this;
}
const EventHandlerPtr& operator=(const EventHandlerPtr& h) const EventHandlerPtr& operator=(const EventHandlerPtr& h)
{ handler = h.handler; return *this; } {
handler = h.handler;
return *this;
}
bool operator==(const EventHandlerPtr& h) const bool operator==(const EventHandlerPtr& h) const { return handler == h.handler; }
{ return handler == h.handler; }
EventHandler* Ptr() { return handler; } EventHandler* Ptr() { return handler; }
@ -93,6 +94,6 @@ public:
private: private:
EventHandler* handler; EventHandler* handler;
}; };
} // namespace zeek } // namespace zeek

View file

@ -1,9 +1,10 @@
#include "zeek/EventLauncher.h"
#include "zeek/Conn.h"
#include "zeek/Event.h"
#include "zeek/File.h"
#include "zeek/NetVar.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/analyzer/Analyzer.h" #include "zeek/analyzer/Analyzer.h"
#include "zeek/EventLauncher.h"
#include "zeek/Event.h"
#include "zeek/NetVar.h"
#include "zeek/Conn.h"
#include "zeek/File.h"
#include "event.bif.func_def" #include "event.bif.func_def"

View file

@ -1,10 +1,12 @@
#include "zeek/EventRegistry.h" #include "zeek/EventRegistry.h"
#include "zeek/EventHandler.h" #include "zeek/EventHandler.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/RE.h" #include "zeek/RE.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
namespace zeek { namespace zeek
{
EventRegistry::EventRegistry() = default; EventRegistry::EventRegistry() = default;
EventRegistry::~EventRegistry() noexcept = default; EventRegistry::~EventRegistry() noexcept = default;
@ -103,9 +105,7 @@ void EventRegistry::PrintDebug()
{ {
EventHandler* v = entry.second.get(); EventHandler* v = entry.second.get();
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(), fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
v->GetFunc() ? "local" : "no", v->GetFunc() ? "local" : "no", *v ? "active" : "not active");
*v ? "active" : "not active"
);
} }
} }
@ -123,4 +123,4 @@ void EventRegistry::SetErrorHandler(std::string_view name)
std::string(name).c_str()); std::string(name).c_str());
} }
} // namespace zeek } // namespace zeek

View file

@ -2,22 +2,24 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <vector> #include <vector>
namespace zeek { #include "zeek/zeek-config.h"
namespace zeek
{
class EventHandler; class EventHandler;
class EventHandlerPtr; class EventHandlerPtr;
class RE_Matcher; class RE_Matcher;
// The registry keeps track of all events that we provide or handle. // The registry keeps track of all events that we provide or handle.
class EventRegistry { class EventRegistry
{
public: public:
EventRegistry(); EventRegistry();
~EventRegistry() noexcept; ~EventRegistry() noexcept;
@ -53,8 +55,8 @@ public:
private: private:
std::map<std::string, std::unique_ptr<EventHandler>, std::less<>> handlers; std::map<std::string, std::unique_ptr<EventHandler>, std::less<>> handlers;
}; };
extern EventRegistry* event_registry; extern EventRegistry* event_registry;
} // namespace zeek } // namespace zeek

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,37 +1,38 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/File.h" #include "zeek/File.h"
#include <sys/types.h> #include <sys/types.h>
#include "zeek/zeek-config.h"
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
# include <sys/time.h> #include <sys/time.h>
# include <time.h> #include <time.h>
#else #else
# ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
# include <sys/time.h> #include <sys/time.h>
# else #else
# include <time.h> #include <time.h>
# endif
#endif #endif
#endif
#include <errno.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include "zeek/Attr.h" #include "zeek/Attr.h"
#include "zeek/Type.h" #include "zeek/Desc.h"
#include "zeek/Event.h"
#include "zeek/Expr.h" #include "zeek/Expr.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/RunState.h"
#include "zeek/Event.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/Desc.h" #include "zeek/RunState.h"
#include "zeek/Type.h"
#include "zeek/Var.h" #include "zeek/Var.h"
namespace zeek { namespace zeek
{
std::list<std::pair<std::string, File*>> File::open_files; std::list<std::pair<std::string, File*>> File::open_files;
@ -159,8 +160,8 @@ File::~File()
Close(); Close();
Unref(attrs); Unref(attrs);
delete [] name; delete[] name;
delete [] access; delete[] access;
#ifdef USE_PERFTOOLS_DEBUG #ifdef USE_PERFTOOLS_DEBUG
heap_checker->UnIgnoreObject(this); heap_checker->UnIgnoreObject(this);
@ -231,7 +232,7 @@ bool File::Close()
void File::Unlink() void File::Unlink()
{ {
for ( auto it = open_files.begin(); it != open_files.end(); ++it) for ( auto it = open_files.begin(); it != open_files.end(); ++it )
{ {
if ( (*it).second == this ) if ( (*it).second == this )
{ {
@ -350,11 +351,11 @@ double File::Size()
FilePtr File::Get(const char* name) FilePtr File::Get(const char* name)
{ {
for ( const auto &el : open_files ) for ( const auto& el : open_files )
if ( el.first == name ) if ( el.first == name )
return {NewRef{}, el.second}; return {NewRef{}, el.second};
return make_intrusive<File>(name, "w"); return make_intrusive<File>(name, "w");
} }
} // namespace zeek } // namespace zeek

View file

@ -3,7 +3,6 @@
#pragma once #pragma once
#include <fcntl.h> #include <fcntl.h>
#include <list> #include <list>
#include <string> #include <string>
#include <utility> #include <utility>
@ -15,16 +14,18 @@
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek { namespace zeek
{
namespace detail { namespace detail
{
class PrintStmt; class PrintStmt;
class Attributes; class Attributes;
extern void do_print_stmt(const std::vector<ValPtr>& vals); extern void do_print_stmt(const std::vector<ValPtr>& vals);
} // namespace detail; } // namespace detail;
class RecordVal; class RecordVal;
class Type; class Type;
@ -33,7 +34,8 @@ using TypePtr = IntrusivePtr<Type>;
class File; class File;
using FilePtr = IntrusivePtr<File>; using FilePtr = IntrusivePtr<File>;
class File final : public Obj { class File final : public Obj
{
public: public:
explicit File(FILE* arg_f); explicit File(FILE* arg_f);
File(FILE* arg_f, const char* filename, const char* access); File(FILE* arg_f, const char* filename, const char* access);
@ -51,8 +53,7 @@ public:
void SetBuf(bool buffered); // false=line buffered, true=fully buffered void SetBuf(bool buffered); // false=line buffered, true=fully buffered
const TypePtr& GetType() const const TypePtr& GetType() const { return t; }
{ return t; }
// Whether the file is open in a general sense; it might // Whether the file is open in a general sense; it might
// not be open as a Unix file due to our management of // not be open as a Unix file due to our management of
@ -84,7 +85,6 @@ public:
bool IsRawOutput() const { return raw_output; } bool IsRawOutput() const { return raw_output; }
protected: protected:
friend void detail::do_print_stmt(const std::vector<ValPtr>& vals); friend void detail::do_print_stmt(const std::vector<ValPtr>& vals);
File() { Init(); } File() { Init(); }
@ -122,6 +122,6 @@ protected:
private: private:
static std::list<std::pair<std::string, File*>> open_files; static std::list<std::pair<std::string, File*>> open_files;
}; };
} // namespace zeek } // namespace zeek

View file

@ -2,18 +2,16 @@
#include "zeek/Flare.h" #include "zeek/Flare.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
namespace zeek::detail { namespace zeek::detail
Flare::Flare()
: pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK)
{ {
}
Flare::Flare() : pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK) { }
[[noreturn]] static void bad_pipe_op(const char* which, bool signal_safe) [[noreturn]] static void bad_pipe_op(const char* which, bool signal_safe)
{ {
@ -36,7 +34,7 @@ void Flare::Fire(bool signal_safe)
{ {
char tmp = 0; char tmp = 0;
for ( ; ; ) for ( ;; )
{ {
int n = write(pipe.WriteFD(), &tmp, 1); int n = write(pipe.WriteFD(), &tmp, 1);
@ -66,7 +64,7 @@ int Flare::Extinguish(bool signal_safe)
int rval = 0; int rval = 0;
char tmp[256]; char tmp[256];
for ( ; ; ) for ( ;; )
{ {
int n = read(pipe.ReadFD(), &tmp, sizeof(tmp)); int n = read(pipe.ReadFD(), &tmp, sizeof(tmp));
@ -91,4 +89,4 @@ int Flare::Extinguish(bool signal_safe)
return rval; return rval;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -4,11 +4,12 @@
#include "zeek/Pipe.h" #include "zeek/Pipe.h"
namespace zeek::detail { namespace zeek::detail
{
class Flare { class Flare
{
public: public:
/** /**
* Create a flare object that can be used to signal a "ready" status via * Create a flare object that can be used to signal a "ready" status via
* a file descriptor that may be integrated with select(), poll(), etc. * a file descriptor that may be integrated with select(), poll(), etc.
@ -41,6 +42,6 @@ public:
private: private:
Pipe pipe; Pipe pipe;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,19 +1,20 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Frag.h" #include "zeek/Frag.h"
#include "zeek/Hash.h" #include "zeek/Hash.h"
#include "zeek/IP.h" #include "zeek/IP.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/session/Manager.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/RunState.h" #include "zeek/RunState.h"
#include "zeek/session/Manager.h"
#include "zeek/zeek-config.h"
constexpr uint32_t MIN_ACCEPTABLE_FRAG_SIZE = 64; constexpr uint32_t MIN_ACCEPTABLE_FRAG_SIZE = 64;
constexpr uint32_t MAX_ACCEPTABLE_FRAG_SIZE = 64000; constexpr uint32_t MAX_ACCEPTABLE_FRAG_SIZE = 64000;
namespace zeek::detail { namespace zeek::detail
{
FragTimer::~FragTimer() FragTimer::~FragTimer()
{ {
@ -29,9 +30,8 @@ void FragTimer::Dispatch(double t, bool /* is_expire */)
reporter->InternalWarning("fragment timer dispatched w/o reassembler"); reporter->InternalWarning("fragment timer dispatched w/o reassembler");
} }
FragReassembler::FragReassembler(session::Manager* arg_s, FragReassembler::FragReassembler(session::Manager* arg_s, const std::unique_ptr<IP_Hdr>& ip,
const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt, const u_char* pkt, const FragReassemblerKey& k, double t)
const FragReassemblerKey& k, double t)
: Reassembler(0, REASSEM_FRAG) : Reassembler(0, REASSEM_FRAG)
{ {
s = arg_s; s = arg_s;
@ -43,7 +43,7 @@ FragReassembler::FragReassembler(session::Manager* arg_s,
proto_hdr_len = ip->HdrLen(); proto_hdr_len = ip->HdrLen();
proto_hdr = new u_char[64]; // max IP header + slop proto_hdr = new u_char[64]; // max IP header + slop
// Don't do a structure copy - need to pick up options, too. // Don't do a structure copy - need to pick up options, too.
memcpy((void*) proto_hdr, (const void*) ip4, proto_hdr_len); memcpy((void*)proto_hdr, (const void*)ip4, proto_hdr_len);
} }
else else
{ {
@ -70,11 +70,10 @@ FragReassembler::FragReassembler(session::Manager* arg_s,
FragReassembler::~FragReassembler() FragReassembler::~FragReassembler()
{ {
DeleteTimer(); DeleteTimer();
delete [] proto_hdr; delete[] proto_hdr;
} }
void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt)
const u_char* pkt)
{ {
const struct ip* ip4 = ip->IP4_Hdr(); const struct ip* ip4 = ip->IP4_Hdr();
@ -90,8 +89,7 @@ void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
} }
else else
{ {
if ( ip->NextProto() != next_proto || if ( ip->NextProto() != next_proto || ip->HdrLen() - 8 != proto_hdr_len )
ip->HdrLen() - 8 != proto_hdr_len )
s->Weird("fragment_protocol_inconsistency", ip.get()); s->Weird("fragment_protocol_inconsistency", ip.get());
// TODO: more detailed unfrag header consistency checks? // TODO: more detailed unfrag header consistency checks?
} }
@ -183,7 +181,7 @@ void FragReassembler::Weird(const char* name) const
void FragReassembler::Overlap(const u_char* b1, const u_char* b2, uint64_t n) void FragReassembler::Overlap(const u_char* b1, const u_char* b2, uint64_t n)
{ {
if ( memcmp((const void*) b1, (const void*) b2, n) ) if ( memcmp((const void*)b1, (const void*)b2, n) )
Weird("fragment_inconsistency"); Weird("fragment_inconsistency");
else else
Weird("fragment_overlap"); Weird("fragment_overlap");
@ -254,7 +252,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
// for a more recent one. // for a more recent one.
u_char* pkt = new u_char[n]; u_char* pkt = new u_char[n];
memcpy((void*) pkt, (const void*) proto_hdr, proto_hdr_len); memcpy((void*)pkt, (const void*)proto_hdr, proto_hdr_len);
u_char* pkt_start = pkt; u_char* pkt_start = pkt;
@ -280,7 +278,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
reporter->InternalWarning("bad fragment reassembly"); reporter->InternalWarning("bad fragment reassembly");
DeleteTimer(); DeleteTimer();
Expire(run_state::network_time); Expire(run_state::network_time);
delete [] pkt_start; delete[] pkt_start;
return; return;
} }
@ -293,7 +291,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
if ( version == 4 ) if ( version == 4 )
{ {
struct ip* reassem4 = (struct ip*) pkt_start; struct ip* reassem4 = (struct ip*)pkt_start;
reassem4->ip_len = htons(frag_size + proto_hdr_len); reassem4->ip_len = htons(frag_size + proto_hdr_len);
reassembled_pkt = std::make_unique<IP_Hdr>(reassem4, true, true); reassembled_pkt = std::make_unique<IP_Hdr>(reassem4, true, true);
DeleteTimer(); DeleteTimer();
@ -301,7 +299,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
else if ( version == 6 ) else if ( version == 6 )
{ {
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start; struct ip6_hdr* reassem6 = (struct ip6_hdr*)pkt_start;
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40); reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n); const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n);
reassembled_pkt = std::make_unique<IP_Hdr>(reassem6, true, n, chain, true); reassembled_pkt = std::make_unique<IP_Hdr>(reassem6, true, n, chain, true);
@ -310,9 +308,8 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
else else
{ {
reporter->InternalWarning("bad IP version in fragment reassembly: %d", reporter->InternalWarning("bad IP version in fragment reassembly: %d", version);
version); delete[] pkt_start;
delete [] pkt_start;
} }
} }
@ -388,4 +385,4 @@ uint32_t FragmentManager::MemoryAllocation() const
return fragments.size() * (sizeof(FragmentMap::key_type) + sizeof(FragmentMap::value_type)); return fragments.size() * (sizeof(FragmentMap::key_type) + sizeof(FragmentMap::value_type));
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -5,28 +5,34 @@
#include <sys/types.h> // for u_char #include <sys/types.h> // for u_char
#include <tuple> #include <tuple>
#include "zeek/util.h" // for bro_uint_t
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/Reassem.h" #include "zeek/Reassem.h"
#include "zeek/Timer.h" #include "zeek/Timer.h"
#include "zeek/util.h" // for bro_uint_t
namespace zeek { namespace zeek
{
class IP_Hdr; class IP_Hdr;
namespace session { class Manager; } namespace session
{
class Manager;
}
namespace detail { namespace detail
{
class FragReassembler; class FragReassembler;
class FragTimer; class FragTimer;
using FragReassemblerKey = std::tuple<IPAddr, IPAddr, bro_uint_t>; using FragReassemblerKey = std::tuple<IPAddr, IPAddr, bro_uint_t>;
class FragReassembler : public Reassembler { class FragReassembler : public Reassembler
{
public: public:
FragReassembler(session::Manager* s, const std::unique_ptr<IP_Hdr>& ip, FragReassembler(session::Manager* s, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt,
const u_char* pkt, const FragReassemblerKey& k, double t); const FragReassemblerKey& k, double t);
~FragReassembler() override; ~FragReassembler() override;
void AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt); void AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt);
@ -52,13 +58,12 @@ protected:
uint16_t proto_hdr_len; uint16_t proto_hdr_len;
FragTimer* expire_timer; FragTimer* expire_timer;
}; };
class FragTimer final : public Timer { class FragTimer final : public Timer
{
public: public:
FragTimer(FragReassembler* arg_f, double arg_t) FragTimer(FragReassembler* arg_f, double arg_t) : Timer(arg_t, TIMER_FRAG) { f = arg_f; }
: Timer(arg_t, TIMER_FRAG)
{ f = arg_f; }
~FragTimer() override; ~FragTimer() override;
void Dispatch(double t, bool is_expire) override; void Dispatch(double t, bool is_expire) override;
@ -68,45 +73,42 @@ public:
protected: protected:
FragReassembler* f; FragReassembler* f;
}; };
class FragmentManager { class FragmentManager
{
public: public:
FragmentManager() = default; FragmentManager() = default;
~FragmentManager(); ~FragmentManager();
FragReassembler* NextFragment(double t, const std::unique_ptr<IP_Hdr>& ip, FragReassembler* NextFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt);
const u_char* pkt);
void Clear(); void Clear();
void Remove(detail::FragReassembler* f); void Remove(detail::FragReassembler* f);
size_t Size() const { return fragments.size(); } size_t Size() const { return fragments.size(); }
size_t MaxFragments() const { return max_fragments; } size_t MaxFragments() const { return max_fragments; }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
uint32_t MemoryAllocation() const; "GHI-572.")]] uint32_t
MemoryAllocation() const;
private: private:
using FragmentMap = std::map<detail::FragReassemblerKey, detail::FragReassembler*>; using FragmentMap = std::map<detail::FragReassemblerKey, detail::FragReassembler*>;
FragmentMap fragments; FragmentMap fragments;
size_t max_fragments = 0; size_t max_fragments = 0;
}; };
extern FragmentManager* fragment_mgr; extern FragmentManager* fragment_mgr;
class FragReassemblerTracker { class FragReassemblerTracker
{
public: public:
FragReassemblerTracker(FragReassembler* f) FragReassemblerTracker(FragReassembler* f) : frag_reassembler(f) { }
: frag_reassembler(f)
{ }
~FragReassemblerTracker() ~FragReassemblerTracker() { fragment_mgr->Remove(frag_reassembler); }
{ fragment_mgr->Remove(frag_reassembler); }
private: private:
FragReassembler* frag_reassembler; FragReassembler* frag_reassembler;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -4,16 +4,17 @@
#include <broker/error.hh> #include <broker/error.hh>
#include "zeek/broker/Data.h"
#include "zeek/Func.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Func.h"
#include "zeek/ID.h"
#include "zeek/Trigger.h" #include "zeek/Trigger.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/ID.h" #include "zeek/broker/Data.h"
std::vector<zeek::detail::Frame*> g_frame_stack; std::vector<zeek::detail::Frame*> g_frame_stack;
namespace zeek::detail { namespace zeek::detail
{
Frame::Frame(int arg_size, const ScriptFunc* func, const zeek::Args* fn_args) Frame::Frame(int arg_size, const ScriptFunc* func, const zeek::Args* fn_args)
{ {
@ -37,8 +38,7 @@ Frame::Frame(int arg_size, const ScriptFunc* func, const zeek::Args* fn_args)
// go away until the function itself goes away, which can only be // go away until the function itself goes away, which can only be
// after this frame does. // after this frame does.
captures = function ? function->GetCapturesFrame() : nullptr; captures = function ? function->GetCapturesFrame() : nullptr;
captures_offset_map = captures_offset_map = function ? function->GetCapturesOffsetMap() : nullptr;
function ? function->GetCapturesOffsetMap() : nullptr;
current_offset = 0; current_offset = 0;
} }
@ -270,7 +270,8 @@ Frame* Frame::SelectiveClone(const IDPList& selection, ScriptFunc* func) const
} }
if ( ! frame[id->Offset() + current_offset].val ) if ( ! frame[id->Offset() + current_offset].val )
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name()); reporter->InternalError("Attempted to clone an id ('%s') with no associated value.",
id->Name());
CloneNonFuncElement(id->Offset(), func, other); CloneNonFuncElement(id->Offset(), func, other);
} }
@ -334,7 +335,8 @@ broker::expected<broker::data> Frame::SerializeClosureFrame(const IDPList& selec
if ( them.length() ) if ( them.length() )
{ {
if ( ! closure ) if ( ! closure )
reporter->InternalError("Attempting to serialize values from a frame that does not exist."); reporter->InternalError(
"Attempting to serialize values from a frame that does not exist.");
rval.emplace_back(std::string("ClosureFrame")); rval.emplace_back(std::string("ClosureFrame"));
@ -380,7 +382,7 @@ broker::expected<broker::data> Frame::SerializeClosureFrame(const IDPList& selec
if ( ! expected ) if ( ! expected )
return broker::ec::invalid_data; return broker::ec::invalid_data;
broker::vector val_tuple {std::move(*expected), static_cast<broker::integer>(tag)}; broker::vector val_tuple{std::move(*expected), static_cast<broker::integer>(tag)};
body[location] = val_tuple; body[location] = val_tuple;
} }
@ -404,8 +406,7 @@ broker::expected<broker::data> Frame::SerializeCopyFrame()
return broker::ec::invalid_data; return broker::ec::invalid_data;
TypeTag tag = val->GetType()->Tag(); TypeTag tag = val->GetType()->Tag();
broker::vector val_tuple {std::move(*expected), broker::vector val_tuple{std::move(*expected), static_cast<broker::integer>(tag)};
static_cast<broker::integer>(tag)};
body.emplace_back(std::move(val_tuple)); body.emplace_back(std::move(val_tuple));
} }
@ -458,7 +459,7 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
return std::make_pair(false, nullptr); return std::make_pair(false, nullptr);
broker::integer g = *has_type; broker::integer g = *has_type;
Type t( static_cast<TypeTag>(g) ); Type t(static_cast<TypeTag>(g));
auto val = Broker::detail::data_to_val(std::move(val_tuple[0]), &t); auto val = Broker::detail::data_to_val(std::move(val_tuple[0]), &t);
if ( ! val ) if ( ! val )
@ -470,7 +471,6 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
return std::make_pair(true, std::move(rf)); return std::make_pair(true, std::move(rf));
} }
// Code to support deprecated semantics: // Code to support deprecated semantics:
IDPList outer_ids; IDPList outer_ids;
@ -572,7 +572,7 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
return std::make_pair(false, nullptr); return std::make_pair(false, nullptr);
broker::integer g = *has_type; broker::integer g = *has_type;
Type t( static_cast<TypeTag>(g) ); Type t(static_cast<TypeTag>(g));
auto val = Broker::detail::data_to_val(std::move(val_tuple[0]), &t); auto val = Broker::detail::data_to_val(std::move(val_tuple[0]), &t);
if ( ! val ) if ( ! val )
@ -590,7 +590,7 @@ void Frame::AddKnownOffsets(const IDPList& ids)
offset_map = std::make_unique<OffsetMap>(); offset_map = std::make_unique<OffsetMap>();
std::transform(ids.begin(), ids.end(), std::inserter(*offset_map, offset_map->end()), std::transform(ids.begin(), ids.end(), std::inserter(*offset_map, offset_map->end()),
[] (const ID* id) -> std::pair<std::string, int> [](const ID* id) -> std::pair<std::string, int>
{ {
return std::make_pair(std::string(id->Name()), id->Offset()); return std::make_pair(std::string(id->Name()), id->Offset());
}); });
@ -643,7 +643,10 @@ void Frame::ClearElement(int n)
bool Frame::IsOuterID(const ID* in) const bool Frame::IsOuterID(const ID* in) const
{ {
return std::any_of(outer_ids.begin(), outer_ids.end(), return std::any_of(outer_ids.begin(), outer_ids.end(),
[&in](ID* id)-> bool { return strcmp(id->Name(), in->Name()) == 0; }); [&in](ID* id) -> bool
{
return strcmp(id->Name(), in->Name()) == 0;
});
} }
broker::expected<broker::data> Frame::SerializeIDList(const IDPList& in) broker::expected<broker::data> Frame::SerializeIDList(const IDPList& in)
@ -661,20 +664,21 @@ broker::expected<broker::data> Frame::SerializeIDList(const IDPList& in)
return {std::move(rval)}; return {std::move(rval)};
} }
broker::expected<broker::data> broker::expected<broker::data> Frame::SerializeOffsetMap(const OffsetMap& in)
Frame::SerializeOffsetMap(const OffsetMap& in)
{ {
broker::vector rval; broker::vector rval;
std::for_each(in.begin(), in.end(), std::for_each(in.begin(), in.end(),
[&rval] (const std::pair<std::string, int>& e) [&rval](const std::pair<std::string, int>& e)
{ rval.emplace_back(e.first); rval.emplace_back(e.second);}); {
rval.emplace_back(e.first);
rval.emplace_back(e.second);
});
return {std::move(rval)}; return {std::move(rval)};
} }
std::pair<bool, IDPList> std::pair<bool, IDPList> Frame::UnserializeIDList(const broker::vector& data)
Frame::UnserializeIDList(const broker::vector& data)
{ {
IDPList rval; IDPList rval;
if ( data.size() % 2 != 0 ) if ( data.size() % 2 != 0 )
@ -725,14 +729,14 @@ Frame::UnserializeOffsetMap(const broker::vector& data)
if ( ! key ) if ( ! key )
return std::make_pair(false, std::move(rval)); return std::make_pair(false, std::move(rval));
auto offset = broker::get_if<broker::integer>(data[i+1]); auto offset = broker::get_if<broker::integer>(data[i + 1]);
if ( ! offset ) if ( ! offset )
return std::make_pair(false, std::move(rval)); return std::make_pair(false, std::move(rval));
rval.insert( {std::move(*key), std::move(*offset)} ); rval.insert({std::move(*key), std::move(*offset)});
} }
return std::make_pair(true, std::move(rval)); return std::make_pair(true, std::move(rval));
} }
} }

View file

@ -2,43 +2,46 @@
#pragma once #pragma once
#include <unordered_map>
#include <string>
#include <utility>
#include <vector>
#include <memory>
#include <optional>
#include <broker/data.hh> #include <broker/data.hh>
#include <broker/expected.hh> #include <broker/expected.hh>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "zeek/ZeekList.h" // for typedef val_list #include "zeek/IntrusivePtr.h"
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/Type.h" #include "zeek/Type.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/ZeekArgs.h" #include "zeek/ZeekArgs.h"
#include "zeek/ZeekList.h" // for typedef val_list
namespace zeek { namespace zeek
{
using ValPtr = IntrusivePtr<Val>; using ValPtr = IntrusivePtr<Val>;
namespace detail { namespace detail
{
class CallExpr; class CallExpr;
class ScriptFunc; class ScriptFunc;
using IDPtr = IntrusivePtr<ID>; using IDPtr = IntrusivePtr<ID>;
namespace trigger { namespace trigger
{
class Trigger; class Trigger;
using TriggerPtr = IntrusivePtr<Trigger>; using TriggerPtr = IntrusivePtr<Trigger>;
} }
class Frame; class Frame;
using FramePtr = IntrusivePtr<Frame>; using FramePtr = IntrusivePtr<Frame>;
class Frame : public Obj { class Frame : public Obj
{
public: public:
/** /**
* Constructs a new frame belonging to *func* with *fn_args* * Constructs a new frame belonging to *func* with *fn_args*
@ -83,8 +86,7 @@ public:
* @param v the value to associate it with * @param v the value to associate it with
*/ */
void SetElement(const ID* id, ValPtr v); void SetElement(const ID* id, ValPtr v);
void SetElement(const IDPtr& id, ValPtr v) void SetElement(const IDPtr& id, ValPtr v) { SetElement(id.get(), std::move(v)); }
{ SetElement(id.get(), std::move(v)); }
/** /**
* Gets the value associated with *id* and returns it. Returns * Gets the value associated with *id* and returns it. Returns
@ -93,8 +95,7 @@ public:
* @param id the id who's value to retreive * @param id the id who's value to retreive
* @return the value associated with *id* * @return the value associated with *id*
*/ */
const ValPtr& GetElementByID(const IDPtr& id) const const ValPtr& GetElementByID(const IDPtr& id) const { return GetElementByID(id.get()); }
{ return GetElementByID(id.get()); }
/** /**
* Adjusts the current offset being used for frame accesses. * Adjusts the current offset being used for frame accesses.
@ -148,14 +149,11 @@ public:
Stmt* GetNextStmt() const { return next_stmt; } Stmt* GetNextStmt() const { return next_stmt; }
/** Used to implement "next" command in debugger. */ /** Used to implement "next" command in debugger. */
void BreakBeforeNextStmt(bool should_break) void BreakBeforeNextStmt(bool should_break) { break_before_next_stmt = should_break; }
{ break_before_next_stmt = should_break; } bool BreakBeforeNextStmt() const { return break_before_next_stmt; }
bool BreakBeforeNextStmt() const
{ return break_before_next_stmt; }
/** Used to implement "finish" command in debugger. */ /** Used to implement "finish" command in debugger. */
void BreakOnReturn(bool should_break) void BreakOnReturn(bool should_break) { break_on_return = should_break; }
{ break_on_return = should_break; }
bool BreakOnReturn() const { return break_on_return; } bool BreakOnReturn() const { return break_on_return; }
/** /**
@ -233,8 +231,8 @@ public:
* reflects captures with copy-semantics rather than deprecated * reflects captures with copy-semantics rather than deprecated
* reference semantics. * reference semantics.
*/ */
static std::pair<bool, FramePtr> Unserialize(const broker::vector& data, static std::pair<bool, FramePtr>
const std::optional<FuncType::CaptureList>& captures); Unserialize(const broker::vector& data, const std::optional<FuncType::CaptureList>& captures);
/** /**
* Sets the IDs that the frame knows offsets for. These offsets will * Sets the IDs that the frame knows offsets for. These offsets will
@ -279,10 +277,10 @@ public:
void AddFunctionWithClosureRef(ScriptFunc* func); void AddFunctionWithClosureRef(ScriptFunc* func);
private: private:
using OffsetMap = std::unordered_map<std::string, int>; using OffsetMap = std::unordered_map<std::string, int>;
struct Element { struct Element
{
ValPtr val; ValPtr val;
// Weak reference is used to prevent circular reference memory leaks // Weak reference is used to prevent circular reference memory leaks
// in lambdas/closures. // in lambdas/closures.
@ -321,20 +319,17 @@ private:
bool IsCaptureID(const ID* in) const; bool IsCaptureID(const ID* in) const;
/** Serializes an offset_map */ /** Serializes an offset_map */
static broker::expected<broker::data> static broker::expected<broker::data> SerializeOffsetMap(const OffsetMap& in);
SerializeOffsetMap(const OffsetMap& in);
/** Serializes an IDPList */ /** Serializes an IDPList */
static broker::expected<broker::data> static broker::expected<broker::data> SerializeIDList(const IDPList& in);
SerializeIDList(const IDPList& in);
/** Unserializes an offset map. */ /** Unserializes an offset map. */
static std::pair<bool, std::unordered_map<std::string, int>> static std::pair<bool, std::unordered_map<std::string, int>>
UnserializeOffsetMap(const broker::vector& data); UnserializeOffsetMap(const broker::vector& data);
/** Unserializes an IDPList. */ /** Unserializes an IDPList. */
static std::pair<bool, IDPList> static std::pair<bool, IDPList> UnserializeIDList(const broker::vector& data);
UnserializeIDList(const broker::vector& data);
/** The number of vals that can be stored in this frame. */ /** The number of vals that can be stored in this frame. */
int size; int size;
@ -395,10 +390,10 @@ private:
const Location* call_loc = nullptr; // only needed if call is nil const Location* call_loc = nullptr; // only needed if call is nil
std::unique_ptr<std::vector<ScriptFunc*>> functions_with_closure_frame_reference; std::unique_ptr<std::vector<ScriptFunc*>> functions_with_closure_frame_reference;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek
/** /**
* If we stopped using this and instead just made a struct of the information * If we stopped using this and instead just made a struct of the information

View file

@ -1,59 +1,55 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include "zeek/zeek-config.h"
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
# include <sys/time.h> #include <sys/time.h>
# include <time.h> #include <time.h>
#else #else
# ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
# include <sys/time.h> #include <sys/time.h>
# else #else
# include <time.h> #include <time.h>
# endif #endif
#endif #endif
#include <sys/resource.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <sys/param.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <algorithm>
#include <broker/error.hh> #include <broker/error.hh>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <unistd.h>
#include <algorithm>
#include "zeek/Base64.h" #include "zeek/Base64.h"
#include "zeek/Debug.h" #include "zeek/Debug.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Event.h"
#include "zeek/Expr.h" #include "zeek/Expr.h"
#include "zeek/Stmt.h"
#include "zeek/Scope.h"
#include "zeek/RunState.h"
#include "zeek/NetVar.h"
#include "zeek/File.h" #include "zeek/File.h"
#include "zeek/Frame.h" #include "zeek/Frame.h"
#include "zeek/NetVar.h"
#include "zeek/RE.h"
#include "zeek/Reporter.h"
#include "zeek/RunState.h"
#include "zeek/Scope.h"
#include "zeek/Stmt.h"
#include "zeek/Traverse.h"
#include "zeek/Var.h" #include "zeek/Var.h"
#include "zeek/analyzer/protocol/tcp/TCP.h" #include "zeek/analyzer/protocol/tcp/TCP.h"
#include "zeek/session/Manager.h"
#include "zeek/RE.h"
#include "zeek/Event.h"
#include "zeek/Traverse.h"
#include "zeek/Reporter.h"
#include "zeek/plugin/Manager.h"
#include "zeek/module_util.h"
#include "zeek/iosource/PktSrc.h"
#include "zeek/iosource/PktDumper.h" #include "zeek/iosource/PktDumper.h"
#include "zeek/iosource/PktSrc.h"
#include "zeek/module_util.h"
#include "zeek/plugin/Manager.h"
#include "zeek/session/Manager.h"
// Ignore clang-format's reordering of include files here so that it doesn't // Ignore clang-format's reordering of include files here so that it doesn't
// break what symbols are available when, which keeps the build from breaking. // break what symbols are available when, which keeps the build from breaking.
@ -79,14 +75,16 @@
extern RETSIGTYPE sig_handler(int signo); extern RETSIGTYPE sig_handler(int signo);
namespace zeek::detail { namespace zeek::detail
{
std::vector<CallInfo> call_stack; std::vector<CallInfo> call_stack;
bool did_builtin_init = false; bool did_builtin_init = false;
std::vector<void (*)()> bif_initializers; std::vector<void (*)()> bif_initializers;
static const std::pair<bool, zeek::ValPtr> empty_hook_result(false, nullptr); static const std::pair<bool, zeek::ValPtr> empty_hook_result(false, nullptr);
} // namespace zeek::detail } // namespace zeek::detail
namespace zeek { namespace zeek
{
std::string render_call_stack() std::string render_call_stack()
{ {
@ -149,8 +147,8 @@ Func::Func(Kind arg_kind) : kind(arg_kind)
Func::~Func() = default; Func::~Func() = default;
void Func::AddBody(detail::StmtPtr /* new_body */, void Func::AddBody(detail::StmtPtr /* new_body */,
const std::vector<detail::IDPtr>& /* new_inits */, const std::vector<detail::IDPtr>& /* new_inits */, size_t /* new_frame_size */,
size_t /* new_frame_size */, int /* priority */) int /* priority */)
{ {
Internal("Func::AddBody called"); Internal("Func::AddBody called");
} }
@ -242,8 +240,7 @@ void Func::CopyStateInto(Func* other) const
other->unique_id = unique_id; other->unique_id = unique_id;
} }
void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const
FunctionFlavor flavor) const
{ {
// Helper function factoring out this code from ScriptFunc:Call() for // Helper function factoring out this code from ScriptFunc:Call() for
// better readability. // better readability.
@ -251,14 +248,16 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
if ( ! handled ) if ( ! handled )
{ {
if ( hook_result ) if ( hook_result )
reporter->InternalError("plugin set processed flag to false but actually returned a value"); reporter->InternalError(
"plugin set processed flag to false but actually returned a value");
// The plugin result hasn't been processed yet (read: fall // The plugin result hasn't been processed yet (read: fall
// into ::Call method). // into ::Call method).
return; return;
} }
switch ( flavor ) { switch ( flavor )
{
case FUNC_FLAVOR_EVENT: case FUNC_FLAVOR_EVENT:
if ( hook_result ) if ( hook_result )
reporter->InternalError("plugin returned non-void result for event %s", reporter->InternalError("plugin returned non-void result for event %s",
@ -268,8 +267,7 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
case FUNC_FLAVOR_HOOK: case FUNC_FLAVOR_HOOK:
if ( hook_result->GetType()->Tag() != TYPE_BOOL ) if ( hook_result->GetType()->Tag() != TYPE_BOOL )
reporter->InternalError("plugin returned non-bool for hook %s", reporter->InternalError("plugin returned non-bool for hook %s", this->Name());
this->Name());
break; break;
@ -280,13 +278,15 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
if ( (! yt) || yt->Tag() == TYPE_VOID ) if ( (! yt) || yt->Tag() == TYPE_VOID )
{ {
if ( hook_result ) if ( hook_result )
reporter->InternalError("plugin returned non-void result for void method %s", reporter->InternalError(
this->Name()); "plugin returned non-void result for void method %s", this->Name());
} }
else if ( hook_result && hook_result->GetType()->Tag() != yt->Tag() && yt->Tag() != TYPE_ANY ) else if ( hook_result && hook_result->GetType()->Tag() != yt->Tag() &&
yt->Tag() != TYPE_ANY )
{ {
reporter->InternalError("plugin returned wrong type (got %d, expecting %d) for %s", reporter->InternalError(
"plugin returned wrong type (got %d, expecting %d) for %s",
hook_result->GetType()->Tag(), yt->Tag(), this->Name()); hook_result->GetType()->Tag(), yt->Tag(), this->Name());
} }
@ -295,10 +295,10 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
} }
} }
namespace detail { namespace detail
{
ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body, ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body, const std::vector<IDPtr>& aggr_inits,
const std::vector<IDPtr>& aggr_inits,
size_t arg_frame_size, int priority) size_t arg_frame_size, int priority)
: Func(SCRIPT_FUNC) : Func(SCRIPT_FUNC)
{ {
@ -316,8 +316,8 @@ ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body,
} }
} }
ScriptFunc::ScriptFunc(std::string _name, FuncTypePtr ft, ScriptFunc::ScriptFunc(std::string _name, FuncTypePtr ft, std::vector<StmtPtr> bs,
std::vector<StmtPtr> bs, std::vector<int> priorities) std::vector<int> priorities)
{ {
name = std::move(_name); name = std::move(_name);
frame_size = ft->ParamList()->GetTypes().size(); frame_size = ft->ParamList()->GetTypes().size();
@ -355,7 +355,10 @@ ScriptFunc::~ScriptFunc()
bool ScriptFunc::IsPure() const bool ScriptFunc::IsPure() const
{ {
return std::all_of(bodies.begin(), bodies.end(), return std::all_of(bodies.begin(), bodies.end(),
[](const Body& b) { return b.stmts->IsPure(); }); [](const Body& b)
{
return b.stmts->IsPure();
});
} }
ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
@ -368,9 +371,8 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
if ( sample_logger ) if ( sample_logger )
sample_logger->FunctionSeen(this); sample_logger->FunctionSeen(this);
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(
HookCallFunction(this, parent, args), HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
empty_hook_result);
CheckPluginResult(handled, hook_result, Flavor()); CheckPluginResult(handled, hook_result, Flavor());
@ -405,8 +407,8 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
ODesc d; ODesc d;
DescribeDebug(&d, args); DescribeDebug(&d, args);
g_trace_state.LogTrace("%s called: %s\n", g_trace_state.LogTrace("%s called: %s\n", GetType()->FlavorString().c_str(),
GetType()->FlavorString().c_str(), d.Description()); d.Description());
} }
StmtFlowType flow = FLOW_NEXT; StmtFlowType flow = FLOW_NEXT;
@ -486,8 +488,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
(flow != FLOW_RETURN /* we fell off the end */ || (flow != FLOW_RETURN /* we fell off the end */ ||
! result /* explicit return with no result */) && ! result /* explicit return with no result */) &&
! f->HasDelayed() ) ! f->HasDelayed() )
reporter->Warning("non-void function returning without a value: %s", reporter->Warning("non-void function returning without a value: %s", Name());
Name());
if ( result && g_trace_state.DoTrace() ) if ( result && g_trace_state.DoTrace() )
{ {
@ -552,8 +553,7 @@ void ScriptFunc::SetCaptures(Frame* f)
} }
} }
void ScriptFunc::AddBody(StmtPtr new_body, void ScriptFunc::AddBody(StmtPtr new_body, const std::vector<IDPtr>& new_inits,
const std::vector<IDPtr>& new_inits,
size_t new_frame_size, int priority) size_t new_frame_size, int priority)
{ {
if ( new_frame_size > frame_size ) if ( new_frame_size > frame_size )
@ -634,8 +634,7 @@ bool ScriptFunc::HasCopySemantics() const
void ScriptFunc::SetClosureFrame(Frame* f) void ScriptFunc::SetClosureFrame(Frame* f)
{ {
if ( closure ) if ( closure )
reporter->InternalError("Tried to override closure for ScriptFunc %s.", reporter->InternalError("Tried to override closure for ScriptFunc %s.", Name());
Name());
// Have to use weak references initially because otherwise Ref'ing the // Have to use weak references initially because otherwise Ref'ing the
// original frame creates a circular reference: the function holds a // original frame creates a circular reference: the function holds a
@ -674,14 +673,13 @@ bool ScriptFunc::DeserializeCaptures(const broker::vector& data)
{ {
auto result = Frame::Unserialize(data, GetType()->GetCaptures()); auto result = Frame::Unserialize(data, GetType()->GetCaptures());
ASSERT(result.first); ASSERT(result.first);
SetCaptures(result.second.release()); SetCaptures(result.second.release());
return true; return true;
} }
FuncPtr ScriptFunc::DoClone() FuncPtr ScriptFunc::DoClone()
{ {
// ScriptFunc could hold a closure. In this case a clone of it must // ScriptFunc could hold a closure. In this case a clone of it must
@ -726,9 +724,7 @@ void ScriptFunc::Describe(ODesc* d) const
} }
} }
StmtPtr ScriptFunc::AddInits( StmtPtr ScriptFunc::AddInits(StmtPtr body, const std::vector<IDPtr>& inits)
StmtPtr body,
const std::vector<IDPtr>& inits)
{ {
if ( inits.empty() ) if ( inits.empty() )
return body; return body;
@ -740,9 +736,8 @@ StmtPtr ScriptFunc::AddInits(
return stmt_series; return stmt_series;
} }
BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, bool arg_is_pure)
bool arg_is_pure) : Func(BUILTIN_FUNC)
: Func(BUILTIN_FUNC)
{ {
func = arg_func; func = arg_func;
name = make_full_var_name(GLOBAL_MODULE_NAME, arg_name); name = make_full_var_name(GLOBAL_MODULE_NAME, arg_name);
@ -759,9 +754,7 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
id->SetConst(); id->SetConst();
} }
BuiltinFunc::~BuiltinFunc() BuiltinFunc::~BuiltinFunc() { }
{
}
bool BuiltinFunc::IsPure() const bool BuiltinFunc::IsPure() const
{ {
@ -778,9 +771,8 @@ ValPtr BuiltinFunc::Invoke(Args* args, Frame* parent) const
if ( sample_logger ) if ( sample_logger )
sample_logger->FunctionSeen(this); sample_logger->FunctionSeen(this);
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(
HookCallFunction(this, parent, args), HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
empty_hook_result);
CheckPluginResult(handled, hook_result, FUNC_FLAVOR_FUNCTION); CheckPluginResult(handled, hook_result, FUNC_FLAVOR_FUNCTION);
@ -819,7 +811,7 @@ void BuiltinFunc::Describe(ODesc* d) const
bool check_built_in_call(BuiltinFunc* f, CallExpr* call) bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
{ {
if ( f->TheFunc() != BifFunc::fmt_bif) if ( f->TheFunc() != BifFunc::fmt_bif )
return true; return true;
const ExprPList& args = call->Args()->Exprs(); const ExprPList& args = call->Args()->Exprs();
@ -862,7 +854,8 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
if ( args.length() != num_fmt + 1 ) if ( args.length() != num_fmt + 1 )
{ {
call->Error("mismatch between format string to util::fmt() and number of arguments passed"); call->Error(
"mismatch between format string to util::fmt() and number of arguments passed");
return false; return false;
} }
} }
@ -933,8 +926,7 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
{ {
ODesc d; ODesc d;
arg->Describe(&d); arg->Describe(&d);
reporter->ExprRuntimeError(ce, "%s (%s), during call:", msg, reporter->ExprRuntimeError(ce, "%s (%s), during call:", msg, d.Description());
d.Description());
} }
else else
reporter->ExprRuntimeError(ce, "%s", msg); reporter->ExprRuntimeError(ce, "%s", msg);
@ -961,7 +953,6 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
} }
}; };
if ( call_stack.empty() ) if ( call_stack.empty() )
{ {
// Shouldn't happen unless someone (mistakenly) calls builtin_error() // Shouldn't happen unless someone (mistakenly) calls builtin_error()
@ -980,7 +971,9 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
} }
auto starts_with_double_underscore = [](const std::string& name) -> bool auto starts_with_double_underscore = [](const std::string& name) -> bool
{ return name.size() > 2 && name[0] == '_' && name[1] == '_'; }; {
return name.size() > 2 && name[0] == '_' && name[1] == '_';
};
std::string last_func = last_call.func->Name(); std::string last_func = last_call.func->Name();
auto pos = last_func.find_first_of("::"); auto pos = last_func.find_first_of("::");
@ -1055,21 +1048,20 @@ void init_primary_bifs()
var_sizes = id::find_type("var_sizes")->AsTableType(); var_sizes = id::find_type("var_sizes")->AsTableType();
#include "zeek.bif.func_init"
#include "stats.bif.func_init"
#include "reporter.bif.func_init"
#include "strings.bif.func_init"
#include "option.bif.func_init"
#include "supervisor.bif.func_init"
#include "packet_analysis.bif.func_init"
#include "CPP-load.bif.func_init" #include "CPP-load.bif.func_init"
#include "option.bif.func_init"
#include "packet_analysis.bif.func_init"
#include "reporter.bif.func_init"
#include "stats.bif.func_init"
#include "strings.bif.func_init"
#include "supervisor.bif.func_init"
#include "zeek.bif.func_init"
init_builtin_types(); init_builtin_types();
did_builtin_init = true; did_builtin_init = true;
} }
} // namespace detail } // namespace detail
void emit_builtin_error(const char* msg) void emit_builtin_error(const char* msg)
{ {
@ -1086,4 +1078,4 @@ void emit_builtin_error(const char* msg, Obj* arg)
zeek::detail::emit_builtin_error_common(msg, arg, false); zeek::detail::emit_builtin_error_common(msg, arg, false);
} }
} // namespace zeek } // namespace zeek

View file

@ -2,38 +2,42 @@
#pragma once #pragma once
#include <utility>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
#include <utility>
#include <vector>
#include "zeek/ZeekList.h" #include "zeek/BifReturnVal.h"
#include "zeek/Stmt.h"
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/Scope.h" #include "zeek/Scope.h"
#include "zeek/Type.h" /* for function_flavor */ #include "zeek/Stmt.h"
#include "zeek/TraverseTypes.h" #include "zeek/TraverseTypes.h"
#include "zeek/Type.h" /* for function_flavor */
#include "zeek/ZeekArgs.h" #include "zeek/ZeekArgs.h"
#include "zeek/BifReturnVal.h" #include "zeek/ZeekList.h"
namespace caf { namespace caf
{
template <class> class expected; template <class> class expected;
} }
namespace broker { namespace broker
{
class data; class data;
using vector = std::vector<data>; using vector = std::vector<data>;
using caf::expected; using caf::expected;
} }
namespace zeek { namespace zeek
{
class Val; class Val;
class FuncType; class FuncType;
namespace detail { namespace detail
{
class Scope; class Scope;
class Stmt; class Stmt;
@ -46,17 +50,21 @@ using StmtPtr = IntrusivePtr<Stmt>;
class ScriptFunc; class ScriptFunc;
} // namespace detail } // namespace detail
class Func; class Func;
using FuncPtr = IntrusivePtr<Func>; using FuncPtr = IntrusivePtr<Func>;
class Func : public Obj { class Func : public Obj
{
public: public:
static inline const FuncPtr nil; static inline const FuncPtr nil;
enum Kind { SCRIPT_FUNC, BUILTIN_FUNC }; enum Kind
{
SCRIPT_FUNC,
BUILTIN_FUNC
};
explicit Func(Kind arg_kind); explicit Func(Kind arg_kind);
@ -65,11 +73,14 @@ public:
virtual bool IsPure() const = 0; virtual bool IsPure() const = 0;
FunctionFlavor Flavor() const { return GetType()->Flavor(); } FunctionFlavor Flavor() const { return GetType()->Flavor(); }
struct Body { struct Body
{
detail::StmtPtr stmts; detail::StmtPtr stmts;
int priority; int priority;
bool operator<(const Body& other) const bool operator<(const Body& other) const
{ return priority > other.priority; } // reverse sort {
return priority > other.priority;
} // reverse sort
}; };
const std::vector<Body>& GetBodies() const { return bodies; } const std::vector<Body>& GetBodies() const { return bodies; }
@ -81,15 +92,13 @@ public:
* @param parent the frame from which the function is being called. * @param parent the frame from which the function is being called.
* @return the return value of the function call. * @return the return value of the function call.
*/ */
virtual ValPtr Invoke( virtual ValPtr Invoke(zeek::Args* args, detail::Frame* parent = nullptr) const = 0;
zeek::Args* args, detail::Frame* parent = nullptr) const = 0;
/** /**
* A version of Invoke() taking a variable number of individual arguments. * A version of Invoke() taking a variable number of individual arguments.
*/ */
template <class... Args> template <class... Args>
std::enable_if_t< std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>,
std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>,
ValPtr> ValPtr>
Invoke(Args&&... args) const Invoke(Args&&... args) const
{ {
@ -98,15 +107,13 @@ public:
} }
// Add a new event handler to an existing function (event). // Add a new event handler to an existing function (event).
virtual void AddBody(detail::StmtPtr new_body, virtual void AddBody(detail::StmtPtr new_body, const std::vector<detail::IDPtr>& new_inits,
const std::vector<detail::IDPtr>& new_inits,
size_t new_frame_size, int priority = 0); size_t new_frame_size, int priority = 0);
virtual void SetScope(detail::ScopePtr newscope); virtual void SetScope(detail::ScopePtr newscope);
virtual detail::ScopePtr GetScope() const { return scope; } virtual detail::ScopePtr GetScope() const { return scope; }
const FuncTypePtr& GetType() const const FuncTypePtr& GetType() const { return type; }
{ return type; }
Kind GetKind() const { return kind; } Kind GetKind() const { return kind; }
@ -122,7 +129,9 @@ public:
uint32_t GetUniqueFuncID() const { return unique_id; } uint32_t GetUniqueFuncID() const { return unique_id; }
static const FuncPtr& GetFuncPtrByID(uint32_t id) static const FuncPtr& GetFuncPtrByID(uint32_t id)
{ return id >= unique_ids.size() ? Func::nil : unique_ids[id]; } {
return id >= unique_ids.size() ? Func::nil : unique_ids[id];
}
protected: protected:
Func(); Func();
@ -131,8 +140,7 @@ protected:
void CopyStateInto(Func* other) const; void CopyStateInto(Func* other) const;
// Helper function for checking result of plugin hook. // Helper function for checking result of plugin hook.
void CheckPluginResult(bool handled, const ValPtr& hook_result, void CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const;
FunctionFlavor flavor) const;
std::vector<Body> bodies; std::vector<Body> bodies;
detail::ScopePtr scope; detail::ScopePtr scope;
@ -141,19 +149,20 @@ protected:
FuncTypePtr type; FuncTypePtr type;
std::string name; std::string name;
static inline std::vector<FuncPtr> unique_ids; static inline std::vector<FuncPtr> unique_ids;
}; };
namespace detail { namespace detail
{
class ScriptFunc : public Func { class ScriptFunc : public Func
{
public: public:
ScriptFunc(const IDPtr& id, StmtPtr body, ScriptFunc(const IDPtr& id, StmtPtr body, const std::vector<IDPtr>& inits, size_t frame_size,
const std::vector<IDPtr>& inits, int priority);
size_t frame_size, int priority);
// For compiled scripts. // For compiled scripts.
ScriptFunc(std::string name, FuncTypePtr ft, ScriptFunc(std::string name, FuncTypePtr ft, std::vector<StmtPtr> bodies,
std::vector<StmtPtr> bodies, std::vector<int> priorities); std::vector<int> priorities);
~ScriptFunc() override; ~ScriptFunc() override;
@ -186,8 +195,7 @@ public:
* *
* @return pointer to mapping of captures to slots * @return pointer to mapping of captures to slots
*/ */
const OffsetMap* GetCapturesOffsetMap() const const OffsetMap* GetCapturesOffsetMap() const { return captures_offset_mapping; }
{ return captures_offset_mapping; }
// The following "Closure" methods implement the deprecated // The following "Closure" methods implement the deprecated
// capture-by-reference functionality. // capture-by-reference functionality.
@ -233,9 +241,8 @@ public:
*/ */
bool DeserializeCaptures(const broker::vector& data); bool DeserializeCaptures(const broker::vector& data);
void AddBody(StmtPtr new_body, void AddBody(StmtPtr new_body, const std::vector<IDPtr>& new_inits, size_t new_frame_size,
const std::vector<IDPtr>& new_inits, int priority) override;
size_t new_frame_size, int priority) override;
/** /**
* Replaces the given current instance of a function body with * Replaces the given current instance of a function body with
@ -245,8 +252,7 @@ public:
* @param old_body Body to replace. * @param old_body Body to replace.
* @param new_body New body to use; can be nil. * @param new_body New body to use; can be nil.
*/ */
void ReplaceBody(const detail::StmtPtr& old_body, void ReplaceBody(const detail::StmtPtr& old_body, detail::StmtPtr new_body);
detail::StmtPtr new_body);
StmtPtr CurrentBody() const { return current_body; } StmtPtr CurrentBody() const { return current_body; }
int CurrentPriority() const { return current_priority; } int CurrentPriority() const { return current_priority; }
@ -266,17 +272,14 @@ public:
void SetFrameSize(int new_size) { frame_size = new_size; } void SetFrameSize(int new_size) { frame_size = new_size; }
/** Sets this function's outer_id list. */ /** Sets this function's outer_id list. */
void SetOuterIDs(IDPList ids) void SetOuterIDs(IDPList ids) { outer_ids = std::move(ids); }
{ outer_ids = std::move(ids); }
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
protected: protected:
ScriptFunc() : Func(SCRIPT_FUNC) {} ScriptFunc() : Func(SCRIPT_FUNC) { }
StmtPtr AddInits( StmtPtr AddInits(StmtPtr body, const std::vector<IDPtr>& inits);
StmtPtr body,
const std::vector<IDPtr>& inits);
/** /**
* Clones this function along with its closures. * Clones this function along with its closures.
@ -323,11 +326,12 @@ private:
// ... and its priority. // ... and its priority.
int current_priority = 0; int current_priority = 0;
}; };
using built_in_func = BifReturnVal (*)(Frame* frame, const Args* args); using built_in_func = BifReturnVal (*)(Frame* frame, const Args* args);
class BuiltinFunc final : public Func { class BuiltinFunc final : public Func
{
public: public:
BuiltinFunc(built_in_func func, const char* name, bool is_pure); BuiltinFunc(built_in_func func, const char* name, bool is_pure);
~BuiltinFunc() override; ~BuiltinFunc() override;
@ -339,23 +343,29 @@ public:
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
protected: protected:
BuiltinFunc() { func = nullptr; is_pure = 0; } BuiltinFunc()
{
func = nullptr;
is_pure = 0;
}
built_in_func func; built_in_func func;
bool is_pure; bool is_pure;
}; };
extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call); extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
struct CallInfo { struct CallInfo
{
const CallExpr* call; const CallExpr* call;
const Func* func; const Func* func;
const zeek::Args& args; const zeek::Args& args;
}; };
// Struct that collects all the specifics defining a Func. Used for ScriptFuncs // Struct that collects all the specifics defining a Func. Used for ScriptFuncs
// with closures. // with closures.
struct function_ingredients { struct function_ingredients
{
// Gathers all of the information from a scope and a function body needed // Gathers all of the information from a scope and a function body needed
// to build a function. // to build a function.
@ -367,7 +377,7 @@ struct function_ingredients {
int frame_size; int frame_size;
int priority; int priority;
ScopePtr scope; ScopePtr scope;
}; };
extern std::vector<CallInfo> call_stack; extern std::vector<CallInfo> call_stack;
@ -388,7 +398,7 @@ extern void emit_builtin_exception(const char* msg);
extern void emit_builtin_exception(const char* msg, const ValPtr& arg); extern void emit_builtin_exception(const char* msg, const ValPtr& arg);
extern void emit_builtin_exception(const char* msg, Obj* arg); extern void emit_builtin_exception(const char* msg, Obj* arg);
} // namespace detail } // namespace detail
extern std::string render_call_stack(); extern std::string render_call_stack();
@ -397,4 +407,4 @@ extern void emit_builtin_error(const char* msg);
extern void emit_builtin_error(const char* msg, const ValPtr&); extern void emit_builtin_error(const char* msg, const ValPtr&);
extern void emit_builtin_error(const char* msg, Obj* arg); extern void emit_builtin_error(const char* msg, Obj* arg);
} // namespace zeek } // namespace zeek

View file

@ -1,45 +1,56 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Hash.h" #include "zeek/Hash.h"
#include <highwayhash/sip_hash.h>
#include <highwayhash/highwayhash_target.h> #include <highwayhash/highwayhash_target.h>
#include <highwayhash/instruction_sets.h> #include <highwayhash/instruction_sets.h>
#include <highwayhash/sip_hash.h>
#include "zeek/digest.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/ZeekString.h"
#include "zeek/Val.h" // needed for const.bif #include "zeek/Val.h" // needed for const.bif
#include "zeek/ZeekString.h"
#include "zeek/digest.h"
#include "zeek/zeek-config.h"
#include "const.bif.netvar_h" #include "const.bif.netvar_h"
namespace zeek::detail { namespace zeek::detail
{
alignas(32) uint64_t KeyedHash::shared_highwayhash_key[4]; alignas(32) uint64_t KeyedHash::shared_highwayhash_key[4];
alignas(32) uint64_t KeyedHash::cluster_highwayhash_key[4]; alignas(32) uint64_t KeyedHash::cluster_highwayhash_key[4];
alignas(16) unsigned long long KeyedHash::shared_siphash_key[2]; alignas(16) unsigned long long KeyedHash::shared_siphash_key[2];
// we use the following lines to not pull in the highwayhash headers in Hash.h - but to check the types did not change underneath us. // we use the following lines to not pull in the highwayhash headers in Hash.h - but to check the
static_assert(std::is_same<hash64_t, highwayhash::HHResult64>::value, "Highwayhash return values must match hash_x_t"); // types did not change underneath us.
static_assert(std::is_same<hash128_t, highwayhash::HHResult128>::value, "Highwayhash return values must match hash_x_t"); static_assert(std::is_same<hash64_t, highwayhash::HHResult64>::value,
static_assert(std::is_same<hash256_t, highwayhash::HHResult256>::value, "Highwayhash return values must match hash_x_t"); "Highwayhash return values must match hash_x_t");
static_assert(std::is_same<hash128_t, highwayhash::HHResult128>::value,
"Highwayhash return values must match hash_x_t");
static_assert(std::is_same<hash256_t, highwayhash::HHResult256>::value,
"Highwayhash return values must match hash_x_t");
void KeyedHash::InitializeSeeds(const std::array<uint32_t, SEED_INIT_SIZE>& seed_data) void KeyedHash::InitializeSeeds(const std::array<uint32_t, SEED_INIT_SIZE>& seed_data)
{ {
static_assert(std::is_same<decltype(KeyedHash::shared_siphash_key), highwayhash::SipHashState::Key>::value, "Highwayhash Key is not unsigned long long[2]"); static_assert(std::is_same<decltype(KeyedHash::shared_siphash_key),
static_assert(std::is_same<decltype(KeyedHash::shared_highwayhash_key), highwayhash::HHKey>::value, "Highwayhash HHKey is not uint64_t[4]"); highwayhash::SipHashState::Key>::value,
"Highwayhash Key is not unsigned long long[2]");
static_assert(
std::is_same<decltype(KeyedHash::shared_highwayhash_key), highwayhash::HHKey>::value,
"Highwayhash HHKey is not uint64_t[4]");
if ( seeds_initialized ) if ( seeds_initialized )
return; return;
// leaving this at being generated by md5, allowing user scripts that use hmac_md5 functionality // leaving this at being generated by md5, allowing user scripts that use hmac_md5 functionality
// to get the same hash values as before. For now. // to get the same hash values as before. For now.
internal_md5((const u_char*) seed_data.data(), sizeof(seed_data) - 16, shared_hmac_md5_key); // The last 128 bits of buf are for siphash internal_md5((const u_char*)seed_data.data(), sizeof(seed_data) - 16,
// yes, we use the same buffer twice to initialize two different keys. This should not really be a shared_hmac_md5_key); // The last 128 bits of buf are for siphash
// security problem of any kind: hmac-md5 is not really used anymore - and even if it was, the hashes // yes, we use the same buffer twice to initialize two different keys. This should not really be
// should not reveal any information about their initialization vector. // a security problem of any kind: hmac-md5 is not really used anymore - and even if it was, the
// hashes should not reveal any information about their initialization vector.
static_assert(sizeof(shared_highwayhash_key) == SHA256_DIGEST_LENGTH); static_assert(sizeof(shared_highwayhash_key) == SHA256_DIGEST_LENGTH);
calculate_digest(Hash_SHA256, (const u_char*) seed_data.data(), sizeof(seed_data) - 16, reinterpret_cast<unsigned char*>(shared_highwayhash_key)); calculate_digest(Hash_SHA256, (const u_char*)seed_data.data(), sizeof(seed_data) - 16,
reinterpret_cast<unsigned char*>(shared_highwayhash_key));
memcpy(shared_siphash_key, reinterpret_cast<const char*>(seed_data.data()) + 64, 16); memcpy(shared_siphash_key, reinterpret_cast<const char*>(seed_data.data()) + 64, 16);
seeds_initialized = true; seeds_initialized = true;
@ -47,39 +58,45 @@ void KeyedHash::InitializeSeeds(const std::array<uint32_t, SEED_INIT_SIZE>& seed
void KeyedHash::InitOptions() void KeyedHash::InitOptions()
{ {
calculate_digest(Hash_SHA256, BifConst::digest_salt->Bytes(), BifConst::digest_salt->Len(), reinterpret_cast<unsigned char*>(cluster_highwayhash_key)); calculate_digest(Hash_SHA256, BifConst::digest_salt->Bytes(), BifConst::digest_salt->Len(),
reinterpret_cast<unsigned char*>(cluster_highwayhash_key));
} }
hash64_t KeyedHash::Hash64(const void* bytes, uint64_t size) hash64_t KeyedHash::Hash64(const void* bytes, uint64_t size)
{ {
return highwayhash::SipHash(shared_siphash_key, reinterpret_cast<const char *>(bytes), size); return highwayhash::SipHash(shared_siphash_key, reinterpret_cast<const char*>(bytes), size);
} }
void KeyedHash::Hash128(const void* bytes, uint64_t size, hash128_t* result) void KeyedHash::Hash128(const void* bytes, uint64_t size, hash128_t* result)
{ {
highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(shared_highwayhash_key, reinterpret_cast<const char *>(bytes), size, result); highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(
shared_highwayhash_key, reinterpret_cast<const char*>(bytes), size, result);
} }
void KeyedHash::Hash256(const void* bytes, uint64_t size, hash256_t* result) void KeyedHash::Hash256(const void* bytes, uint64_t size, hash256_t* result)
{ {
highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(shared_highwayhash_key, reinterpret_cast<const char *>(bytes), size, result); highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(
shared_highwayhash_key, reinterpret_cast<const char*>(bytes), size, result);
} }
hash64_t KeyedHash::StaticHash64(const void* bytes, uint64_t size) hash64_t KeyedHash::StaticHash64(const void* bytes, uint64_t size)
{ {
hash64_t result = 0; hash64_t result = 0;
highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(cluster_highwayhash_key, reinterpret_cast<const char *>(bytes), size, &result); highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(
cluster_highwayhash_key, reinterpret_cast<const char*>(bytes), size, &result);
return result; return result;
} }
void KeyedHash::StaticHash128(const void* bytes, uint64_t size, hash128_t* result) void KeyedHash::StaticHash128(const void* bytes, uint64_t size, hash128_t* result)
{ {
highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(cluster_highwayhash_key, reinterpret_cast<const char *>(bytes), size, result); highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(
cluster_highwayhash_key, reinterpret_cast<const char*>(bytes), size, result);
} }
void KeyedHash::StaticHash256(const void* bytes, uint64_t size, hash256_t* result) void KeyedHash::StaticHash256(const void* bytes, uint64_t size, hash256_t* result)
{ {
highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(cluster_highwayhash_key, reinterpret_cast<const char *>(bytes), size, result); highwayhash::InstructionSets::Run<highwayhash::HighwayHash>(
cluster_highwayhash_key, reinterpret_cast<const char*>(bytes), size, result);
} }
void init_hash_function() void init_hash_function()
@ -92,7 +109,7 @@ void init_hash_function()
HashKey::HashKey(bro_int_t i) HashKey::HashKey(bro_int_t i)
{ {
key_u.i = i; key_u.i = i;
key = (void*) &key_u; key = (void*)&key_u;
size = sizeof(i); size = sizeof(i);
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -100,7 +117,7 @@ HashKey::HashKey(bro_int_t i)
HashKey::HashKey(bro_uint_t u) HashKey::HashKey(bro_uint_t u)
{ {
key_u.i = bro_int_t(u); key_u.i = bro_int_t(u);
key = (void*) &key_u; key = (void*)&key_u;
size = sizeof(u); size = sizeof(u);
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -108,7 +125,7 @@ HashKey::HashKey(bro_uint_t u)
HashKey::HashKey(uint32_t u) HashKey::HashKey(uint32_t u)
{ {
key_u.u32 = u; key_u.u32 = u;
key = (void*) &key_u; key = (void*)&key_u;
size = sizeof(u); size = sizeof(u);
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -116,7 +133,7 @@ HashKey::HashKey(uint32_t u)
HashKey::HashKey(const uint32_t u[], int n) HashKey::HashKey(const uint32_t u[], int n)
{ {
size = n * sizeof(u[0]); size = n * sizeof(u[0]);
key = (void*) u; key = (void*)u;
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -128,7 +145,7 @@ HashKey::HashKey(double d)
} u; } u;
key_u.d = u.d = d; key_u.d = u.d = d;
key = (void*) &key_u; key = (void*)&key_u;
size = sizeof(d); size = sizeof(d);
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -136,7 +153,7 @@ HashKey::HashKey(double d)
HashKey::HashKey(const void* p) HashKey::HashKey(const void* p)
{ {
key_u.p = p; key_u.p = p;
key = (void*) &key_u; key = (void*)&key_u;
size = sizeof(p); size = sizeof(p);
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -144,14 +161,14 @@ HashKey::HashKey(const void* p)
HashKey::HashKey(const char* s) HashKey::HashKey(const char* s)
{ {
size = strlen(s); // note - skip final \0 size = strlen(s); // note - skip final \0
key = (void*) s; key = (void*)s;
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
HashKey::HashKey(const String* s) HashKey::HashKey(const String* s)
{ {
size = s->Len(); size = s->Len();
key = (void*) s->Bytes(); key = (void*)s->Bytes();
hash = HashBytes(key, size); hash = HashBytes(key, size);
} }
@ -162,7 +179,7 @@ HashKey::HashKey(int copy_key, void* arg_key, int arg_size)
if ( copy_key ) if ( copy_key )
{ {
key = (void*) new char[size]; key = (void*)new char[size];
memcpy(key, arg_key, size); memcpy(key, arg_key, size);
} }
else else
@ -179,8 +196,7 @@ HashKey::HashKey(const void* arg_key, int arg_size, hash_t arg_hash)
is_our_dynamic = true; is_our_dynamic = true;
} }
HashKey::HashKey(const void* arg_key, int arg_size, hash_t arg_hash, HashKey::HashKey(const void* arg_key, int arg_size, hash_t arg_hash, bool /* dont_copy */)
bool /* dont_copy */)
{ {
size = arg_size; size = arg_size;
hash = arg_hash; hash = arg_hash;
@ -208,7 +224,7 @@ void* HashKey::TakeKey()
void* HashKey::CopyKey(const void* k, int s) const void* HashKey::CopyKey(const void* k, int s) const
{ {
void* k_copy = (void*) new char[s]; void* k_copy = (void*)new char[s];
memcpy(k_copy, k, s); memcpy(k_copy, k, s);
return k_copy; return k_copy;
} }
@ -218,4 +234,4 @@ hash_t HashKey::HashBytes(const void* bytes, int size)
return KeyedHash::Hash64(bytes, size); return KeyedHash::Hash64(bytes, size);
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -9,12 +9,13 @@
* We use these kinds of hashes heavily internally - e.g. for scriptland hash generation. * We use these kinds of hashes heavily internally - e.g. for scriptland hash generation.
* It is important that these hashes are not easily guessable to prevent complexity attacks. * It is important that these hashes are not easily guessable to prevent complexity attacks.
* *
* The HashKey class is the actual class that is used to generate Hash keys that are used internally, * The HashKey class is the actual class that is used to generate Hash keys that are used
* e.g. for lookups in hash-tables; the Hashes are also used for connection ID generation. * internally, e.g. for lookups in hash-tables; the Hashes are also used for connection ID
* generation.
* *
* This means that the hashes created by most functions in this file will be different each run, unless * This means that the hashes created by most functions in this file will be different each run,
* a seed file is used. There are a few functions that create hashes that are static over runs * unless a seed file is used. There are a few functions that create hashes that are static over
* and use an installation-wide seed value; these are specifically called out. * runs and use an installation-wide seed value; these are specifically called out.
*/ */
#pragma once #pragma once
@ -26,26 +27,33 @@
// to allow bro_md5_hmac access to the hmac seed // to allow bro_md5_hmac access to the hmac seed
#include "zeek/ZeekArgs.h" #include "zeek/ZeekArgs.h"
namespace zeek { class String; } namespace zeek
namespace zeek::detail { {
class String;
}
namespace zeek::detail
{
class Frame; class Frame;
class BifReturnVal; class BifReturnVal;
} }
namespace zeek::BifFunc { namespace zeek::BifFunc
extern zeek::detail::BifReturnVal md5_hmac_bif(zeek::detail::Frame* frame, const zeek::Args*); {
} extern zeek::detail::BifReturnVal md5_hmac_bif(zeek::detail::Frame* frame, const zeek::Args*);
}
namespace zeek::detail { namespace zeek::detail
{
typedef uint64_t hash_t; typedef uint64_t hash_t;
typedef uint64_t hash64_t; typedef uint64_t hash64_t;
typedef uint64_t hash128_t[2]; typedef uint64_t hash128_t[2];
typedef uint64_t hash256_t[4]; typedef uint64_t hash256_t[4];
class KeyedHash { class KeyedHash
{
public: public:
/** /**
* Generate a 64 bit digest hash. * Generate a 64 bit digest hash.
@ -193,19 +201,23 @@ public:
private: private:
// actually HHKey. This key changes each start (unless a seed is specified) // actually HHKey. This key changes each start (unless a seed is specified)
alignas(32) static uint64_t shared_highwayhash_key[4]; alignas(32) static uint64_t shared_highwayhash_key[4];
// actually HHKey. This key is installation specific and sourced from the digest_salt script-level const. // actually HHKey. This key is installation specific and sourced from the digest_salt
// script-level const.
alignas(32) static uint64_t cluster_highwayhash_key[4]; alignas(32) static uint64_t cluster_highwayhash_key[4];
// actually HH_U64, which has the same type. This key changes each start (unless a seed is specified) // actually HH_U64, which has the same type. This key changes each start (unless a seed is
// specified)
alignas(16) static unsigned long long shared_siphash_key[2]; alignas(16) static unsigned long long shared_siphash_key[2];
// This key changes each start (unless a seed is specified) // This key changes each start (unless a seed is specified)
inline static uint8_t shared_hmac_md5_key[16]; inline static uint8_t shared_hmac_md5_key[16];
inline static bool seeds_initialized = false; inline static bool seeds_initialized = false;
friend void util::detail::hmac_md5(size_t size, const unsigned char* bytes, unsigned char digest[16]); friend void util::detail::hmac_md5(size_t size, const unsigned char* bytes,
unsigned char digest[16]);
friend BifReturnVal BifFunc::md5_hmac_bif(zeek::detail::Frame* frame, const Args*); friend BifReturnVal BifFunc::md5_hmac_bif(zeek::detail::Frame* frame, const Args*);
}; };
typedef enum { typedef enum
{
HASH_KEY_INT, HASH_KEY_INT,
HASH_KEY_DOUBLE, HASH_KEY_DOUBLE,
HASH_KEY_STRING HASH_KEY_STRING
@ -213,7 +225,8 @@ typedef enum {
constexpr int NUM_HASH_KEYS = HASH_KEY_STRING + 1; constexpr int NUM_HASH_KEYS = HASH_KEY_STRING + 1;
class HashKey { class HashKey
{
public: public:
explicit HashKey(bro_int_t i); explicit HashKey(bro_int_t i);
explicit HashKey(bro_uint_t u); explicit HashKey(bro_uint_t u);
@ -226,7 +239,7 @@ public:
~HashKey() ~HashKey()
{ {
if ( is_our_dynamic ) if ( is_our_dynamic )
delete [] (char *) key; delete[](char*) key;
} }
// Create a HashKey given all of its components. "key" is assumed // Create a HashKey given all of its components. "key" is assumed
@ -261,10 +274,15 @@ public:
int Size() const { return size; } int Size() const { return size; }
hash_t Hash() const { return hash; } hash_t Hash() const { return hash; }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const { return padded_sizeof(*this) + util::pad_size(size); } "GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this) + util::pad_size(size);
}
static hash_t HashBytes(const void* bytes, int size); static hash_t HashBytes(const void* bytes, int size);
protected: protected:
void* CopyKey(const void* key, int size) const; void* CopyKey(const void* key, int size) const;
@ -279,8 +297,8 @@ protected:
hash_t hash; hash_t hash;
int size; int size;
bool is_our_dynamic = false; bool is_our_dynamic = false;
}; };
extern void init_hash_function(); extern void init_hash_function();
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,28 +1,29 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/ID.h" #include "zeek/ID.h"
#include "zeek/Attr.h" #include "zeek/Attr.h"
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Expr.h"
#include "zeek/Dict.h" #include "zeek/Dict.h"
#include "zeek/EventRegistry.h" #include "zeek/EventRegistry.h"
#include "zeek/Expr.h"
#include "zeek/File.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/Scope.h" #include "zeek/Scope.h"
#include "zeek/Type.h"
#include "zeek/File.h"
#include "zeek/Traverse.h" #include "zeek/Traverse.h"
#include "zeek/Type.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/zeekygen/Manager.h"
#include "zeek/zeekygen/IdentifierInfo.h"
#include "zeek/zeekygen/ScriptInfo.h"
#include "zeek/zeekygen/utils.h"
#include "zeek/module_util.h" #include "zeek/module_util.h"
#include "zeek/script_opt/IDOptInfo.h" #include "zeek/script_opt/IDOptInfo.h"
#include "zeek/zeek-config.h"
#include "zeek/zeekygen/IdentifierInfo.h"
#include "zeek/zeekygen/Manager.h"
#include "zeek/zeekygen/ScriptInfo.h"
#include "zeek/zeekygen/utils.h"
namespace zeek { namespace zeek
{
RecordTypePtr id::conn_id; RecordTypePtr id::conn_id;
RecordTypePtr id::endpoint; RecordTypePtr id::endpoint;
@ -46,8 +47,7 @@ const TypePtr& id::find_type(std::string_view name)
auto id = zeek::detail::global_scope()->Find(name); auto id = zeek::detail::global_scope()->Find(name);
if ( ! id ) if ( ! id )
reporter->InternalError("Failed to find type named: %s", reporter->InternalError("Failed to find type named: %s", std::string(name).data());
std::string(name).data());
return id->GetType(); return id->GetType();
} }
@ -57,8 +57,7 @@ const ValPtr& id::find_val(std::string_view name)
auto id = zeek::detail::global_scope()->Find(name); auto id = zeek::detail::global_scope()->Find(name);
if ( ! id ) if ( ! id )
reporter->InternalError("Failed to find variable named: %s", reporter->InternalError("Failed to find variable named: %s", std::string(name).data());
std::string(name).data());
return id->GetVal(); return id->GetVal();
} }
@ -68,8 +67,7 @@ const ValPtr& id::find_const(std::string_view name)
auto id = zeek::detail::global_scope()->Find(name); auto id = zeek::detail::global_scope()->Find(name);
if ( ! id ) if ( ! id )
reporter->InternalError("Failed to find variable named: %s", reporter->InternalError("Failed to find variable named: %s", std::string(name).data());
std::string(name).data());
if ( ! id->IsConst() ) if ( ! id->IsConst() )
reporter->InternalError("Variable is not 'const', but expected to be: %s", reporter->InternalError("Variable is not 'const', but expected to be: %s",
@ -107,7 +105,8 @@ void id::detail::init_types()
index_vec = id::find_type<VectorType>("index_vec"); index_vec = id::find_type<VectorType>("index_vec");
} }
namespace detail { namespace detail
{
ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export) ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
{ {
@ -129,7 +128,7 @@ ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
ID::~ID() ID::~ID()
{ {
delete [] name; delete[] name;
delete opt_info; delete opt_info;
} }
@ -157,8 +156,7 @@ void ID::SetVal(ValPtr v)
UpdateValID(); UpdateValID();
#endif #endif
if ( type && val && if ( type && val && type->Tag() == TYPE_FUNC &&
type->Tag() == TYPE_FUNC &&
type->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT ) type->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT )
{ {
EventHandler* handler = event_registry->Lookup(name); EventHandler* handler = event_registry->Lookup(name);
@ -186,8 +184,7 @@ void ID::SetVal(ValPtr v, InitClass c)
return; return;
} }
if ( type->Tag() != TYPE_TABLE && if ( type->Tag() != TYPE_TABLE && (type->Tag() != TYPE_PATTERN || c == INIT_REMOVE) &&
(type->Tag() != TYPE_PATTERN || c == INIT_REMOVE) &&
(type->Tag() != TYPE_VECTOR || c == INIT_REMOVE) ) (type->Tag() != TYPE_VECTOR || c == INIT_REMOVE) )
{ {
if ( c == INIT_EXTRA ) if ( c == INIT_EXTRA )
@ -226,7 +223,8 @@ void ID::SetVal(ExprPtr ev, InitClass c)
if ( ! val ) if ( ! val )
{ {
Error(zeek::util::fmt("%s initializer applied to ID without value", Error(zeek::util::fmt("%s initializer applied to ID without value",
c == INIT_EXTRA ? "+=" : "-="), this); c == INIT_EXTRA ? "+=" : "-="),
this);
return; return;
} }
@ -373,8 +371,7 @@ TraversalCode ID::Traverse(TraversalCallback* cb) const
} }
// FIXME: Perhaps we should be checking at other than global scope. // FIXME: Perhaps we should be checking at other than global scope.
else if ( val && IsFunc(val->GetType()->Tag()) && else if ( val && IsFunc(val->GetType()->Tag()) && cb->current_scope == detail::global_scope() )
cb->current_scope == detail::global_scope() )
{ {
tc = val->AsFunc()->Traverse(cb); tc = val->AsFunc()->Traverse(cb);
HANDLE_TC_STMT_PRE(tc); HANDLE_TC_STMT_PRE(tc);
@ -448,7 +445,8 @@ void ID::DescribeReSTShort(ODesc* d) const
{ {
TypeTag t = type->Tag(); TypeTag t = type->Tag();
switch ( t ) { switch ( t )
{
case TYPE_TABLE: case TYPE_TABLE:
d->Add(type->IsSet() ? "set" : type_name(t)); d->Add(type->IsSet() ? "set" : type_name(t));
break; break;
@ -529,8 +527,7 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
{ {
auto ft = type->AsFuncType(); auto ft = type->AsFuncType();
if ( ft->Flavor() == FUNC_FLAVOR_EVENT || if ( ft->Flavor() == FUNC_FLAVOR_EVENT || ft->Flavor() == FUNC_FLAVOR_HOOK )
ft->Flavor() == FUNC_FLAVOR_HOOK )
{ {
const auto& protos = ft->Prototypes(); const auto& protos = ft->Prototypes();
@ -568,9 +565,7 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
d->NL(); d->NL();
} }
if ( val && type && if ( val && type && type->Tag() != TYPE_FUNC && type->InternalType() != TYPE_INTERNAL_VOID &&
type->Tag() != TYPE_FUNC &&
type->InternalType() != TYPE_INTERNAL_VOID &&
// Values within Version module are likely to include a // Values within Version module are likely to include a
// constantly-changing version number and be a frequent // constantly-changing version number and be a frequent
// source of error/desynchronization, so don't include them. // source of error/desynchronization, so don't include them.
@ -579,12 +574,12 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
d->Add(":Default:"); d->Add(":Default:");
auto ii = zeekygen_mgr->GetIdentifierInfo(Name()); auto ii = zeekygen_mgr->GetIdentifierInfo(Name());
auto redefs = ii->GetRedefs(); auto redefs = ii->GetRedefs();
const auto& iv = ! redefs.empty() && ii->InitialVal() ? ii->InitialVal() const auto& iv = ! redefs.empty() && ii->InitialVal() ? ii->InitialVal() : val;
: val;
if ( type->InternalType() == TYPE_INTERNAL_OTHER ) if ( type->InternalType() == TYPE_INTERNAL_OTHER )
{ {
switch ( type->Tag() ) { switch ( type->Tag() )
{
case TYPE_TABLE: case TYPE_TABLE:
if ( iv->AsTable()->Length() == 0 ) if ( iv->AsTable()->Length() == 0 )
{ {
@ -675,12 +670,11 @@ std::vector<Func*> ID::GetOptionHandlers() const
return v; return v;
} }
void IDOptInfo::AddInitExpr(ExprPtr init_expr) void IDOptInfo::AddInitExpr(ExprPtr init_expr)
{ {
init_exprs.emplace_back(std::move(init_expr)); init_exprs.emplace_back(std::move(init_expr));
} }
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -7,12 +7,13 @@
#include <string_view> #include <string_view>
#include <vector> #include <vector>
#include "zeek/Obj.h"
#include "zeek/Attr.h" #include "zeek/Attr.h"
#include "zeek/Notifier.h" #include "zeek/Notifier.h"
#include "zeek/Obj.h"
#include "zeek/TraverseTypes.h" #include "zeek/TraverseTypes.h"
namespace zeek { namespace zeek
{
class Func; class Func;
class Val; class Val;
@ -29,23 +30,36 @@ using EnumTypePtr = IntrusivePtr<EnumType>;
using ValPtr = IntrusivePtr<Val>; using ValPtr = IntrusivePtr<Val>;
using FuncPtr = IntrusivePtr<Func>; using FuncPtr = IntrusivePtr<Func>;
} }
namespace zeek::detail { namespace zeek::detail
{
class Attributes; class Attributes;
class Expr; class Expr;
using ExprPtr = IntrusivePtr<Expr>; using ExprPtr = IntrusivePtr<Expr>;
enum InitClass { INIT_NONE, INIT_FULL, INIT_EXTRA, INIT_REMOVE, }; enum InitClass
enum IDScope { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL }; {
INIT_NONE,
INIT_FULL,
INIT_EXTRA,
INIT_REMOVE,
};
enum IDScope
{
SCOPE_FUNCTION,
SCOPE_MODULE,
SCOPE_GLOBAL
};
class ID; class ID;
using IDPtr = IntrusivePtr<ID>; using IDPtr = IntrusivePtr<ID>;
class IDOptInfo; class IDOptInfo;
class ID final : public Obj, public notifier::detail::Modifiable { class ID final : public Obj, public notifier::detail::Modifiable
{
public: public:
static inline const IDPtr nil; static inline const IDPtr nil;
@ -65,15 +79,11 @@ public:
void SetType(TypePtr t); void SetType(TypePtr t);
const TypePtr& GetType() const const TypePtr& GetType() const { return type; }
{ return type; }
template <class T> template <class T> IntrusivePtr<T> GetType() const { return cast_intrusive<T>(type); }
IntrusivePtr<T> GetType() const
{ return cast_intrusive<T>(type); }
bool IsType() const bool IsType() const { return is_type; }
{ return is_type; }
void MakeType() { is_type = true; } void MakeType() { is_type = true; }
@ -84,8 +94,7 @@ public:
bool HasVal() const { return val != nullptr; } bool HasVal() const { return val != nullptr; }
const ValPtr& GetVal() const const ValPtr& GetVal() const { return val; }
{ return val; }
void ClearVal(); void ClearVal();
@ -108,8 +117,7 @@ public:
void RemoveAttr(AttrTag a); void RemoveAttr(AttrTag a);
void UpdateValAttrs(); void UpdateValAttrs();
const AttributesPtr& GetAttrs() const const AttributesPtr& GetAttrs() const { return attrs; }
{ return attrs; }
const AttrPtr& GetAttr(AttrTag t) const; const AttrPtr& GetAttr(AttrTag t) const;
@ -128,15 +136,12 @@ public:
void DescribeReST(ODesc* d, bool roles_only = false) const; void DescribeReST(ODesc* d, bool roles_only = false) const;
void DescribeReSTShort(ODesc* d) const; void DescribeReSTShort(ODesc* d) const;
bool DoInferReturnType() const bool DoInferReturnType() const { return infer_return_type; }
{ return infer_return_type; } void SetInferReturnType(bool infer) { infer_return_type = infer; }
void SetInferReturnType(bool infer)
{ infer_return_type = infer; }
virtual TraversalCode Traverse(TraversalCallback* cb) const; virtual TraversalCode Traverse(TraversalCallback* cb) const;
bool HasOptionHandlers() const bool HasOptionHandlers() const { return ! option_handlers.empty(); }
{ return !option_handlers.empty(); }
void AddOptionHandler(FuncPtr callback, int priority); void AddOptionHandler(FuncPtr callback, int priority);
std::vector<Func*> GetOptionHandlers() const; std::vector<Func*> GetOptionHandlers() const;
@ -168,12 +173,12 @@ protected:
// via the associated pointer, to allow it to be modified in // via the associated pointer, to allow it to be modified in
// contexts where the ID is itself "const". // contexts where the ID is itself "const".
IDOptInfo* opt_info; IDOptInfo* opt_info;
};
}; } // namespace zeek::detail
} // namespace zeek::detail namespace zeek::id
{
namespace zeek::id {
/** /**
* Lookup an ID in the global module and return it, if one exists; * Lookup an ID in the global module and return it, if one exists;
@ -197,9 +202,10 @@ const TypePtr& find_type(std::string_view name);
* @param name The identifier name to lookup * @param name The identifier name to lookup
* @return The type of the identifier. * @return The type of the identifier.
*/ */
template<class T> template <class T> IntrusivePtr<T> find_type(std::string_view name)
IntrusivePtr<T> find_type(std::string_view name) {
{ return cast_intrusive<T>(find_type(name)); } return cast_intrusive<T>(find_type(name));
}
/** /**
* Lookup an ID by its name and return its value. A fatal occurs if the ID * Lookup an ID by its name and return its value. A fatal occurs if the ID
@ -215,9 +221,10 @@ const ValPtr& find_val(std::string_view name);
* @param name The identifier name to lookup * @param name The identifier name to lookup
* @return The current value of the identifier. * @return The current value of the identifier.
*/ */
template<class T> template <class T> IntrusivePtr<T> find_val(std::string_view name)
IntrusivePtr<T> find_val(std::string_view name) {
{ return cast_intrusive<T>(find_val(name)); } return cast_intrusive<T>(find_val(name));
}
/** /**
* Lookup an ID by its name and return its value. A fatal occurs if the ID * Lookup an ID by its name and return its value. A fatal occurs if the ID
@ -233,9 +240,10 @@ const ValPtr& find_const(std::string_view name);
* @param name The identifier name to lookup * @param name The identifier name to lookup
* @return The current value of the identifier. * @return The current value of the identifier.
*/ */
template<class T> template <class T> IntrusivePtr<T> find_const(std::string_view name)
IntrusivePtr<T> find_const(std::string_view name) {
{ return cast_intrusive<T>(find_const(name)); } return cast_intrusive<T>(find_const(name));
}
/** /**
* Lookup an ID by its name and return the function it references. * Lookup an ID by its name and return the function it references.
@ -257,9 +265,10 @@ extern TableTypePtr count_set;
extern VectorTypePtr string_vec; extern VectorTypePtr string_vec;
extern VectorTypePtr index_vec; extern VectorTypePtr index_vec;
namespace detail { namespace detail
{
void init_types(); void init_types();
} // namespace detail } // namespace detail
} // namespace zeek::id } // namespace zeek::id

122
src/IP.cc
View file

@ -2,18 +2,19 @@
#include "zeek/IP.h" #include "zeek/IP.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
#include <netinet/in.h>
#include <sys/types.h>
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/Reporter.h"
#include "zeek/Type.h" #include "zeek/Type.h"
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/Var.h" #include "zeek/Var.h"
#include "zeek/ZeekString.h" #include "zeek/ZeekString.h"
#include "zeek/Reporter.h"
namespace zeek { namespace zeek
{
static VectorValPtr BuildOptionsVal(const u_char* data, int len) static VectorValPtr BuildOptionsVal(const u_char* data, int len)
{ {
@ -22,7 +23,7 @@ static VectorValPtr BuildOptionsVal(const u_char* data, int len)
while ( len > 0 ) while ( len > 0 )
{ {
static auto ip6_option_type = id::find_type<RecordType>("ip6_option"); static auto ip6_option_type = id::find_type<RecordType>("ip6_option");
const struct ip6_opt* opt = (const struct ip6_opt*) data; const struct ip6_opt* opt = (const struct ip6_opt*)data;
auto rv = make_intrusive<RecordVal>(ip6_option_type); auto rv = make_intrusive<RecordVal>(ip6_option_type);
rv->Assign(0, opt->ip6o_type); rv->Assign(0, opt->ip6o_type);
@ -54,13 +55,14 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
{ {
RecordValPtr rv; RecordValPtr rv;
switch ( type ) { switch ( type )
{
case IPPROTO_IPV6: case IPPROTO_IPV6:
{ {
static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr"); static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr");
rv = make_intrusive<RecordVal>(ip6_hdr_type); rv = make_intrusive<RecordVal>(ip6_hdr_type);
const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data;
rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000)>>20); rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000) >> 20);
rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff); rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff);
rv->Assign(2, ntohs(ip6->ip6_plen)); rv->Assign(2, ntohs(ip6->ip6_plen));
rv->Assign(3, ip6->ip6_nxt); rv->Assign(3, ip6->ip6_nxt);
@ -68,8 +70,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
rv->Assign(5, make_intrusive<AddrVal>(IPAddr(ip6->ip6_src))); rv->Assign(5, make_intrusive<AddrVal>(IPAddr(ip6->ip6_src)));
rv->Assign(6, make_intrusive<AddrVal>(IPAddr(ip6->ip6_dst))); rv->Assign(6, make_intrusive<AddrVal>(IPAddr(ip6->ip6_dst)));
if ( ! chain ) if ( ! chain )
chain = make_intrusive<VectorVal>( chain =
id::find_type<VectorType>("ip6_ext_hdr_chain")); make_intrusive<VectorVal>(id::find_type<VectorType>("ip6_ext_hdr_chain"));
rv->Assign(7, std::move(chain)); rv->Assign(7, std::move(chain));
} }
break; break;
@ -83,7 +85,6 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
rv->Assign(1, hbh->ip6h_len); rv->Assign(1, hbh->ip6h_len);
uint16_t off = 2 * sizeof(uint8_t); uint16_t off = 2 * sizeof(uint8_t);
rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); rv->Assign(2, BuildOptionsVal(data + off, Length() - off));
} }
break; break;
@ -120,8 +121,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
const struct ip6_frag* frag = (const struct ip6_frag*)data; const struct ip6_frag* frag = (const struct ip6_frag*)data;
rv->Assign(0, frag->ip6f_nxt); rv->Assign(0, frag->ip6f_nxt);
rv->Assign(1, frag->ip6f_reserved); rv->Assign(1, frag->ip6f_reserved);
rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8)>>3); rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8) >> 3);
rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006)>>1); rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006) >> 1);
rv->Assign(4, static_cast<bool>(ntohs(frag->ip6f_offlg) & 0x0001)); rv->Assign(4, static_cast<bool>(ntohs(frag->ip6f_offlg) & 0x0001));
rv->Assign(5, ntohl(frag->ip6f_ident)); rv->Assign(5, ntohl(frag->ip6f_ident));
} }
@ -161,7 +162,7 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
{ {
static auto ip6_mob_type = id::find_type<RecordType>("ip6_mobility_hdr"); static auto ip6_mob_type = id::find_type<RecordType>("ip6_mobility_hdr");
rv = make_intrusive<RecordVal>(ip6_mob_type); rv = make_intrusive<RecordVal>(ip6_mob_type);
const struct ip6_mobility* mob = (const struct ip6_mobility*) data; const struct ip6_mobility* mob = (const struct ip6_mobility*)data;
rv->Assign(0, mob->ip6mob_payload); rv->Assign(0, mob->ip6mob_payload);
rv->Assign(1, mob->ip6mob_len); rv->Assign(1, mob->ip6mob_len);
rv->Assign(2, mob->ip6mob_type); rv->Assign(2, mob->ip6mob_type);
@ -184,7 +185,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
static auto ip6_mob_back_type = id::find_type<RecordType>("ip6_mobility_back"); static auto ip6_mob_back_type = id::find_type<RecordType>("ip6_mobility_back");
static auto ip6_mob_be_type = id::find_type<RecordType>("ip6_mobility_be"); static auto ip6_mob_be_type = id::find_type<RecordType>("ip6_mobility_be");
switch ( mob->ip6mob_type ) { switch ( mob->ip6mob_type )
{
case 0: case 0:
{ {
auto m = make_intrusive<RecordVal>(ip6_mob_brr_type); auto m = make_intrusive<RecordVal>(ip6_mob_brr_type);
@ -222,7 +224,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
auto m = make_intrusive<RecordVal>(ip6_mob_hot_type); auto m = make_intrusive<RecordVal>(ip6_mob_hot_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data))); m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t)))));
m->Assign(2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) + sizeof(uint64_t))))); m->Assign(2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) +
sizeof(uint64_t)))));
off += sizeof(uint16_t) + 2 * sizeof(uint64_t); off += sizeof(uint16_t) + 2 * sizeof(uint64_t);
m->Assign(3, BuildOptionsVal(data + off, Length() - off)); m->Assign(3, BuildOptionsVal(data + off, Length() - off));
msg->Assign(4, std::move(m)); msg->Assign(4, std::move(m));
@ -234,7 +237,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
auto m = make_intrusive<RecordVal>(ip6_mob_cot_type); auto m = make_intrusive<RecordVal>(ip6_mob_cot_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data))); m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t)))));
m->Assign(2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) + sizeof(uint64_t))))); m->Assign(2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) +
sizeof(uint64_t)))));
off += sizeof(uint16_t) + 2 * sizeof(uint64_t); off += sizeof(uint16_t) + 2 * sizeof(uint64_t);
m->Assign(3, BuildOptionsVal(data + off, Length() - off)); m->Assign(3, BuildOptionsVal(data + off, Length() - off));
msg->Assign(5, std::move(m)); msg->Assign(5, std::move(m));
@ -245,11 +249,19 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
{ {
auto m = make_intrusive<RecordVal>(ip6_mob_bu_type); auto m = make_intrusive<RecordVal>(ip6_mob_bu_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data))); m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, static_cast<bool>(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x8000)); m->Assign(1, static_cast<bool>(
m->Assign(2, static_cast<bool>(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x4000)); ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) &
m->Assign(3, static_cast<bool>(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x2000)); 0x8000));
m->Assign(4, static_cast<bool>(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x1000)); m->Assign(2, static_cast<bool>(
m->Assign(5, ntohs(*((uint16_t*)(msg_data + 2*sizeof(uint16_t))))); ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) &
0x4000));
m->Assign(3, static_cast<bool>(
ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) &
0x2000));
m->Assign(4, static_cast<bool>(
ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) &
0x1000));
m->Assign(5, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t)))));
off += 3 * sizeof(uint16_t); off += 3 * sizeof(uint16_t);
m->Assign(6, BuildOptionsVal(data + off, Length() - off)); m->Assign(6, BuildOptionsVal(data + off, Length() - off));
msg->Assign(6, std::move(m)); msg->Assign(6, std::move(m));
@ -260,9 +272,10 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
{ {
auto m = make_intrusive<RecordVal>(ip6_mob_back_type); auto m = make_intrusive<RecordVal>(ip6_mob_back_type);
m->Assign(0, *((uint8_t*)msg_data)); m->Assign(0, *((uint8_t*)msg_data));
m->Assign(1, static_cast<bool>(*((uint8_t*)(msg_data + sizeof(uint8_t))) & 0x80)); m->Assign(1, static_cast<bool>(
*((uint8_t*)(msg_data + sizeof(uint8_t))) & 0x80));
m->Assign(2, ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t))))); m->Assign(2, ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))));
m->Assign(3, ntohs(*((uint16_t*)(msg_data + 2*sizeof(uint16_t))))); m->Assign(3, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t)))));
off += 3 * sizeof(uint16_t); off += 3 * sizeof(uint16_t);
m->Assign(4, BuildOptionsVal(data + off, Length() - off)); m->Assign(4, BuildOptionsVal(data + off, Length() - off));
msg->Assign(7, std::move(m)); msg->Assign(7, std::move(m));
@ -298,7 +311,9 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
} }
RecordValPtr IPv6_Hdr::ToVal() const RecordValPtr IPv6_Hdr::ToVal() const
{ return ToVal(nullptr); } {
return ToVal(nullptr);
}
IPAddr IP_Hdr::IPHeaderSrcAddr() const IPAddr IP_Hdr::IPHeaderSrcAddr() const
{ {
@ -366,10 +381,11 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
const u_char* data = Payload(); const u_char* data = Payload();
int proto = NextProto(); int proto = NextProto();
switch ( proto ) { switch ( proto )
{
case IPPROTO_TCP: case IPPROTO_TCP:
{ {
const struct tcphdr* tp = (const struct tcphdr*) data; const struct tcphdr* tp = (const struct tcphdr*)data;
auto tcp_hdr = make_intrusive<RecordVal>(tcp_hdr_type); auto tcp_hdr = make_intrusive<RecordVal>(tcp_hdr_type);
int tcp_hdr_len = tp->th_off * 4; int tcp_hdr_len = tp->th_off * 4;
@ -391,7 +407,7 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
case IPPROTO_UDP: case IPPROTO_UDP:
{ {
const struct udphdr* up = (const struct udphdr*) data; const struct udphdr* up = (const struct udphdr*)data;
auto udp_hdr = make_intrusive<RecordVal>(udp_hdr_type); auto udp_hdr = make_intrusive<RecordVal>(udp_hdr_type);
udp_hdr->Assign(0, val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP)); udp_hdr->Assign(0, val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP));
@ -404,7 +420,7 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
case IPPROTO_ICMP: case IPPROTO_ICMP:
{ {
const struct icmp* icmpp = (const struct icmp *) data; const struct icmp* icmpp = (const struct icmp*)data;
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type); auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, icmpp->icmp_type); icmp_hdr->Assign(0, icmpp->icmp_type);
@ -415,7 +431,7 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
{ {
const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*) data; const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*)data;
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type); auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, icmpp->icmp6_type); icmp_hdr->Assign(0, icmpp->icmp6_type);
@ -436,7 +452,8 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
static inline bool isIPv6ExtHeader(uint8_t type) static inline bool isIPv6ExtHeader(uint8_t type)
{ {
switch (type) { switch ( type )
{
case IPPROTO_HOPOPTS: case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING: case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS: case IPPROTO_DSTOPTS:
@ -452,18 +469,18 @@ static inline bool isIPv6ExtHeader(uint8_t type)
IPv6_Hdr_Chain::~IPv6_Hdr_Chain() IPv6_Hdr_Chain::~IPv6_Hdr_Chain()
{ {
for ( size_t i = 0; i < chain.size(); ++i ) delete chain[i]; for ( size_t i = 0; i < chain.size(); ++i )
delete chain[i];
delete homeAddr; delete homeAddr;
delete finalDst; delete finalDst;
} }
void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len, void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len, bool set_next, uint16_t next)
bool set_next, uint16_t next)
{ {
length = 0; length = 0;
uint8_t current_type, next_type; uint8_t current_type, next_type;
next_type = IPPROTO_IPV6; next_type = IPPROTO_IPV6;
const u_char* hdrs = (const u_char*) ip6; const u_char* hdrs = (const u_char*)ip6;
if ( total_len < (int)sizeof(struct ip6_hdr) ) if ( total_len < (int)sizeof(struct ip6_hdr) )
{ {
@ -501,20 +518,18 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len,
// Check for routing headers and remember final destination address. // Check for routing headers and remember final destination address.
if ( current_type == IPPROTO_ROUTING ) if ( current_type == IPPROTO_ROUTING )
ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, cur_len); ProcessRoutingHeader((const struct ip6_rthdr*)hdrs, cur_len);
// Only Mobile IPv6 has a destination option we care about right now. // Only Mobile IPv6 has a destination option we care about right now.
if ( current_type == IPPROTO_DSTOPTS ) if ( current_type == IPPROTO_DSTOPTS )
ProcessDstOpts((const struct ip6_dest*) hdrs, cur_len); ProcessDstOpts((const struct ip6_dest*)hdrs, cur_len);
hdrs += cur_len; hdrs += cur_len;
length += cur_len; length += cur_len;
total_len -= cur_len; total_len -= cur_len;
} while ( current_type != IPPROTO_FRAGMENT && } while ( current_type != IPPROTO_FRAGMENT && current_type != IPPROTO_ESP &&
current_type != IPPROTO_ESP && current_type != IPPROTO_MOBILITY && isIPv6ExtHeader(next_type) );
current_type != IPPROTO_MOBILITY &&
isIPv6ExtHeader(next_type) );
} }
bool IPv6_Hdr_Chain::IsFragment() const bool IPv6_Hdr_Chain::IsFragment() const
@ -525,7 +540,7 @@ bool IPv6_Hdr_Chain::IsFragment() const
return false; return false;
} }
return chain[chain.size()-1]->Type() == IPPROTO_FRAGMENT; return chain[chain.size() - 1]->Type() == IPPROTO_FRAGMENT;
} }
IPAddr IPv6_Hdr_Chain::SrcAddr() const IPAddr IPv6_Hdr_Chain::SrcAddr() const
@ -567,7 +582,8 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16_t le
// Last 16 bytes of header (for all known types) is the address we want. // Last 16 bytes of header (for all known types) is the address we want.
const in6_addr* addr = (const in6_addr*)(((const u_char*)r) + len - 16); const in6_addr* addr = (const in6_addr*)(((const u_char*)r) + len - 16);
switch ( r->ip6r_type ) { switch ( r->ip6r_type )
{
case 0: // Defined by RFC 2460, deprecated by RFC 5095 case 0: // Defined by RFC 2460, deprecated by RFC 5095
{ {
if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 ) if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 )
@ -610,14 +626,15 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
// https://datatracker.ietf.org/doc/html/rfc8200#section-4.6 // https://datatracker.ietf.org/doc/html/rfc8200#section-4.6
assert(len >= 2); assert(len >= 2);
const u_char* data = (const u_char*) d; const u_char* data = (const u_char*)d;
len -= 2 * sizeof(uint8_t); len -= 2 * sizeof(uint8_t);
data += 2* sizeof(uint8_t); data += 2 * sizeof(uint8_t);
while ( len > 0 ) while ( len > 0 )
{ {
const struct ip6_opt* opt = (const struct ip6_opt*) data; const struct ip6_opt* opt = (const struct ip6_opt*)data;
switch ( opt->ip6o_type ) { switch ( opt->ip6o_type )
{
case 0: case 0:
// If option type is zero, it's a Pad0 and can be just a single // If option type is zero, it's a Pad0 and can be just a single
// byte in width. Skip over it. // byte in width. Skip over it.
@ -637,14 +654,16 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
break; break;
} }
if ( opt->ip6o_type == 201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3 if ( opt->ip6o_type ==
201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
{ {
if ( opt->ip6o_len == sizeof(struct in6_addr) ) if ( opt->ip6o_len == sizeof(struct in6_addr) )
{ {
if ( homeAddr ) if ( homeAddr )
reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts"); reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts");
else else
homeAddr = new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt)))); homeAddr =
new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt))));
} }
else else
reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len"); reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len");
@ -677,7 +696,8 @@ VectorValPtr IPv6_Hdr_Chain::ToVal() const
uint8_t type = chain[i]->Type(); uint8_t type = chain[i]->Type();
ext_hdr->Assign(0, type); ext_hdr->Assign(0, type);
switch (type) { switch ( type )
{
case IPPROTO_HOPOPTS: case IPPROTO_HOPOPTS:
ext_hdr->Assign(1, std::move(v)); ext_hdr->Assign(1, std::move(v));
break; break;
@ -717,7 +737,7 @@ IP_Hdr* IP_Hdr::Copy() const
if ( ip4 ) if ( ip4 )
{ {
memcpy(new_hdr, ip4, HdrLen()); memcpy(new_hdr, ip4, HdrLen());
return new IP_Hdr((const struct ip*) new_hdr, true); return new IP_Hdr((const struct ip*)new_hdr, true);
} }
memcpy(new_hdr, ip6, HdrLen()); memcpy(new_hdr, ip6, HdrLen());
@ -756,4 +776,4 @@ IPv6_Hdr_Chain* IPv6_Hdr_Chain::Copy(const ip6_hdr* new_hdr) const
return rval; return rval;
} }
} // namespace zeek } // namespace zeek

135
src/IP.h
View file

@ -2,11 +2,11 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <sys/types.h> // for u_char
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <sys/types.h> // for u_char
#include "zeek/zeek-config.h"
#ifdef HAVE_NETINET_IP6_H #ifdef HAVE_NETINET_IP6_H
#include <netinet/ip6.h> #include <netinet/ip6.h>
@ -16,7 +16,8 @@
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
namespace zeek { namespace zeek
{
class IPAddr; class IPAddr;
class RecordVal; class RecordVal;
@ -24,36 +25,42 @@ class VectorVal;
using RecordValPtr = IntrusivePtr<RecordVal>; using RecordValPtr = IntrusivePtr<RecordVal>;
using VectorValPtr = IntrusivePtr<VectorVal>; using VectorValPtr = IntrusivePtr<VectorVal>;
namespace detail { class FragReassembler; } namespace detail
{
class FragReassembler;
}
#ifndef IPPROTO_MOBILITY #ifndef IPPROTO_MOBILITY
#define IPPROTO_MOBILITY 135 #define IPPROTO_MOBILITY 135
#endif #endif
struct ip6_mobility { struct ip6_mobility
{
uint8_t ip6mob_payload; uint8_t ip6mob_payload;
uint8_t ip6mob_len; uint8_t ip6mob_len;
uint8_t ip6mob_type; uint8_t ip6mob_type;
uint8_t ip6mob_rsv; uint8_t ip6mob_rsv;
uint16_t ip6mob_chksum; uint16_t ip6mob_chksum;
}; };
/** /**
* Base class for IPv6 header/extensions. * Base class for IPv6 header/extensions.
*/ */
class IPv6_Hdr { class IPv6_Hdr
{
public: public:
/** /**
* Construct an IPv6 header or extension header from assigned type number. * Construct an IPv6 header or extension header from assigned type number.
*/ */
IPv6_Hdr(uint8_t t, const u_char* d) : type(t), data(d) {} IPv6_Hdr(uint8_t t, const u_char* d) : type(t), data(d) { }
/** /**
* Replace the value of the next protocol field. * Replace the value of the next protocol field.
*/ */
void ChangeNext(uint8_t next_type) void ChangeNext(uint8_t next_type)
{ {
switch ( type ) { switch ( type )
{
case IPPROTO_IPV6: case IPPROTO_IPV6:
((ip6_hdr*)data)->ip6_nxt = next_type; ((ip6_hdr*)data)->ip6_nxt = next_type;
break; break;
@ -71,7 +78,7 @@ public:
} }
} }
~IPv6_Hdr() {} ~IPv6_Hdr() { }
/** /**
* Returns the assigned IPv6 extension header type number of the header * Returns the assigned IPv6 extension header type number of the header
@ -79,7 +86,8 @@ public:
*/ */
uint8_t NextHdr() const uint8_t NextHdr() const
{ {
switch ( type ) { switch ( type )
{
case IPPROTO_IPV6: case IPPROTO_IPV6:
return ((ip6_hdr*)data)->ip6_nxt; return ((ip6_hdr*)data)->ip6_nxt;
case IPPROTO_HOPOPTS: case IPPROTO_HOPOPTS:
@ -100,7 +108,8 @@ public:
*/ */
uint16_t Length() const uint16_t Length() const
{ {
switch ( type ) { switch ( type )
{
case IPPROTO_IPV6: case IPPROTO_IPV6:
return 40; return 40;
case IPPROTO_HOPOPTS: case IPPROTO_HOPOPTS:
@ -113,7 +122,7 @@ public:
case IPPROTO_AH: case IPPROTO_AH:
return 8 + 4 * ((ip6_ext*)data)->ip6e_len; return 8 + 4 * ((ip6_ext*)data)->ip6e_len;
case IPPROTO_ESP: case IPPROTO_ESP:
return 8; //encrypted payload begins after 8 bytes return 8; // encrypted payload begins after 8 bytes
default: default:
return 0; return 0;
} }
@ -138,15 +147,15 @@ public:
protected: protected:
uint8_t type; uint8_t type;
const u_char* data; const u_char* data;
}; };
class IPv6_Hdr_Chain { class IPv6_Hdr_Chain
{
public: public:
/** /**
* Initializes the header chain from an IPv6 header structure. * Initializes the header chain from an IPv6 header structure.
*/ */
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, int len) IPv6_Hdr_Chain(const struct ip6_hdr* ip6, int len) { Init(ip6, len, false); }
{ Init(ip6, len, false); }
~IPv6_Hdr_Chain(); ~IPv6_Hdr_Chain();
@ -180,29 +189,28 @@ public:
* Returns pointer to fragment header structure if the chain contains one. * Returns pointer to fragment header structure if the chain contains one.
*/ */
const struct ip6_frag* GetFragHdr() const const struct ip6_frag* GetFragHdr() const
{ return IsFragment() ? {
(const struct ip6_frag*)chain[chain.size()-1]->Data(): nullptr; } return IsFragment() ? (const struct ip6_frag*)chain[chain.size() - 1]->Data() : nullptr;
}
/** /**
* If the header chain is a fragment, returns the offset in number of bytes * If the header chain is a fragment, returns the offset in number of bytes
* relative to the start of the Fragmentable Part of the original packet. * relative to the start of the Fragmentable Part of the original packet.
*/ */
uint16_t FragOffset() const uint16_t FragOffset() const
{ return IsFragment() ? {
(ntohs(GetFragHdr()->ip6f_offlg) & 0xfff8) : 0; } return IsFragment() ? (ntohs(GetFragHdr()->ip6f_offlg) & 0xfff8) : 0;
}
/** /**
* If the header chain is a fragment, returns the identification field. * If the header chain is a fragment, returns the identification field.
*/ */
uint32_t ID() const uint32_t ID() const { return IsFragment() ? ntohl(GetFragHdr()->ip6f_ident) : 0; }
{ return IsFragment() ? ntohl(GetFragHdr()->ip6f_ident) : 0; }
/** /**
* If the header chain is a fragment, returns the M (more fragments) flag. * If the header chain is a fragment, returns the M (more fragments) flag.
*/ */
int MF() const int MF() const { return IsFragment() ? (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; }
{ return IsFragment() ?
(ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; }
/** /**
* If the chain contains a Destination Options header with a Home Address * If the chain contains a Destination Options header with a Home Address
@ -236,15 +244,16 @@ protected:
* the first next protocol pointer field that points to a fragment header. * the first next protocol pointer field that points to a fragment header.
*/ */
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16_t next, int len) IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16_t next, int len)
{ Init(ip6, len, true, next); } {
Init(ip6, len, true, next);
}
/** /**
* Initializes the header chain from an IPv6 header structure of a given * Initializes the header chain from an IPv6 header structure of a given
* length, possibly setting the first next protocol pointer field that * length, possibly setting the first next protocol pointer field that
* points to a fragment header. * points to a fragment header.
*/ */
void Init(const struct ip6_hdr* ip6, int total_len, bool set_next, void Init(const struct ip6_hdr* ip6, int total_len, bool set_next, uint16_t next = 0);
uint16_t next = 0);
/** /**
* Process a routing header and allocate/remember the final destination * Process a routing header and allocate/remember the final destination
@ -275,13 +284,14 @@ protected:
* non-zero segments left. * non-zero segments left.
*/ */
IPAddr* finalDst = nullptr; IPAddr* finalDst = nullptr;
}; };
/** /**
* A class that wraps either an IPv4 or IPv6 packet and abstracts methods * A class that wraps either an IPv4 or IPv6 packet and abstracts methods
* for inquiring about common features between the two. * for inquiring about common features between the two.
*/ */
class IP_Hdr { class IP_Hdr
{
public: public:
/** /**
* Construct the header wrapper from an IPv4 packet. Caller must have * Construct the header wrapper from an IPv4 packet. Caller must have
@ -290,7 +300,7 @@ public:
* @param arg_del whether to take ownership of \a arg_ip4 pointer's memory. * @param arg_del whether to take ownership of \a arg_ip4 pointer's memory.
* @param reassembled whether this header is for a reassembled packet. * @param reassembled whether this header is for a reassembled packet.
*/ */
IP_Hdr(const struct ip* arg_ip4, bool arg_del, bool reassembled=false) IP_Hdr(const struct ip* arg_ip4, bool arg_del, bool reassembled = false)
: ip4(arg_ip4), del(arg_del), reassembled(reassembled) : ip4(arg_ip4), del(arg_del), reassembled(reassembled)
{ {
} }
@ -307,10 +317,10 @@ public:
* @param c an already-constructed header chain to take ownership of. * @param c an already-constructed header chain to take ownership of.
* @param reassembled whether this header is for a reassembled packet. * @param reassembled whether this header is for a reassembled packet.
*/ */
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, int len, IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, int len, const IPv6_Hdr_Chain* c = nullptr,
const IPv6_Hdr_Chain* c = nullptr, bool reassembled=false) bool reassembled = false)
: ip6(arg_ip6), ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6, len)), : ip6(arg_ip6), ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6, len)), del(arg_del),
del(arg_del), reassembled(reassembled) reassembled(reassembled)
{ {
} }
@ -330,8 +340,8 @@ public:
if ( del ) if ( del )
{ {
delete [] (struct ip*) ip4; delete[](struct ip*) ip4;
delete [] (struct ip6_hdr*) ip6; delete[](struct ip6_hdr*) ip6;
} }
} }
@ -377,9 +387,9 @@ public:
const u_char* Payload() const const u_char* Payload() const
{ {
if ( ip4 ) if ( ip4 )
return ((const u_char*) ip4) + ip4->ip_hl * 4; return ((const u_char*)ip4) + ip4->ip_hl * 4;
return ((const u_char*) ip6) + ip6_hdrs->TotalLength(); return ((const u_char*)ip6) + ip6_hdrs->TotalLength();
} }
/** /**
@ -390,10 +400,10 @@ public:
{ {
if ( ip4 ) if ( ip4 )
return nullptr; return nullptr;
else if ( (*ip6_hdrs)[ip6_hdrs->Size()-1]->Type() != IPPROTO_MOBILITY ) else if ( (*ip6_hdrs)[ip6_hdrs->Size() - 1]->Type() != IPPROTO_MOBILITY )
return nullptr; return nullptr;
else else
return (const ip6_mobility*)(*ip6_hdrs)[ip6_hdrs->Size()-1]->Data(); return (const ip6_mobility*)(*ip6_hdrs)[ip6_hdrs->Size() - 1]->Data();
} }
/** /**
@ -422,8 +432,7 @@ public:
/** /**
* Returns length of IP packet header (includes extension headers for IPv6). * Returns length of IP packet header (includes extension headers for IPv6).
*/ */
uint16_t HdrLen() const uint16_t HdrLen() const { return ip4 ? ip4->ip_hl * 4 : ip6_hdrs->TotalLength(); }
{ return ip4 ? ip4->ip_hl * 4 : ip6_hdrs->TotalLength(); }
/** /**
* For IPv6 header chains, returns the type of the last header in the chain. * For IPv6 header chains, returns the type of the last header in the chain.
@ -435,7 +444,7 @@ public:
size_t i = ip6_hdrs->Size(); size_t i = ip6_hdrs->Size();
if ( i > 0 ) if ( i > 0 )
return (*ip6_hdrs)[i-1]->Type(); return (*ip6_hdrs)[i - 1]->Type();
return IPPROTO_NONE; return IPPROTO_NONE;
} }
@ -452,7 +461,7 @@ public:
size_t i = ip6_hdrs->Size(); size_t i = ip6_hdrs->Size();
if ( i > 0 ) if ( i > 0 )
return (*ip6_hdrs)[i-1]->NextHdr(); return (*ip6_hdrs)[i - 1]->NextHdr();
return IPPROTO_NONE; return IPPROTO_NONE;
} }
@ -460,54 +469,50 @@ public:
/** /**
* Returns the IPv4 Time to Live or IPv6 Hop Limit field. * Returns the IPv4 Time to Live or IPv6 Hop Limit field.
*/ */
unsigned char TTL() const unsigned char TTL() const { return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
{ return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
/** /**
* Returns whether the IP header indicates this packet is a fragment. * Returns whether the IP header indicates this packet is a fragment.
*/ */
bool IsFragment() const bool IsFragment() const
{ return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : {
ip6_hdrs->IsFragment(); } return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 : ip6_hdrs->IsFragment();
}
/** /**
* Returns the fragment packet's offset in relation to the original * Returns the fragment packet's offset in relation to the original
* packet in bytes. * packet in bytes.
*/ */
uint16_t FragOffset() const uint16_t FragOffset() const
{ return ip4 ? (ntohs(ip4->ip_off) & 0x1fff) * 8 : {
ip6_hdrs->FragOffset(); } return ip4 ? (ntohs(ip4->ip_off) & 0x1fff) * 8 : ip6_hdrs->FragOffset();
}
/** /**
* Returns the fragment packet's identification field. * Returns the fragment packet's identification field.
*/ */
uint32_t ID() const uint32_t ID() const { return ip4 ? ntohs(ip4->ip_id) : ip6_hdrs->ID(); }
{ return ip4 ? ntohs(ip4->ip_id) : ip6_hdrs->ID(); }
/** /**
* Returns whether a fragment packet's "More Fragments" field is set. * Returns whether a fragment packet's "More Fragments" field is set.
*/ */
int MF() const int MF() const { return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : ip6_hdrs->MF(); }
{ return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : ip6_hdrs->MF(); }
/** /**
* Returns whether a fragment packet's "Don't Fragment" field is set. * Returns whether a fragment packet's "Don't Fragment" field is set.
* Note that IPv6 has no such field. * Note that IPv6 has no such field.
*/ */
int DF() const int DF() const { return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; }
{ return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; }
/** /**
* Returns value of an IPv6 header's flow label field or 0 if it's IPv4. * Returns value of an IPv6 header's flow label field or 0 if it's IPv4.
*/ */
uint32_t FlowLabel() const uint32_t FlowLabel() const { return ip4 ? 0 : (ntohl(ip6->ip6_flow) & 0x000fffff); }
{ return ip4 ? 0 : (ntohl(ip6->ip6_flow) & 0x000fffff); }
/** /**
* Returns number of IP headers in packet (includes IPv6 extension headers). * Returns number of IP headers in packet (includes IPv6 extension headers).
*/ */
size_t NumHeaders() const size_t NumHeaders() const { return ip4 ? 1 : ip6_hdrs->Size(); }
{ return ip4 ? 1 : ip6_hdrs->Size(); }
/** /**
* Returns an ip_hdr or ip6_hdr_chain RecordVal. * Returns an ip_hdr or ip6_hdr_chain RecordVal.
@ -534,6 +539,6 @@ private:
const IPv6_Hdr_Chain* ip6_hdrs = nullptr; const IPv6_Hdr_Chain* ip6_hdrs = nullptr;
bool del = false; bool del = false;
bool reassembled = false; bool reassembled = false;
}; };
} // namespace zeek } // namespace zeek

View file

@ -1,34 +1,35 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/IPAddr.h"
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include <vector> #include <vector>
#include "zeek/IPAddr.h"
#include "zeek/Reporter.h"
#include "zeek/ZeekString.h"
#include "zeek/Conn.h" #include "zeek/Conn.h"
#include "zeek/Hash.h" #include "zeek/Hash.h"
#include "zeek/bro_inet_ntop.h" #include "zeek/Reporter.h"
#include "zeek/ZeekString.h"
#include "zeek/analyzer/Manager.h" #include "zeek/analyzer/Manager.h"
#include "zeek/bro_inet_ntop.h"
namespace zeek { namespace zeek
{
const IPAddr IPAddr::v4_unspecified = IPAddr(in4_addr{}); const IPAddr IPAddr::v4_unspecified = IPAddr(in4_addr{});
const IPAddr IPAddr::v6_unspecified = IPAddr(); const IPAddr IPAddr::v6_unspecified = IPAddr();
namespace detail { namespace detail
{
ConnKey::ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, ConnKey::ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, uint16_t dst_port,
uint16_t dst_port, TransportProto t, bool one_way) TransportProto t, bool one_way)
: transport(t) : transport(t)
{ {
// Lookup up connection based on canonical ordering, which is // Lookup up connection based on canonical ordering, which is
// the smaller of <src addr, src port> and <dst addr, dst port> // the smaller of <src addr, src port> and <dst addr, dst port>
// followed by the other. // followed by the other.
if ( one_way || if ( one_way || addr_port_canon_lt(src, src_port, dst, dst_port) )
addr_port_canon_lt(src, src_port, dst, dst_port)
)
{ {
ip1 = src.in6; ip1 = src.in6;
ip2 = dst.in6; ip2 = dst.in6;
@ -45,8 +46,7 @@ ConnKey::ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port,
} }
ConnKey::ConnKey(const ConnTuple& id) ConnKey::ConnKey(const ConnTuple& id)
: ConnKey(id.src_addr, id.dst_addr, id.src_port, id.dst_port, : ConnKey(id.src_addr, id.dst_addr, id.src_port, id.dst_port, id.proto, id.is_one_way)
id.proto, id.is_one_way)
{ {
} }
@ -64,7 +64,7 @@ ConnKey& ConnKey::operator=(const ConnKey& rhs)
return *this; return *this;
} }
} // namespace detail } // namespace detail
IPAddr::IPAddr(const String& s) IPAddr::IPAddr(const String& s)
{ {
@ -81,7 +81,7 @@ static inline uint32_t bit_mask32(int bottom_bits)
if ( bottom_bits >= 32 ) if ( bottom_bits >= 32 )
return 0xffffffff; return 0xffffffff;
return (((uint32_t) 1) << bottom_bits) - 1; return (((uint32_t)1) << bottom_bits) - 1;
} }
void IPAddr::Mask(int top_bits_to_keep) void IPAddr::Mask(int top_bits_to_keep)
@ -92,12 +92,11 @@ void IPAddr::Mask(int top_bits_to_keep)
return; return;
} }
uint32_t mask_bits[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; uint32_t mask_bits[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
std::ldiv_t res = std::ldiv(top_bits_to_keep, 32); std::ldiv_t res = std::ldiv(top_bits_to_keep, 32);
if ( res.quot < 4 ) if ( res.quot < 4 )
mask_bits[res.quot] = mask_bits[res.quot] = htonl(mask_bits[res.quot] & ~bit_mask32(32 - res.rem));
htonl(mask_bits[res.quot] & ~bit_mask32(32 - res.rem));
for ( unsigned int i = res.quot + 1; i < 4; ++i ) for ( unsigned int i = res.quot + 1; i < 4; ++i )
mask_bits[i] = 0; mask_bits[i] = 0;
@ -116,7 +115,7 @@ void IPAddr::ReverseMask(int top_bits_to_chop)
return; return;
} }
uint32_t mask_bits[4] = { 0, 0, 0, 0 }; uint32_t mask_bits[4] = {0, 0, 0, 0};
std::ldiv_t res = std::ldiv(top_bits_to_chop, 32); std::ldiv_t res = std::ldiv(top_bits_to_chop, 32);
if ( res.quot < 4 ) if ( res.quot < 4 )
@ -144,7 +143,7 @@ bool IPAddr::ConvertString(const char* s, in6_addr* result)
// that can't e.g. handle leading zeroes. // that can't e.g. handle leading zeroes.
int a[4]; int a[4];
int n = 0; int n = 0;
int match_count = sscanf(s, "%d.%d.%d.%d%n", a+0, a+1, a+2, a+3, &n); int match_count = sscanf(s, "%d.%d.%d.%d%n", a + 0, a + 1, a + 2, a + 3, &n);
if ( match_count != 4 ) if ( match_count != 4 )
return false; return false;
@ -200,15 +199,14 @@ std::string IPAddr::AsHexString() const
if ( GetFamily() == IPv4 ) if ( GetFamily() == IPv4 )
{ {
uint32_t* p = (uint32_t*) &in6.s6_addr[12]; uint32_t* p = (uint32_t*)&in6.s6_addr[12];
snprintf(buf, sizeof(buf), "%08x", (uint32_t) ntohl(*p)); snprintf(buf, sizeof(buf), "%08x", (uint32_t)ntohl(*p));
} }
else else
{ {
uint32_t* p = (uint32_t*) in6.s6_addr; uint32_t* p = (uint32_t*)in6.s6_addr;
snprintf(buf, sizeof(buf), "%08x%08x%08x%08x", snprintf(buf, sizeof(buf), "%08x%08x%08x%08x", (uint32_t)ntohl(p[0]), (uint32_t)ntohl(p[1]),
(uint32_t) ntohl(p[0]), (uint32_t) ntohl(p[1]), (uint32_t)ntohl(p[2]), (uint32_t)ntohl(p[3]));
(uint32_t) ntohl(p[2]), (uint32_t) ntohl(p[3]));
} }
return buf; return buf;
@ -219,7 +217,7 @@ std::string IPAddr::PtrName() const
if ( GetFamily() == IPv4 ) if ( GetFamily() == IPv4 )
{ {
char buf[256]; char buf[256];
uint32_t* p = (uint32_t*) &in6.s6_addr[12]; uint32_t* p = (uint32_t*)&in6.s6_addr[12];
uint32_t a = ntohl(*p); uint32_t a = ntohl(*p);
uint32_t a3 = (a >> 24) & 0xff; uint32_t a3 = (a >> 24) & 0xff;
uint32_t a2 = (a >> 16) & 0xff; uint32_t a2 = (a >> 16) & 0xff;
@ -232,15 +230,15 @@ std::string IPAddr::PtrName() const
{ {
static const char hex_digit[] = "0123456789abcdef"; static const char hex_digit[] = "0123456789abcdef";
std::string ptr_name("ip6.arpa"); std::string ptr_name("ip6.arpa");
uint32_t* p = (uint32_t*) in6.s6_addr; uint32_t* p = (uint32_t*)in6.s6_addr;
for ( unsigned int i = 0; i < 4; ++i ) for ( unsigned int i = 0; i < 4; ++i )
{ {
uint32_t a = ntohl(p[i]); uint32_t a = ntohl(p[i]);
for ( unsigned int j = 1; j <=8; ++j ) for ( unsigned int j = 1; j <= 8; ++j )
{ {
ptr_name.insert(0, 1, '.'); ptr_name.insert(0, 1, '.');
ptr_name.insert(0, 1, hex_digit[(a >> (32-j*4)) & 0x0f]); ptr_name.insert(0, 1, hex_digit[(a >> (32 - j * 4)) & 0x0f]);
} }
} }
@ -248,8 +246,7 @@ std::string IPAddr::PtrName() const
} }
} }
IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length) IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length) : prefix(in4), length(96 + length)
: prefix(in4), length(96 + length)
{ {
if ( length > 32 ) if ( length > 32 )
{ {
@ -260,8 +257,7 @@ IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length)
prefix.Mask(this->length); prefix.Mask(this->length);
} }
IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) : prefix(in6), length(length)
: prefix(in6), length(length)
{ {
if ( length > 128 ) if ( length > 128 )
{ {
@ -289,8 +285,7 @@ bool IPAddr::CheckPrefixLength(uint8_t length, bool len_is_v6_relative) const
return true; return true;
} }
IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length, bool len_is_v6_relative) IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length, bool len_is_v6_relative) : prefix(addr)
: prefix(addr)
{ {
if ( prefix.CheckPrefixLength(length, len_is_v6_relative) ) if ( prefix.CheckPrefixLength(length, len_is_v6_relative) )
{ {
@ -318,12 +313,13 @@ std::string IPPrefix::AsString() const
else else
modp_uitoa10(length, l); modp_uitoa10(length, l);
return prefix.AsString() +"/" + l; return prefix.AsString() + "/" + l;
} }
std::unique_ptr<detail::HashKey> IPPrefix::MakeHashKey() const std::unique_ptr<detail::HashKey> IPPrefix::MakeHashKey() const
{ {
struct { struct
{
in6_addr ip; in6_addr ip;
uint32_t len; uint32_t len;
} key; } key;
@ -359,4 +355,4 @@ bool IPPrefix::ConvertString(const char* text, IPPrefix* result)
return true; return true;
} }
} // namespace zeek } // namespace zeek

View file

@ -2,34 +2,37 @@
#pragma once #pragma once
#include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring> #include <cstring>
#include <string>
#include <memory> #include <memory>
#include <string>
#include "zeek/threading/SerialTypes.h" #include "zeek/threading/SerialTypes.h"
using in4_addr = in_addr; using in4_addr = in_addr;
namespace zeek { namespace zeek
{
class String; class String;
struct ConnTuple; struct ConnTuple;
namespace detail { namespace detail
{
class HashKey; class HashKey;
struct ConnKey { struct ConnKey
{
in6_addr ip1; in6_addr ip1;
in6_addr ip2; in6_addr ip2;
uint16_t port1; uint16_t port1;
uint16_t port2; uint16_t port2;
TransportProto transport; TransportProto transport;
ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, uint16_t dst_port,
uint16_t dst_port, TransportProto t, bool one_way); TransportProto t, bool one_way);
ConnKey(const ConnTuple& conn); ConnKey(const ConnTuple& conn);
ConnKey(const ConnKey& rhs) { *this = rhs; } ConnKey(const ConnKey& rhs) { *this = rhs; }
@ -41,16 +44,17 @@ struct ConnKey {
bool operator>(const ConnKey& rhs) const { return memcmp(this, &rhs, sizeof(ConnKey)) > 0; } bool operator>(const ConnKey& rhs) const { return memcmp(this, &rhs, sizeof(ConnKey)) > 0; }
ConnKey& operator=(const ConnKey& rhs); ConnKey& operator=(const ConnKey& rhs);
}; };
using ConnIDKey [[deprecated("Remove in v5.1. Use zeek::detail::ConnKey.")]] = ConnKey; using ConnIDKey [[deprecated("Remove in v5.1. Use zeek::detail::ConnKey.")]] = ConnKey;
} // namespace detail } // namespace detail
/** /**
* Class storing both IPv4 and IPv6 addresses. * Class storing both IPv4 and IPv6 addresses.
*/ */
class IPAddr { class IPAddr
{
public: public:
/** /**
* Address family. * Address family.
@ -60,15 +64,16 @@ public:
/** /**
* Byte order. * Byte order.
*/ */
enum ByteOrder { Host, Network }; enum ByteOrder
{
Host,
Network
};
/** /**
* Constructs the unspecified IPv6 address (all 128 bits zeroed). * Constructs the unspecified IPv6 address (all 128 bits zeroed).
*/ */
IPAddr() IPAddr() { memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); }
{
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
}
/** /**
* Constructs an address instance from an IPv4 address. * Constructs an address instance from an IPv4 address.
@ -94,10 +99,7 @@ public:
* @param s String containing an IP address as either a dotted IPv4 * @param s String containing an IP address as either a dotted IPv4
* address or a hex IPv6 address. * address or a hex IPv6 address.
*/ */
IPAddr(const std::string& s) IPAddr(const std::string& s) { Init(s.data()); }
{
Init(s.data());
}
/** /**
* Constructs an address instance from a string representation. * Constructs an address instance from a string representation.
@ -105,10 +107,7 @@ public:
* @param s ASCIIZ string containing an IP address as either a * @param s ASCIIZ string containing an IP address as either a
* dotted IPv4 address or a hex IPv6 address. * dotted IPv4 address or a hex IPv6 address.
*/ */
IPAddr(const char* s) IPAddr(const char* s) { Init(s); }
{
Init(s);
}
/** /**
* Constructs an address instance from a string representation. * Constructs an address instance from a string representation.
@ -135,7 +134,7 @@ public:
/** /**
* Copy constructor. * Copy constructor.
*/ */
IPAddr(const IPAddr& other) : in6(other.in6) { }; IPAddr(const IPAddr& other) : in6(other.in6){};
/** /**
* Destructor. * Destructor.
@ -175,8 +174,8 @@ public:
bool IsBroadcast() const bool IsBroadcast() const
{ {
if ( GetFamily() == IPv4 ) if ( GetFamily() == IPv4 )
return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) &&
&& (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff)); (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff));
return false; return false;
} }
@ -197,12 +196,12 @@ public:
{ {
if ( GetFamily() == IPv4 ) if ( GetFamily() == IPv4 )
{ {
*bytes = (uint32_t*) &in6.s6_addr[12]; *bytes = (uint32_t*)&in6.s6_addr[12];
return 1; return 1;
} }
else else
{ {
*bytes = (uint32_t*) in6.s6_addr; *bytes = (uint32_t*)in6.s6_addr;
return 4; return 4;
} }
} }
@ -348,10 +347,7 @@ public:
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0; return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0;
} }
friend bool operator!=(const IPAddr& addr1, const IPAddr& addr2) friend bool operator!=(const IPAddr& addr1, const IPAddr& addr2) { return ! (addr1 == addr2); }
{
return ! (addr1 == addr2);
}
/** /**
* Comparison operator IP addresses. This defines a well-defined order for * Comparison operator IP addresses. This defines a well-defined order for
@ -368,15 +364,9 @@ public:
return addr1 < addr2 || addr1 == addr2; return addr1 < addr2 || addr1 == addr2;
} }
friend bool operator>=(const IPAddr& addr1, const IPAddr& addr2) friend bool operator>=(const IPAddr& addr1, const IPAddr& addr2) { return ! (addr1 < addr2); }
{
return ! ( addr1 < addr2 );
}
friend bool operator>(const IPAddr& addr1, const IPAddr& addr2) friend bool operator>(const IPAddr& addr1, const IPAddr& addr2) { return ! (addr1 <= addr2); }
{
return ! ( addr1 <= addr2 );
}
/** /**
* Converts the address into the type used internally by the * Converts the address into the type used internally by the
@ -384,8 +374,12 @@ public:
*/ */
void ConvertToThreadingValue(threading::Value::addr_t* v) const; void ConvertToThreadingValue(threading::Value::addr_t* v) const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const { return padded_sizeof(*this); } "GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this);
}
/** /**
* Check if an IP prefix length would be valid against this IP address. * Check if an IP prefix length would be valid against this IP address.
@ -450,10 +444,8 @@ private:
in6_addr in6; // IPv6 or v4-to-v6-mapped address in6_addr in6; // IPv6 or v4-to-v6-mapped address
// Top 96 bits of a v4-mapped-addr. // Top 96 bits of a v4-mapped-addr.
static constexpr uint8_t v4_mapped_prefix[12] = { 0, 0, 0, 0, static constexpr uint8_t v4_mapped_prefix[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
0, 0, 0, 0, };
0, 0, 0xff, 0xff };
};
inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order) inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order)
{ {
@ -464,7 +456,7 @@ inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order)
if ( order == Host ) if ( order == Host )
{ {
uint32_t* p = (uint32_t*) &in6.s6_addr[12]; uint32_t* p = (uint32_t*)&in6.s6_addr[12];
*p = htonl(*p); *p = htonl(*p);
} }
} }
@ -475,9 +467,9 @@ inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order)
if ( order == Host ) if ( order == Host )
{ {
for ( unsigned int i = 0; i < 4; ++ i) for ( unsigned int i = 0; i < 4; ++i )
{ {
uint32_t* p = (uint32_t*) &in6.s6_addr[i*4]; uint32_t* p = (uint32_t*)&in6.s6_addr[i * 4];
*p = htonl(*p); *p = htonl(*p);
} }
} }
@ -490,21 +482,20 @@ inline bool IPAddr::IsLoopback() const
return in6.s6_addr[12] == 127; return in6.s6_addr[12] == 127;
else else
return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) && (in6.s6_addr[2] == 0) &&
&& (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 0) (in6.s6_addr[3] == 0) && (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0) &&
&& (in6.s6_addr[4] == 0) && (in6.s6_addr[5] == 0) (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0) && (in6.s6_addr[8] == 0) &&
&& (in6.s6_addr[6] == 0) && (in6.s6_addr[7] == 0) (in6.s6_addr[9] == 0) && (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) &&
&& (in6.s6_addr[8] == 0) && (in6.s6_addr[9] == 0) (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0) && (in6.s6_addr[14] == 0) &&
&& (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) (in6.s6_addr[15] == 1));
&& (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0)
&& (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1));
} }
inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
{ {
v->family = GetFamily(); v->family = GetFamily();
switch ( v->family ) { switch ( v->family )
{
case IPv4: case IPv4:
CopyIPv4(&v->in.in4); CopyIPv4(&v->in.in4);
@ -524,9 +515,8 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
* (i.e., \c 192.168.1.1/16 and \c FD00::/8. * (i.e., \c 192.168.1.1/16 and \c FD00::/8.
*/ */
class IPPrefix class IPPrefix
{ {
public: public:
/** /**
* Constructs a prefix 0/0. * Constructs a prefix 0/0.
*/ */
@ -565,14 +555,12 @@ public:
* \a length is expected to range from 0 to 128 even if \a addr is IPv4, * \a length is expected to range from 0 to 128 even if \a addr is IPv4,
* meaning that the mask is to apply to the IPv4-mapped-IPv6 representation. * meaning that the mask is to apply to the IPv4-mapped-IPv6 representation.
*/ */
IPPrefix(const IPAddr& addr, uint8_t length, IPPrefix(const IPAddr& addr, uint8_t length, bool len_is_v6_relative = false);
bool len_is_v6_relative = false);
/** /**
* Copy constructor. * Copy constructor.
*/ */
IPPrefix(const IPPrefix& other) IPPrefix(const IPPrefix& other) : prefix(other.prefix), length(other.length) { }
: prefix(other.prefix), length(other.length) { }
/** /**
* Destructor. * Destructor.
@ -589,10 +577,7 @@ public:
* Returns the bit length of the prefix, relative to the 32 bits * Returns the bit length of the prefix, relative to the 32 bits
* of an IPv4 prefix or relative to the 128 bits of an IPv6 prefix. * of an IPv4 prefix or relative to the 128 bits of an IPv6 prefix.
*/ */
uint8_t Length() const uint8_t Length() const { return prefix.GetFamily() == IPv4 ? length - 96 : length; }
{
return prefix.GetFamily() == IPv4 ? length - 96 : length;
}
/** /**
* Returns the bit length of the prefix always relative to a full * Returns the bit length of the prefix always relative to a full
@ -647,8 +632,12 @@ public:
prefix.ConvertToThreadingValue(&v->prefix); prefix.ConvertToThreadingValue(&v->prefix);
} }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const { return padded_sizeof(*this); } "GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this);
}
/** /**
* Comparison operator for IP prefix. * Comparison operator for IP prefix.
@ -658,10 +647,7 @@ public:
return net1.Prefix() == net2.Prefix() && net1.Length() == net2.Length(); return net1.Prefix() == net2.Prefix() && net1.Length() == net2.Length();
} }
friend bool operator!=(const IPPrefix& net1, const IPPrefix& net2) friend bool operator!=(const IPPrefix& net1, const IPPrefix& net2) { return ! (net1 == net2); }
{
return ! (net1 == net2);
}
/** /**
* Comparison operator IP prefixes. This defines a well-defined order for * Comparison operator IP prefixes. This defines a well-defined order for
@ -685,15 +671,9 @@ public:
return net1 < net2 || net1 == net2; return net1 < net2 || net1 == net2;
} }
friend bool operator>=(const IPPrefix& net1, const IPPrefix& net2) friend bool operator>=(const IPPrefix& net1, const IPPrefix& net2) { return ! (net1 < net2); }
{
return ! (net1 < net2 );
}
friend bool operator>(const IPPrefix& net1, const IPPrefix& net2) friend bool operator>(const IPPrefix& net1, const IPPrefix& net2) { return ! (net1 <= net2); }
{
return ! ( net1 <= net2 );
}
/** /**
* Converts an IPv4 or IPv6 prefix string into a network address prefix structure. * Converts an IPv4 or IPv6 prefix string into a network address prefix structure.
@ -720,6 +700,6 @@ public:
private: private:
IPAddr prefix; // We store it as an address with the non-prefix bits masked out via Mask(). IPAddr prefix; // We store it as an address with the non-prefix bits masked out via Mask().
uint8_t length = 0; // The bit length of the prefix relative to full IPv6 addr. uint8_t length = 0; // The bit length of the prefix relative to full IPv6 addr.
}; };
} // namespace zeek } // namespace zeek

View file

@ -1,12 +1,14 @@
#include "zeek/zeek-config.h"
#include "zeek/IntSet.h" #include "zeek/IntSet.h"
#include "zeek/zeek-config.h"
#ifdef HAVE_MEMORY_H #ifdef HAVE_MEMORY_H
#include <memory.h> #include <memory.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
namespace zeek::detail { namespace zeek::detail
{
void IntSet::Expand(unsigned int i) void IntSet::Expand(unsigned int i)
{ {
@ -16,9 +18,9 @@ void IntSet::Expand(unsigned int i)
memset(newset, 0, newsize); memset(newset, 0, newsize);
memcpy(newset, set, size); memcpy(newset, set, size);
delete [] set; delete[] set;
size = newsize; size = newsize;
set = newset; set = newset;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -8,9 +8,11 @@
#include <string.h> #include <string.h>
namespace zeek::detail { namespace zeek::detail
{
class IntSet { class IntSet
{
public: public:
// n is a hint for the value of the largest integer. // n is a hint for the value of the largest integer.
explicit IntSet(unsigned int n = 1); explicit IntSet(unsigned int n = 1);
@ -38,7 +40,7 @@ inline IntSet::IntSet(unsigned int n)
inline IntSet::~IntSet() inline IntSet::~IntSet()
{ {
delete [] set; delete[] set;
} }
inline void IntSet::Insert(unsigned int i) inline void IntSet::Insert(unsigned int i)
@ -67,4 +69,4 @@ inline void IntSet::Clear()
memset(set, 0, size); memset(set, 0, size);
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,23 +2,28 @@
#pragma once #pragma once
#include <functional>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <functional>
namespace zeek { namespace zeek
{
/** /**
* A tag class for the #IntrusivePtr constructor which means: adopt * A tag class for the #IntrusivePtr constructor which means: adopt
* the reference from the caller. * the reference from the caller.
*/ */
struct AdoptRef {}; struct AdoptRef
{
};
/** /**
* A tag class for the #IntrusivePtr constructor which means: create a * A tag class for the #IntrusivePtr constructor which means: create a
* new reference to the object. * new reference to the object.
*/ */
struct NewRef {}; struct NewRef
{
};
/** /**
* An intrusive, reference counting smart pointer implementation. Much like * An intrusive, reference counting smart pointer implementation. Much like
@ -42,8 +47,8 @@ struct NewRef {};
* should use a smart pointer whenever possible to reduce boilerplate code and * should use a smart pointer whenever possible to reduce boilerplate code and
* increase robustness of the code (in particular w.r.t. exceptions). * increase robustness of the code (in particular w.r.t. exceptions).
*/ */
template <class T> template <class T> class IntrusivePtr
class IntrusivePtr { {
public: public:
// -- member types // -- member types
@ -74,10 +79,7 @@ public:
* *
* @param raw_ptr Pointer to the shared object. * @param raw_ptr Pointer to the shared object.
*/ */
constexpr IntrusivePtr(AdoptRef, pointer raw_ptr) noexcept constexpr IntrusivePtr(AdoptRef, pointer raw_ptr) noexcept : ptr_(raw_ptr) { }
: ptr_(raw_ptr)
{
}
/** /**
* Constructs a new intrusive pointer for managing the lifetime of the object * Constructs a new intrusive pointer for managing the lifetime of the object
@ -87,8 +89,7 @@ public:
* *
* @param raw_ptr Pointer to the shared object. * @param raw_ptr Pointer to the shared object.
*/ */
IntrusivePtr(NewRef, pointer raw_ptr) noexcept IntrusivePtr(NewRef, pointer raw_ptr) noexcept : ptr_(raw_ptr)
: ptr_(raw_ptr)
{ {
if ( ptr_ ) if ( ptr_ )
Ref(ptr_); Ref(ptr_);
@ -99,10 +100,7 @@ public:
// nop // nop
} }
IntrusivePtr(const IntrusivePtr& other) noexcept IntrusivePtr(const IntrusivePtr& other) noexcept : IntrusivePtr(NewRef{}, other.get()) { }
: IntrusivePtr(NewRef{}, other.get())
{
}
template <class U, class = std::enable_if_t<std::is_convertible_v<U*, T*>>> template <class U, class = std::enable_if_t<std::is_convertible_v<U*, T*>>>
IntrusivePtr(IntrusivePtr<U> other) noexcept : ptr_(other.release()) IntrusivePtr(IntrusivePtr<U> other) noexcept : ptr_(other.release())
@ -116,10 +114,7 @@ public:
Unref(ptr_); Unref(ptr_);
} }
void swap(IntrusivePtr& other) noexcept void swap(IntrusivePtr& other) noexcept { std::swap(ptr_, other.ptr_); }
{
std::swap(ptr_, other.ptr_);
}
friend void swap(IntrusivePtr& a, IntrusivePtr& b) noexcept friend void swap(IntrusivePtr& a, IntrusivePtr& b) noexcept
{ {
@ -132,10 +127,7 @@ public:
* intrusive pointer to @c nullptr. * intrusive pointer to @c nullptr.
* @returns the raw pointer without modifying the reference count. * @returns the raw pointer without modifying the reference count.
*/ */
pointer release() noexcept pointer release() noexcept { return std::exchange(ptr_, nullptr); }
{
return std::exchange(ptr_, nullptr);
}
IntrusivePtr& operator=(const IntrusivePtr& other) noexcept IntrusivePtr& operator=(const IntrusivePtr& other) noexcept
{ {
@ -160,34 +152,19 @@ public:
return *this; return *this;
} }
pointer get() const noexcept pointer get() const noexcept { return ptr_; }
{
return ptr_;
}
pointer operator->() const noexcept pointer operator->() const noexcept { return ptr_; }
{
return ptr_;
}
reference operator*() const noexcept reference operator*() const noexcept { return *ptr_; }
{
return *ptr_;
}
bool operator!() const noexcept bool operator!() const noexcept { return ! ptr_; }
{
return !ptr_;
}
explicit operator bool() const noexcept explicit operator bool() const noexcept { return ptr_ != nullptr; }
{
return ptr_ != nullptr;
}
private: private:
pointer ptr_ = nullptr; pointer ptr_ = nullptr;
}; };
/** /**
* Convenience function for creating a reference counted object and wrapping it * Convenience function for creating a reference counted object and wrapping it
@ -197,8 +174,7 @@ private:
* @note This function assumes that any @c T starts with a reference count of 1. * @note This function assumes that any @c T starts with a reference count of 1.
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T, class... Ts> template <class T, class... Ts> IntrusivePtr<T> make_intrusive(Ts&&... args)
IntrusivePtr<T> make_intrusive(Ts&&... args)
{ {
// Assumes that objects start with a reference count of 1! // Assumes that objects start with a reference count of 1!
return {AdoptRef{}, new T(std::forward<Ts>(args)...)}; return {AdoptRef{}, new T(std::forward<Ts>(args)...)};
@ -210,8 +186,7 @@ IntrusivePtr<T> make_intrusive(Ts&&... args)
* @param p The pointer of type @c U to cast to another type, @c T. * @param p The pointer of type @c U to cast to another type, @c T.
* @return The pointer, as cast to type @c T. * @return The pointer, as cast to type @c T.
*/ */
template <class T, class U> template <class T, class U> IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
{ {
return {AdoptRef{}, static_cast<T*>(p.release())}; return {AdoptRef{}, static_cast<T*>(p.release())};
} }
@ -221,68 +196,68 @@ IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator==(const zeek::IntrusivePtr<T>& x, std::nullptr_t)
bool operator==(const zeek::IntrusivePtr<T>& x, std::nullptr_t) { {
return !x; return ! x;
} }
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator==(std::nullptr_t, const zeek::IntrusivePtr<T>& x)
bool operator==(std::nullptr_t, const zeek::IntrusivePtr<T>& x) { {
return !x; return ! x;
} }
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator!=(const zeek::IntrusivePtr<T>& x, std::nullptr_t)
bool operator!=(const zeek::IntrusivePtr<T>& x, std::nullptr_t) { {
return static_cast<bool>(x); return static_cast<bool>(x);
} }
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator!=(std::nullptr_t, const zeek::IntrusivePtr<T>& x)
bool operator!=(std::nullptr_t, const zeek::IntrusivePtr<T>& x) { {
return static_cast<bool>(x); return static_cast<bool>(x);
} }
// -- comparison to raw pointer ------------------------------------------------ // -- comparison to raw pointer ------------------------------------------------
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator==(const zeek::IntrusivePtr<T>& x, const T* y)
bool operator==(const zeek::IntrusivePtr<T>& x, const T* y) { {
return x.get() == y; return x.get() == y;
} }
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator==(const T* x, const zeek::IntrusivePtr<T>& y)
bool operator==(const T* x, const zeek::IntrusivePtr<T>& y) { {
return x == y.get(); return x == y.get();
} }
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator!=(const zeek::IntrusivePtr<T>& x, const T* y)
bool operator!=(const zeek::IntrusivePtr<T>& x, const T* y) { {
return x.get() != y; return x.get() != y;
} }
/** /**
* @relates IntrusivePtr * @relates IntrusivePtr
*/ */
template <class T> template <class T> bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y)
bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y) { {
return x != y.get(); return x != y.get();
} }
// -- comparison to intrusive pointer ------------------------------------------ // -- comparison to intrusive pointer ------------------------------------------
@ -294,7 +269,7 @@ bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y) {
*/ */
template <class T, class U> template <class T, class U>
auto operator==(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y) auto operator==(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y)
-> decltype(x.get() == y.get()) -> decltype(x.get() == y.get())
{ {
return x.get() == y.get(); return x.get() == y.get();
} }
@ -304,19 +279,23 @@ auto operator==(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y)
*/ */
template <class T, class U> template <class T, class U>
auto operator!=(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y) auto operator!=(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y)
-> decltype(x.get() != y.get()) -> decltype(x.get() != y.get())
{ {
return x.get() != y.get(); return x.get() != y.get();
} }
} // namespace zeek } // namespace zeek
// -- hashing ------------------------------------------------ // -- hashing ------------------------------------------------
namespace std { namespace std
template <class T> struct hash<zeek::IntrusivePtr<T>> { {
template <class T> struct hash<zeek::IntrusivePtr<T>>
{
// Hash of intrusive pointer is the same as hash of the raw pointer it holds. // Hash of intrusive pointer is the same as hash of the raw pointer it holds.
size_t operator()(const zeek::IntrusivePtr<T>& v) const noexcept size_t operator()(const zeek::IntrusivePtr<T>& v) const noexcept
{ return std::hash<T*>{}(v.get()); } {
}; return std::hash<T*>{}(v.get());
} }
};
}

View file

@ -1,4 +1,5 @@
#include "zeek/List.h" #include "zeek/List.h"
#include "zeek/3rdparty/doctest.h" #include "zeek/3rdparty/doctest.h"
TEST_CASE("list construction") TEST_CASE("list construction")
@ -13,7 +14,7 @@ TEST_CASE("list construction")
TEST_CASE("list operation") TEST_CASE("list operation")
{ {
zeek::List<int> list({ 1, 2, 3 }); zeek::List<int> list({1, 2, 3});
CHECK(list.size() == 3); CHECK(list.size() == 3);
CHECK(list.max() == 3); CHECK(list.max() == 3);
CHECK(list[0] == 1); CHECK(list[0] == 1);
@ -85,14 +86,14 @@ TEST_CASE("list operation")
TEST_CASE("list iteration") TEST_CASE("list iteration")
{ {
zeek::List<int> list({ 1, 2, 3, 4}); zeek::List<int> list({1, 2, 3, 4});
int index = 1; int index = 1;
for ( int v : list ) for ( int v : list )
CHECK(v == index++); CHECK(v == index++);
index = 1; index = 1;
for ( auto it = list.begin(); it != list.end(); index++, ++it) for ( auto it = list.begin(); it != list.end(); index++, ++it )
CHECK(*it == index); CHECK(*it == index);
} }

View file

@ -20,20 +20,25 @@
// sizeof(data) <= sizeof(void*). // sizeof(data) <= sizeof(void*).
#include <stdarg.h> #include <stdarg.h>
#include <cassert>
#include <initializer_list> #include <initializer_list>
#include <iterator> #include <iterator>
#include <utility> #include <utility>
#include <cassert>
#include "zeek/util.h" #include "zeek/util.h"
namespace zeek { namespace zeek
{
enum class ListOrder : int { ORDERED, UNORDERED }; enum class ListOrder : int
{
ORDERED,
UNORDERED
};
template<typename T, ListOrder Order = ListOrder::ORDERED> template <typename T, ListOrder Order = ListOrder::ORDERED> class List
class List { {
public: public:
constexpr static int DEFAULT_LIST_SIZE = 10; constexpr static int DEFAULT_LIST_SIZE = 10;
constexpr static int LIST_GROWTH_FACTOR = 2; constexpr static int LIST_GROWTH_FACTOR = 2;
@ -51,7 +56,7 @@ public:
max_entries = size; max_entries = size;
entries = (T*) util::safe_malloc(max_entries * sizeof(T)); entries = (T*)util::safe_malloc(max_entries * sizeof(T));
} }
List(const List& b) List(const List& b)
@ -60,7 +65,7 @@ public:
num_entries = b.num_entries; num_entries = b.num_entries;
if ( max_entries ) if ( max_entries )
entries = (T*) util::safe_malloc(max_entries * sizeof(T)); entries = (T*)util::safe_malloc(max_entries * sizeof(T));
else else
entries = nullptr; entries = nullptr;
@ -81,11 +86,11 @@ public:
List(const T* arr, int n) List(const T* arr, int n)
{ {
num_entries = max_entries = n; num_entries = max_entries = n;
entries = (T*) util::safe_malloc(max_entries * sizeof(T)); entries = (T*)util::safe_malloc(max_entries * sizeof(T));
memcpy(entries, arr, n * sizeof(T)); memcpy(entries, arr, n * sizeof(T));
} }
List(std::initializer_list<T> il) : List(il.begin(), il.size()) {} List(std::initializer_list<T> il) : List(il.begin(), il.size()) { }
List& operator=(const List& b) List& operator=(const List& b)
{ {
@ -98,7 +103,7 @@ public:
num_entries = b.num_entries; num_entries = b.num_entries;
if ( max_entries ) if ( max_entries )
entries = (T *) util::safe_malloc(max_entries * sizeof(T)); entries = (T*)util::safe_malloc(max_entries * sizeof(T));
else else
entries = nullptr; entries = nullptr;
@ -124,10 +129,7 @@ public:
} }
// Return nth ent of list (do not remove). // Return nth ent of list (do not remove).
T& operator[](int i) const T& operator[](int i) const { return entries[i]; }
{
return entries[i];
}
void clear() // remove all entries void clear() // remove all entries
{ {
@ -148,7 +150,7 @@ public:
if ( new_size != max_entries ) if ( new_size != max_entries )
{ {
entries = (T*) util::safe_realloc((void*) entries, sizeof(T) * new_size); entries = (T*)util::safe_realloc((void*)entries, sizeof(T) * new_size);
if ( entries ) if ( entries )
max_entries = new_size; max_entries = new_size;
else else
@ -158,9 +160,12 @@ public:
return max_entries; return max_entries;
} }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated(
int MemoryAllocation() const "Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] int
{ return padded_sizeof(*this) + util::pad_size(max_entries * sizeof(T)); } MemoryAllocation() const
{
return padded_sizeof(*this) + util::pad_size(max_entries * sizeof(T));
}
void push_front(const T& a) void push_front(const T& a)
{ {
@ -168,7 +173,7 @@ public:
resize(max_entries ? max_entries * LIST_GROWTH_FACTOR : DEFAULT_LIST_SIZE); resize(max_entries ? max_entries * LIST_GROWTH_FACTOR : DEFAULT_LIST_SIZE);
for ( int i = num_entries; i > 0; --i ) for ( int i = num_entries; i > 0; --i )
entries[i] = entries[i-1]; // move all pointers up one entries[i] = entries[i - 1]; // move all pointers up one
++num_entries; ++num_entries;
entries[0] = a; entries[0] = a;
@ -183,10 +188,10 @@ public:
} }
void pop_front() { remove_nth(0); } void pop_front() { remove_nth(0); }
void pop_back() { remove_nth(num_entries-1); } void pop_back() { remove_nth(num_entries - 1); }
T& front() { return entries[0]; } T& front() { return entries[0]; }
T& back() { return entries[num_entries-1]; } T& back() { return entries[num_entries - 1]; }
// The append method is maintained for historical/compatibility reasons. // The append method is maintained for historical/compatibility reasons.
// (It's commonly used in the event generation API) // (It's commonly used in the event generation API)
@ -209,7 +214,7 @@ public:
T remove_nth(int n) // delete nth entry from list T remove_nth(int n) // delete nth entry from list
{ {
assert(n >=0 && n < num_entries); assert(n >= 0 && n < num_entries);
T old_ent = entries[n]; T old_ent = entries[n];
@ -221,7 +226,7 @@ public:
--num_entries; --num_entries;
for ( ; n < num_entries; ++n ) for ( ; n < num_entries; ++n )
entries[n] = entries[n+1]; entries[n] = entries[n + 1];
} }
else else
{ {
@ -298,7 +303,6 @@ public:
const_reverse_iterator crend() const { return rend(); } const_reverse_iterator crend() const { return rend(); }
protected: protected:
// This could essentially be an std::vector if we wanted. Some // This could essentially be an std::vector if we wanted. Some
// reasons to maybe not refactor to use std::vector ? // reasons to maybe not refactor to use std::vector ?
// //
@ -328,15 +332,13 @@ protected:
int num_entries; int num_entries;
}; };
// Specialization of the List class to store pointers of a type. // Specialization of the List class to store pointers of a type.
template<typename T, ListOrder Order = ListOrder::ORDERED> template <typename T, ListOrder Order = ListOrder::ORDERED> using PList = List<T*, Order>;
using PList = List<T*, Order>;
// Popular type of list: list of strings. // Popular type of list: list of strings.
using name_list = PList<char>; using name_list = PList<char>;
} // namespace zeek } // namespace zeek
// Macro to visit each list element in turn. // Macro to visit each list element in turn.
#define loop_over_list(list, iterator) \ #define loop_over_list(list, iterator) \

View file

@ -1,6 +1,5 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/NFA.h" #include "zeek/NFA.h"
#include <algorithm> #include <algorithm>
@ -8,8 +7,10 @@
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/EquivClass.h" #include "zeek/EquivClass.h"
#include "zeek/IntSet.h" #include "zeek/IntSet.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
static int nfa_state_id = 0; static int nfa_state_id = 0;
@ -159,9 +160,8 @@ unsigned int NFA_State::TotalMemoryAllocation() const
{ {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return padded_sizeof(*this) return padded_sizeof(*this) + xtions.MemoryAllocation() - padded_sizeof(xtions) +
+ xtions.MemoryAllocation() - padded_sizeof(xtions) (epsclosure ? epsclosure->MemoryAllocation() : 0);
+ (epsclosure ? epsclosure->MemoryAllocation() : 0);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
@ -219,7 +219,7 @@ void NFA_Machine::LinkCopies(int n)
for ( i = 0; i < n; ++i ) for ( i = 0; i < n; ++i )
AppendMachine(copies[i]); AppendMachine(copies[i]);
delete [] copies; delete[] copies;
} }
NFA_Machine* NFA_Machine::DuplicateMachine() NFA_Machine* NFA_Machine::DuplicateMachine()
@ -332,7 +332,6 @@ NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2)
return new NFA_Machine(first, last); return new NFA_Machine(first, last);
} }
NFA_state_list* epsilon_closure(NFA_state_list* states) NFA_state_list* epsilon_closure(NFA_state_list* states)
{ {
// We just keep one of this as it may get quite large. // We just keep one of this as it may get quite large.
@ -375,4 +374,4 @@ bool NFA_state_cmp_neg(const NFA_State* v1, const NFA_State* v2)
return false; return false;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,8 +2,8 @@
#pragma once #pragma once
#include "zeek/Obj.h"
#include "zeek/List.h" #include "zeek/List.h"
#include "zeek/Obj.h"
#define NO_ACCEPT 0 #define NO_ACCEPT 0
@ -16,11 +16,13 @@
#define SYM_EPSILON 259 #define SYM_EPSILON 259
#define SYM_CCL 260 #define SYM_CCL 260
namespace zeek { namespace zeek
{
class Func; class Func;
namespace detail { namespace detail
{
class CCL; class CCL;
class EquivClass; class EquivClass;
@ -28,7 +30,8 @@ class EquivClass;
class NFA_State; class NFA_State;
using NFA_state_list = PList<NFA_State>; using NFA_state_list = PList<NFA_State>;
class NFA_State : public Obj { class NFA_State : public Obj
{
public: public:
NFA_State(int sym, EquivClass* ec); NFA_State(int sym, EquivClass* ec);
explicit NFA_State(CCL* ccl); explicit NFA_State(CCL* ccl);
@ -62,8 +65,9 @@ public:
void Dump(FILE* f); void Dump(FILE* f);
// Recursivly count all the reachable states. // Recursivly count all the reachable states.
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int TotalMemoryAllocation() const; "GHI-572.")]] unsigned int
TotalMemoryAllocation() const;
protected: protected:
int sym; // if SYM_CCL, then use ccl int sym; // if SYM_CCL, then use ccl
@ -78,14 +82,16 @@ protected:
NFA_state_list xtions; NFA_state_list xtions;
NFA_state_list* epsclosure; NFA_state_list* epsclosure;
NFA_State* mark; NFA_State* mark;
}; };
class EpsilonState : public NFA_State { class EpsilonState : public NFA_State
{
public: public:
EpsilonState() : NFA_State(SYM_EPSILON, nullptr) { } EpsilonState() : NFA_State(SYM_EPSILON, nullptr) { }
}; };
class NFA_Machine : public Obj { class NFA_Machine : public Obj
{
public: public:
explicit NFA_Machine(NFA_State* first, NFA_State* final = nullptr); explicit NFA_Machine(NFA_State* first, NFA_State* final = nullptr);
~NFA_Machine() override; ~NFA_Machine() override;
@ -97,7 +103,11 @@ public:
void AddAccept(int accept_val); void AddAccept(int accept_val);
void MakeClosure() { MakePositiveClosure(); MakeOptional(); } void MakeClosure()
{
MakePositiveClosure();
MakeOptional();
}
void MakeOptional(); void MakeOptional();
void MakePositiveClosure(); void MakePositiveClosure();
@ -118,8 +128,9 @@ public:
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
void Dump(FILE* f); void Dump(FILE* f);
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const "GHI-572.")]] unsigned int
MemoryAllocation() const
{ {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@ -131,7 +142,7 @@ protected:
NFA_State* first_state; NFA_State* first_state;
NFA_State* final_state; NFA_State* final_state;
int bol, eol; int bol, eol;
}; };
extern NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2); extern NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2);
@ -145,5 +156,5 @@ extern NFA_state_list* epsilon_closure(NFA_state_list* states);
// For sorting NFA states based on their ID fields (decreasing) // For sorting NFA states based on their ID fields (decreasing)
extern bool NFA_state_cmp_neg(const NFA_State* v1, const NFA_State* v2); extern bool NFA_state_cmp_neg(const NFA_State* v1, const NFA_State* v2);
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,12 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/Var.h"
#include "zeek/EventHandler.h" #include "zeek/EventHandler.h"
#include "zeek/Val.h"
#include "zeek/ID.h" #include "zeek/ID.h"
#include "zeek/Val.h"
#include "zeek/Var.h"
#include "zeek/zeek-config.h"
zeek::RecordType* conn_id; zeek::RecordType* conn_id;
zeek::RecordType* endpoint; zeek::RecordType* endpoint;
@ -105,7 +105,8 @@ zeek::StringVal* cmd_line_bpf_filter;
zeek::StringVal* global_hash_seed; zeek::StringVal* global_hash_seed;
namespace zeek::detail { namespace zeek::detail
{
int watchdog_interval; int watchdog_interval;
@ -192,7 +193,8 @@ int record_all_packets;
bro_uint_t bits_per_uid; bro_uint_t bits_per_uid;
} // namespace zeek::detail. The namespace has be closed here before we include the netvar_def files. } // namespace zeek::detail. The namespace has be closed here before we include the netvar_def
// files.
// Because of how the BIF include files are built with namespaces already in them, // Because of how the BIF include files are built with namespaces already in them,
// these files need to be included separately before the namespace is opened below. // these files need to be included separately before the namespace is opened below.
@ -205,9 +207,9 @@ static void bif_init_event_handlers()
static void bif_init_net_var() static void bif_init_net_var()
{ {
#include "const.bif.netvar_init" #include "const.bif.netvar_init"
#include "packet_analysis.bif.netvar_init"
#include "reporter.bif.netvar_init" #include "reporter.bif.netvar_init"
#include "supervisor.bif.netvar_init" #include "supervisor.bif.netvar_init"
#include "packet_analysis.bif.netvar_init"
} }
static void init_bif_types() static void init_bif_types()
@ -216,14 +218,15 @@ static void init_bif_types()
} }
#include "const.bif.netvar_def" #include "const.bif.netvar_def"
#include "types.bif.netvar_def"
#include "event.bif.netvar_def" #include "event.bif.netvar_def"
#include "packet_analysis.bif.netvar_def"
#include "reporter.bif.netvar_def" #include "reporter.bif.netvar_def"
#include "supervisor.bif.netvar_def" #include "supervisor.bif.netvar_def"
#include "packet_analysis.bif.netvar_def" #include "types.bif.netvar_def"
// Re-open the namespace now that the bif headers are all included. // Re-open the namespace now that the bif headers are all included.
namespace zeek::detail { namespace zeek::detail
{
void init_event_handlers() void init_event_handlers()
{ {
@ -268,8 +271,10 @@ void init_net_var()
tcp_partial_close_delay = id::find_val("tcp_partial_close_delay")->AsInterval(); tcp_partial_close_delay = id::find_val("tcp_partial_close_delay")->AsInterval();
tcp_max_initial_window = id::find_val("tcp_max_initial_window")->AsCount(); tcp_max_initial_window = id::find_val("tcp_max_initial_window")->AsCount();
tcp_max_above_hole_without_any_acks = id::find_val("tcp_max_above_hole_without_any_acks")->AsCount(); tcp_max_above_hole_without_any_acks =
tcp_excessive_data_without_further_acks = id::find_val("tcp_excessive_data_without_further_acks")->AsCount(); id::find_val("tcp_max_above_hole_without_any_acks")->AsCount();
tcp_excessive_data_without_further_acks =
id::find_val("tcp_excessive_data_without_further_acks")->AsCount();
tcp_max_old_segments = id::find_val("tcp_max_old_segments")->AsCount(); tcp_max_old_segments = id::find_val("tcp_max_old_segments")->AsCount();
non_analyzed_lifetime = id::find_val("non_analyzed_lifetime")->AsInterval(); non_analyzed_lifetime = id::find_val("non_analyzed_lifetime")->AsInterval();
@ -280,15 +285,11 @@ void init_net_var()
tcp_storm_thresh = id::find_val("tcp_storm_thresh")->AsCount(); tcp_storm_thresh = id::find_val("tcp_storm_thresh")->AsCount();
tcp_storm_interarrival_thresh = id::find_val("tcp_storm_interarrival_thresh")->AsInterval(); tcp_storm_interarrival_thresh = id::find_val("tcp_storm_interarrival_thresh")->AsInterval();
tcp_content_deliver_all_orig = tcp_content_deliver_all_orig = bool(id::find_val("tcp_content_deliver_all_orig")->AsBool());
bool(id::find_val("tcp_content_deliver_all_orig")->AsBool()); tcp_content_deliver_all_resp = bool(id::find_val("tcp_content_deliver_all_resp")->AsBool());
tcp_content_deliver_all_resp =
bool(id::find_val("tcp_content_deliver_all_resp")->AsBool());
udp_content_deliver_all_orig = udp_content_deliver_all_orig = bool(id::find_val("udp_content_deliver_all_orig")->AsBool());
bool(id::find_val("udp_content_deliver_all_orig")->AsBool()); udp_content_deliver_all_resp = bool(id::find_val("udp_content_deliver_all_resp")->AsBool());
udp_content_deliver_all_resp =
bool(id::find_val("udp_content_deliver_all_resp")->AsBool());
udp_content_delivery_ports_use_resp = udp_content_delivery_ports_use_resp =
bool(id::find_val("udp_content_delivery_ports_use_resp")->AsBool()); bool(id::find_val("udp_content_delivery_ports_use_resp")->AsBool());
@ -345,4 +346,4 @@ void init_net_var()
timer_mgr_inactivity_timeout = id::find_val("timer_mgr_inactivity_timeout")->AsInterval(); timer_mgr_inactivity_timeout = id::find_val("timer_mgr_inactivity_timeout")->AsInterval();
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,11 +2,12 @@
#pragma once #pragma once
#include "zeek/Val.h"
#include "zeek/EventRegistry.h" #include "zeek/EventRegistry.h"
#include "zeek/Stats.h" #include "zeek/Stats.h"
#include "zeek/Val.h"
namespace zeek::detail { namespace zeek::detail
{
extern int watchdog_interval; extern int watchdog_interval;
@ -101,11 +102,11 @@ extern void init_event_handlers();
extern void init_net_var(); extern void init_net_var();
extern void init_builtin_types(); extern void init_builtin_types();
} // namespace zeek::detail } // namespace zeek::detail
#include "const.bif.netvar_h" #include "const.bif.netvar_h"
#include "types.bif.netvar_h"
#include "event.bif.netvar_h" #include "event.bif.netvar_h"
#include "packet_analysis.bif.netvar_h"
#include "reporter.bif.netvar_h" #include "reporter.bif.netvar_h"
#include "supervisor.bif.netvar_h" #include "supervisor.bif.netvar_h"
#include "packet_analysis.bif.netvar_h" #include "types.bif.netvar_h"

View file

@ -1,13 +1,15 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/Notifier.h"
#include <set> #include <set>
#include "zeek/Notifier.h"
#include "zeek/DebugLogger.h" #include "zeek/DebugLogger.h"
zeek::notifier::detail::Registry zeek::notifier::detail::registry; zeek::notifier::detail::Registry zeek::notifier::detail::registry;
namespace zeek::notifier::detail { namespace zeek::notifier::detail
{
Receiver::Receiver() Receiver::Receiver()
{ {
@ -86,4 +88,4 @@ Modifiable::~Modifiable()
registry.Unregister(this); registry.Unregister(this);
} }
} // namespace zeek::notifier::detail } // namespace zeek::notifier::detail

View file

@ -7,15 +7,17 @@
#pragma once #pragma once
#include <unordered_map>
#include <cstdint> #include <cstdint>
#include <unordered_map>
namespace zeek::notifier::detail { namespace zeek::notifier::detail
{
class Modifiable; class Modifiable;
/** Interface class for receivers of notifications. */ /** Interface class for receivers of notifications. */
class Receiver { class Receiver
{
public: public:
Receiver(); Receiver();
virtual ~Receiver(); virtual ~Receiver();
@ -32,10 +34,11 @@ public:
* no further modifications can possibly occur. * no further modifications can possibly occur.
*/ */
virtual void Terminate() { } virtual void Terminate() { }
}; };
/** Singleton class tracking all notification requests globally. */ /** Singleton class tracking all notification requests globally. */
class Registry { class Registry
{
public: public:
~Registry(); ~Registry();
@ -86,7 +89,7 @@ private:
typedef std::unordered_multimap<Modifiable*, Receiver*> ModifiableMap; typedef std::unordered_multimap<Modifiable*, Receiver*> ModifiableMap;
ModifiableMap registrations; ModifiableMap registrations;
}; };
/** /**
* Singleton object tracking all global notification requests. * Singleton object tracking all global notification requests.
@ -97,7 +100,8 @@ extern Registry registry;
* Base class for objects that can trigger notifications to receivers when * Base class for objects that can trigger notifications to receivers when
* modified. * modified.
*/ */
class Modifiable { class Modifiable
{
public: public:
/** /**
* Calling this method signals to all registered receivers that the * Calling this method signals to all registered receivers that the
@ -116,6 +120,6 @@ protected:
// Number of currently registered receivers. // Number of currently registered receivers.
uint64_t num_receivers = 0; uint64_t num_receivers = 0;
}; };
} // namespace zeek::notifier::detail } // namespace zeek::notifier::detail

View file

@ -1,17 +1,19 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include <stdlib.h> #include <stdlib.h>
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Func.h"
#include "zeek/File.h" #include "zeek/File.h"
#include "zeek/Func.h"
#include "zeek/plugin/Manager.h" #include "zeek/plugin/Manager.h"
#include "zeek/zeek-config.h"
namespace zeek { namespace zeek
namespace detail { {
namespace detail
{
Location start_location("<start uninitialized>", 0, 0, 0, 0); Location start_location("<start uninitialized>", 0, 0, 0, 0);
Location end_location("<end uninitialized>", 0, 0, 0, 0); Location end_location("<end uninitialized>", 0, 0, 0, 0);
@ -44,14 +46,13 @@ void Location::Describe(ODesc* d) const
bool Location::operator==(const Location& l) const bool Location::operator==(const Location& l) const
{ {
if ( filename == l.filename || if ( filename == l.filename || (filename && l.filename && util::streq(filename, l.filename)) )
(filename && l.filename && util::streq(filename, l.filename)) )
return first_line == l.first_line && last_line == l.last_line; return first_line == l.first_line && last_line == l.last_line;
else else
return false; return false;
} }
} // namespace detail } // namespace detail
int Obj::suppress_errors = 0; int Obj::suppress_errors = 0;
@ -63,7 +64,8 @@ Obj::~Obj()
delete location; delete location;
} }
void Obj::Warn(const char* msg, const Obj* obj2, bool pinpoint_only, const detail::Location* expr_location) const void Obj::Warn(const char* msg, const Obj* obj2, bool pinpoint_only,
const detail::Location* expr_location) const
{ {
ODesc d; ODesc d;
DoMsg(&d, msg, obj2, pinpoint_only, expr_location); DoMsg(&d, msg, obj2, pinpoint_only, expr_location);
@ -71,7 +73,8 @@ void Obj::Warn(const char* msg, const Obj* obj2, bool pinpoint_only, const detai
reporter->PopLocation(); reporter->PopLocation();
} }
void Obj::Error(const char* msg, const Obj* obj2, bool pinpoint_only, const detail::Location* expr_location) const void Obj::Error(const char* msg, const Obj* obj2, bool pinpoint_only,
const detail::Location* expr_location) const
{ {
if ( suppress_errors ) if ( suppress_errors )
return; return;
@ -146,8 +149,7 @@ bool Obj::SetLocationInfo(const detail::Location* start, const detail::Location*
delete location; delete location;
location = new detail::Location(start->filename, location = new detail::Location(start->filename, start->first_line, end->last_line,
start->first_line, end->last_line,
start->first_column, end->last_column); start->first_column, end->last_column);
return true; return true;
@ -162,8 +164,8 @@ void Obj::UpdateLocationEndInfo(const detail::Location& end)
location->last_column = end.last_column; location->last_column = end.last_column;
} }
void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2, void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2, bool pinpoint_only,
bool pinpoint_only, const detail::Location* expr_location) const const detail::Location* expr_location) const
{ {
d->SetShort(); d->SetShort();
@ -209,7 +211,7 @@ void bad_ref(int type)
void obj_delete_func(void* v) void obj_delete_func(void* v)
{ {
Unref((Obj*) v); Unref((Obj*)v);
} }
} // namespace zeek } // namespace zeek

View file

@ -2,36 +2,38 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <limits.h> #include <limits.h>
namespace zeek { #include "zeek/zeek-config.h"
namespace zeek
{
class ODesc; class ODesc;
namespace detail { namespace detail
{
class Location final { class Location final
{
public: public:
constexpr Location(const char* fname, int line_f, int line_l, int col_f, int col_l) noexcept
constexpr Location(const char* fname, int line_f, int line_l, : filename(fname), first_line(line_f), last_line(line_l), first_column(col_f),
int col_f, int col_l) noexcept last_column(col_l)
:filename(fname), first_line(line_f), last_line(line_l), {
first_column(col_f), last_column(col_l) {} }
Location() = default; Location() = default;
void Describe(ODesc* d) const; void Describe(ODesc* d) const;
bool operator==(const Location& l) const; bool operator==(const Location& l) const;
bool operator!=(const Location& l) const bool operator!=(const Location& l) const { return ! (*this == l); }
{ return ! (*this == l); }
const char* filename = nullptr; const char* filename = nullptr;
int first_line = 0, last_line = 0; int first_line = 0, last_line = 0;
int first_column = 0, last_column = 0; int first_column = 0, last_column = 0;
}; };
#define YYLTYPE zeek::detail::yyltype #define YYLTYPE zeek::detail::yyltype
typedef Location yyltype; typedef Location yyltype;
@ -56,9 +58,10 @@ inline void set_location(const Location start, const Location end)
end_location = end; end_location = end;
} }
} // namespace detail } // namespace detail
class Obj { class Obj
{
public: public:
Obj() Obj()
{ {
@ -83,20 +86,19 @@ public:
virtual ~Obj(); virtual ~Obj();
/* disallow copying */ /* disallow copying */
Obj(const Obj &) = delete; Obj(const Obj&) = delete;
Obj &operator=(const Obj &) = delete; Obj& operator=(const Obj&) = delete;
// Report user warnings/errors. If obj2 is given, then it's // Report user warnings/errors. If obj2 is given, then it's
// included in the message, though if pinpoint_only is non-zero, // included in the message, though if pinpoint_only is non-zero,
// then obj2 is only used to pinpoint the location. // then obj2 is only used to pinpoint the location.
void Warn(const char* msg, const Obj* obj2 = nullptr, void Warn(const char* msg, const Obj* obj2 = nullptr, bool pinpoint_only = false,
bool pinpoint_only = false, const detail::Location* expr_location = nullptr) const; const detail::Location* expr_location = nullptr) const;
void Error(const char* msg, const Obj* obj2 = nullptr, void Error(const char* msg, const Obj* obj2 = nullptr, bool pinpoint_only = false,
bool pinpoint_only = false, const detail::Location* expr_location = nullptr) const; const detail::Location* expr_location = nullptr) const;
// Report internal errors. // Report internal errors.
void BadTag(const char* msg, const char* t1 = nullptr, void BadTag(const char* msg, const char* t1 = nullptr, const char* t2 = nullptr) const;
const char* t2 = nullptr) const;
#define CHECK_TAG(t1, t2, text, tag_to_text_func) \ #define CHECK_TAG(t1, t2, text, tag_to_text_func) \
{ \ { \
if ( t1 != t2 ) \ if ( t1 != t2 ) \
@ -106,16 +108,17 @@ public:
[[noreturn]] void Internal(const char* msg) const; [[noreturn]] void Internal(const char* msg) const;
void InternalWarning(const char* msg) const; void InternalWarning(const char* msg) const;
virtual void Describe(ODesc* d) const { /* FIXME: Add code */ }; virtual void Describe(ODesc* d) const {/* FIXME: Add code */};
void AddLocation(ODesc* d) const; void AddLocation(ODesc* d) const;
// Get location info for debugging. // Get location info for debugging.
virtual const detail::Location* GetLocationInfo() const virtual const detail::Location* GetLocationInfo() const
{ return location ? location : &detail::no_location; } {
return location ? location : &detail::no_location;
}
virtual bool SetLocationInfo(const detail::Location* loc) virtual bool SetLocationInfo(const detail::Location* loc) { return SetLocationInfo(loc, loc); }
{ return SetLocationInfo(loc, loc); }
// Location = range from start to end. // Location = range from start to end.
virtual bool SetLocationInfo(const detail::Location* start, const detail::Location* end); virtual bool SetLocationInfo(const detail::Location* start, const detail::Location* end);
@ -131,7 +134,8 @@ public:
// Helper class to temporarily suppress errors // Helper class to temporarily suppress errors
// as long as there exist any instances. // as long as there exist any instances.
class SuppressErrors { class SuppressErrors
{
public: public:
SuppressErrors() { ++Obj::suppress_errors; } SuppressErrors() { ++Obj::suppress_errors; }
~SuppressErrors() { --Obj::suppress_errors; } ~SuppressErrors() { --Obj::suppress_errors; }
@ -145,10 +149,9 @@ protected:
private: private:
friend class SuppressErrors; friend class SuppressErrors;
void DoMsg(ODesc* d, const char s1[], const Obj* obj2 = nullptr, void DoMsg(ODesc* d, const char s1[], const Obj* obj2 = nullptr, bool pinpoint_only = false,
bool pinpoint_only = false, const detail::Location* expr_location = nullptr) const; const detail::Location* expr_location = nullptr) const;
void PinPoint(ODesc* d, const Obj* obj2 = nullptr, void PinPoint(ODesc* d, const Obj* obj2 = nullptr, bool pinpoint_only = false) const;
bool pinpoint_only = false) const;
friend inline void Ref(Obj* o); friend inline void Ref(Obj* o);
friend inline void Unref(Obj* o); friend inline void Unref(Obj* o);
@ -159,7 +162,7 @@ private:
// If non-zero, do not print runtime errors. Useful for // If non-zero, do not print runtime errors. Useful for
// speculative evaluation. // speculative evaluation.
static int suppress_errors; static int suppress_errors;
}; };
// Sometimes useful when dealing with Obj subclasses that have their // Sometimes useful when dealing with Obj subclasses that have their
// own (protected) versions of Error. // own (protected) versions of Error.
@ -194,4 +197,4 @@ inline void Unref(Obj* o)
// A dict_delete_func that knows to Unref() dictionary entries. // A dict_delete_func that knows to Unref() dictionary entries.
extern void obj_delete_func(void* v); extern void obj_delete_func(void* v);
} // namespace zeek } // namespace zeek

View file

@ -2,25 +2,25 @@
#include "zeek/OpaqueVal.h" #include "zeek/OpaqueVal.h"
#include <memory>
#include <broker/data.hh> #include <broker/data.hh>
#include <broker/error.hh> #include <broker/error.hh>
#include <memory>
#include "zeek/CompHash.h" #include "zeek/CompHash.h"
#include "zeek/Desc.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/Scope.h" #include "zeek/Scope.h"
#include "zeek/Desc.h"
#include "zeek/Var.h" #include "zeek/Var.h"
#include "zeek/probabilistic/BloomFilter.h" #include "zeek/probabilistic/BloomFilter.h"
#include "zeek/probabilistic/CardinalityCounter.h" #include "zeek/probabilistic/CardinalityCounter.h"
namespace zeek { namespace zeek
{
// Helper to retrieve a broker value out of a broker::vector at a specified // Helper to retrieve a broker value out of a broker::vector at a specified
// index, and casted to the expected destination type. // index, and casted to the expected destination type.
template<typename S, typename V, typename D> template <typename S, typename V, typename D>
inline bool get_vector_idx(const V& v, unsigned int i, D* dst) inline bool get_vector_idx(const V& v, unsigned int i, D* dst)
{ {
if ( i >= v.size() ) if ( i >= v.size() )
@ -40,12 +40,9 @@ OpaqueMgr* OpaqueMgr::mgr()
return &mgr; return &mgr;
} }
OpaqueVal::OpaqueVal(OpaqueTypePtr t) : Val(std::move(t)) OpaqueVal::OpaqueVal(OpaqueTypePtr t) : Val(std::move(t)) { }
{}
OpaqueVal::~OpaqueVal() OpaqueVal::~OpaqueVal() { }
{
}
const std::string& OpaqueMgr::TypeID(const OpaqueVal* v) const const std::string& OpaqueMgr::TypeID(const OpaqueVal* v) const
{ {
@ -211,9 +208,7 @@ HashVal::HashVal(OpaqueTypePtr t) : OpaqueVal(std::move(t))
valid = false; valid = false;
} }
MD5Val::MD5Val() : HashVal(md5_type) MD5Val::MD5Val() : HashVal(md5_type) { }
{
}
MD5Val::~MD5Val() MD5Val::~MD5Val()
{ {
@ -232,7 +227,7 @@ void HashVal::digest_one(EVP_MD_CTX* h, const Val* v)
{ {
ODesc d(DESC_BINARY); ODesc d(DESC_BINARY);
v->Describe(&d); v->Describe(&d);
detail::hash_update(h, (const u_char *) d.Bytes(), d.Len()); detail::hash_update(h, (const u_char*)d.Bytes(), d.Len());
} }
} }
@ -289,18 +284,16 @@ broker::expected<broker::data> MD5Val::DoSerialize() const
if ( ! IsValid() ) if ( ! IsValid() )
return {broker::vector{false}}; return {broker::vector{false}};
MD5_CTX* md = (MD5_CTX*) EVP_MD_CTX_md_data(ctx); MD5_CTX* md = (MD5_CTX*)EVP_MD_CTX_md_data(ctx);
broker::vector d = { broker::vector d = {true,
true,
static_cast<uint64_t>(md->A), static_cast<uint64_t>(md->A),
static_cast<uint64_t>(md->B), static_cast<uint64_t>(md->B),
static_cast<uint64_t>(md->C), static_cast<uint64_t>(md->C),
static_cast<uint64_t>(md->D), static_cast<uint64_t>(md->D),
static_cast<uint64_t>(md->Nl), static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh), static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num) static_cast<uint64_t>(md->num)};
};
for ( int i = 0; i < MD5_LBLOCK; ++i ) for ( int i = 0; i < MD5_LBLOCK; ++i )
d.emplace_back(static_cast<uint64_t>(md->data[i])); d.emplace_back(static_cast<uint64_t>(md->data[i]));
@ -325,7 +318,7 @@ bool MD5Val::DoUnserialize(const broker::data& data)
} }
Init(); Init();
MD5_CTX* md = (MD5_CTX*) EVP_MD_CTX_md_data(ctx); MD5_CTX* md = (MD5_CTX*)EVP_MD_CTX_md_data(ctx);
if ( ! get_vector_idx<uint64_t>(*d, 1, &md->A) ) if ( ! get_vector_idx<uint64_t>(*d, 1, &md->A) )
return false; return false;
@ -351,9 +344,7 @@ bool MD5Val::DoUnserialize(const broker::data& data)
return true; return true;
} }
SHA1Val::SHA1Val() : HashVal(sha1_type) SHA1Val::SHA1Val() : HashVal(sha1_type) { }
{
}
SHA1Val::~SHA1Val() SHA1Val::~SHA1Val()
{ {
@ -409,10 +400,9 @@ broker::expected<broker::data> SHA1Val::DoSerialize() const
if ( ! IsValid() ) if ( ! IsValid() )
return {broker::vector{false}}; return {broker::vector{false}};
SHA_CTX* md = (SHA_CTX*) EVP_MD_CTX_md_data(ctx); SHA_CTX* md = (SHA_CTX*)EVP_MD_CTX_md_data(ctx);
broker::vector d = { broker::vector d = {true,
true,
static_cast<uint64_t>(md->h0), static_cast<uint64_t>(md->h0),
static_cast<uint64_t>(md->h1), static_cast<uint64_t>(md->h1),
static_cast<uint64_t>(md->h2), static_cast<uint64_t>(md->h2),
@ -420,8 +410,7 @@ broker::expected<broker::data> SHA1Val::DoSerialize() const
static_cast<uint64_t>(md->h4), static_cast<uint64_t>(md->h4),
static_cast<uint64_t>(md->Nl), static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh), static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num) static_cast<uint64_t>(md->num)};
};
for ( int i = 0; i < SHA_LBLOCK; ++i ) for ( int i = 0; i < SHA_LBLOCK; ++i )
d.emplace_back(static_cast<uint64_t>(md->data[i])); d.emplace_back(static_cast<uint64_t>(md->data[i]));
@ -446,7 +435,7 @@ bool SHA1Val::DoUnserialize(const broker::data& data)
} }
Init(); Init();
SHA_CTX* md = (SHA_CTX*) EVP_MD_CTX_md_data(ctx); SHA_CTX* md = (SHA_CTX*)EVP_MD_CTX_md_data(ctx);
if ( ! get_vector_idx<uint64_t>(*d, 1, &md->h0) ) if ( ! get_vector_idx<uint64_t>(*d, 1, &md->h0) )
return false; return false;
@ -474,9 +463,7 @@ bool SHA1Val::DoUnserialize(const broker::data& data)
return true; return true;
} }
SHA256Val::SHA256Val() : HashVal(sha256_type) SHA256Val::SHA256Val() : HashVal(sha256_type) { }
{
}
SHA256Val::~SHA256Val() SHA256Val::~SHA256Val()
{ {
@ -501,7 +488,7 @@ ValPtr SHA256Val::DoClone(CloneState* state)
bool SHA256Val::DoInit() bool SHA256Val::DoInit()
{ {
assert( ! IsValid() ); assert(! IsValid());
ctx = detail::hash_init(detail::Hash_SHA256); ctx = detail::hash_init(detail::Hash_SHA256);
return true; return true;
} }
@ -532,15 +519,10 @@ broker::expected<broker::data> SHA256Val::DoSerialize() const
if ( ! IsValid() ) if ( ! IsValid() )
return {broker::vector{false}}; return {broker::vector{false}};
SHA256_CTX* md = (SHA256_CTX*) EVP_MD_CTX_md_data(ctx); SHA256_CTX* md = (SHA256_CTX*)EVP_MD_CTX_md_data(ctx);
broker::vector d = { broker::vector d = {true, static_cast<uint64_t>(md->Nl), static_cast<uint64_t>(md->Nh),
true, static_cast<uint64_t>(md->num), static_cast<uint64_t>(md->md_len)};
static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num),
static_cast<uint64_t>(md->md_len)
};
for ( int i = 0; i < 8; ++i ) for ( int i = 0; i < 8; ++i )
d.emplace_back(static_cast<uint64_t>(md->h[i])); d.emplace_back(static_cast<uint64_t>(md->h[i]));
@ -568,7 +550,7 @@ bool SHA256Val::DoUnserialize(const broker::data& data)
} }
Init(); Init();
SHA256_CTX* md = (SHA256_CTX*) EVP_MD_CTX_md_data(ctx); SHA256_CTX* md = (SHA256_CTX*)EVP_MD_CTX_md_data(ctx);
if ( ! get_vector_idx<uint64_t>(*d, 1, &md->Nl) ) if ( ! get_vector_idx<uint64_t>(*d, 1, &md->Nl) )
return false; return false;
@ -594,9 +576,7 @@ bool SHA256Val::DoUnserialize(const broker::data& data)
return true; return true;
} }
EntropyVal::EntropyVal() : OpaqueVal(entropy_type) EntropyVal::EntropyVal() : OpaqueVal(entropy_type) { }
{
}
bool EntropyVal::Feed(const void* data, size_t size) bool EntropyVal::Feed(const void* data, size_t size)
{ {
@ -604,8 +584,8 @@ bool EntropyVal::Feed(const void* data, size_t size)
return true; return true;
} }
bool EntropyVal::Get(double *r_ent, double *r_chisq, double *r_mean, bool EntropyVal::Get(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc,
double *r_montepicalc, double *r_scc) double* r_scc)
{ {
state.end(r_ent, r_chisq, r_mean, r_montepicalc, r_scc); state.end(r_ent, r_chisq, r_mean, r_montepicalc, r_scc);
return true; return true;
@ -615,22 +595,14 @@ IMPLEMENT_OPAQUE_VALUE(EntropyVal)
broker::expected<broker::data> EntropyVal::DoSerialize() const broker::expected<broker::data> EntropyVal::DoSerialize() const
{ {
broker::vector d = broker::vector d = {
{ static_cast<uint64_t>(state.totalc), static_cast<uint64_t>(state.mp),
static_cast<uint64_t>(state.totalc), static_cast<uint64_t>(state.sccfirst), static_cast<uint64_t>(state.inmont),
static_cast<uint64_t>(state.mp), static_cast<uint64_t>(state.mcount), static_cast<uint64_t>(state.cexp),
static_cast<uint64_t>(state.sccfirst), static_cast<uint64_t>(state.montex), static_cast<uint64_t>(state.montey),
static_cast<uint64_t>(state.inmont), static_cast<uint64_t>(state.montepi), static_cast<uint64_t>(state.sccu0),
static_cast<uint64_t>(state.mcount), static_cast<uint64_t>(state.scclast), static_cast<uint64_t>(state.scct1),
static_cast<uint64_t>(state.cexp), static_cast<uint64_t>(state.scct2), static_cast<uint64_t>(state.scct3),
static_cast<uint64_t>(state.montex),
static_cast<uint64_t>(state.montey),
static_cast<uint64_t>(state.montepi),
static_cast<uint64_t>(state.sccu0),
static_cast<uint64_t>(state.scclast),
static_cast<uint64_t>(state.scct1),
static_cast<uint64_t>(state.scct2),
static_cast<uint64_t>(state.scct3),
}; };
d.reserve(256 + 3 + RT_MONTEN + 11); d.reserve(256 + 3 + RT_MONTEN + 11);
@ -694,15 +666,13 @@ bool EntropyVal::DoUnserialize(const broker::data& data)
return true; return true;
} }
BloomFilterVal::BloomFilterVal() BloomFilterVal::BloomFilterVal() : OpaqueVal(bloomfilter_type)
: OpaqueVal(bloomfilter_type)
{ {
hash = nullptr; hash = nullptr;
bloom_filter = nullptr; bloom_filter = nullptr;
} }
BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf) BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf) : OpaqueVal(bloomfilter_type)
: OpaqueVal(bloomfilter_type)
{ {
hash = nullptr; hash = nullptr;
bloom_filter = bf; bloom_filter = bf;
@ -762,12 +732,10 @@ std::string BloomFilterVal::InternalState() const
return bloom_filter->InternalState(); return bloom_filter->InternalState();
} }
BloomFilterValPtr BloomFilterVal::Merge(const BloomFilterVal* x, BloomFilterValPtr BloomFilterVal::Merge(const BloomFilterVal* x, const BloomFilterVal* y)
const BloomFilterVal* y)
{ {
if ( x->Type() && // any one 0 is ok here if ( x->Type() && // any one 0 is ok here
y->Type() && y->Type() && ! same_type(x->Type(), y->Type()) )
! same_type(x->Type(), y->Type()) )
{ {
reporter->Error("cannot merge Bloom filters with different types"); reporter->Error("cannot merge Bloom filters with different types");
return nullptr; return nullptr;
@ -875,8 +843,8 @@ CardinalityVal::~CardinalityVal()
ValPtr CardinalityVal::DoClone(CloneState* state) ValPtr CardinalityVal::DoClone(CloneState* state)
{ {
return state->NewClone(this, return state->NewClone(
make_intrusive<CardinalityVal>(new probabilistic::detail::CardinalityCounter(*c))); this, make_intrusive<CardinalityVal>(new probabilistic::detail::CardinalityCounter(*c)));
} }
bool CardinalityVal::Typify(TypePtr arg_type) bool CardinalityVal::Typify(TypePtr arg_type)
@ -948,16 +916,15 @@ bool CardinalityVal::DoUnserialize(const broker::data& data)
return true; return true;
} }
ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p) ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p) : OpaqueVal(paraglob_type)
: OpaqueVal(paraglob_type)
{ {
this->internal_paraglob = std::move(p); this->internal_paraglob = std::move(p);
} }
VectorValPtr ParaglobVal::Get(StringVal* &pattern) VectorValPtr ParaglobVal::Get(StringVal*& pattern)
{ {
auto rval = make_intrusive<VectorVal>(id::string_vec); auto rval = make_intrusive<VectorVal>(id::string_vec);
std::string string_pattern (reinterpret_cast<const char*>(pattern->Bytes()), pattern->Len()); std::string string_pattern(reinterpret_cast<const char*>(pattern->Bytes()), pattern->Len());
std::vector<std::string> matches = this->internal_paraglob->get(string_pattern); std::vector<std::string> matches = this->internal_paraglob->get(string_pattern);
for ( size_t i = 0; i < matches.size(); i++ ) for ( size_t i = 0; i < matches.size(); i++ )
@ -977,7 +944,7 @@ broker::expected<broker::data> ParaglobVal::DoSerialize() const
{ {
broker::vector d; broker::vector d;
std::unique_ptr<std::vector<uint8_t>> iv = this->internal_paraglob->serialize(); std::unique_ptr<std::vector<uint8_t>> iv = this->internal_paraglob->serialize();
for (uint8_t a : *(iv.get())) for ( uint8_t a : *(iv.get()) )
d.emplace_back(static_cast<uint64_t>(a)); d.emplace_back(static_cast<uint64_t>(a));
return {std::move(d)}; return {std::move(d)};
} }
@ -988,10 +955,10 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
if ( ! d ) if ( ! d )
return false; return false;
std::unique_ptr<std::vector<uint8_t>> iv (new std::vector<uint8_t>); std::unique_ptr<std::vector<uint8_t>> iv(new std::vector<uint8_t>);
iv->resize(d->size()); iv->resize(d->size());
for (std::vector<broker::data>::size_type i = 0; i < d->size(); ++i) for ( std::vector<broker::data>::size_type i = 0; i < d->size(); ++i )
{ {
if ( ! get_vector_idx<uint64_t>(*d, i, iv.get()->data() + i) ) if ( ! get_vector_idx<uint64_t>(*d, i, iv.get()->data() + i) )
return false; return false;
@ -1001,12 +968,12 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
{ {
this->internal_paraglob = std::make_unique<paraglob::Paraglob>(std::move(iv)); this->internal_paraglob = std::make_unique<paraglob::Paraglob>(std::move(iv));
} }
catch (const paraglob::underflow_error& e) catch ( const paraglob::underflow_error& e )
{ {
reporter->Error("Paraglob underflow error -> %s", e.what()); reporter->Error("Paraglob underflow error -> %s", e.what());
return false; return false;
} }
catch (const paraglob::overflow_error& e) catch ( const paraglob::overflow_error& e )
{ {
reporter->Error("Paraglob overflow error -> %s", e.what()); reporter->Error("Paraglob overflow error -> %s", e.what());
return false; return false;
@ -1017,16 +984,17 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
ValPtr ParaglobVal::DoClone(CloneState* state) ValPtr ParaglobVal::DoClone(CloneState* state)
{ {
try { try
return make_intrusive<ParaglobVal> {
(std::make_unique<paraglob::Paraglob>(this->internal_paraglob->serialize())); return make_intrusive<ParaglobVal>(
std::make_unique<paraglob::Paraglob>(this->internal_paraglob->serialize()));
} }
catch (const paraglob::underflow_error& e) catch ( const paraglob::underflow_error& e )
{ {
reporter->Error("Paraglob underflow error while cloning -> %s", e.what()); reporter->Error("Paraglob underflow error while cloning -> %s", e.what());
return nullptr; return nullptr;
} }
catch (const paraglob::overflow_error& e) catch ( const paraglob::overflow_error& e )
{ {
reporter->Error("Paraglob overflow error while cloning -> %s", e.what()); reporter->Error("Paraglob overflow error while cloning -> %s", e.what());
return nullptr; return nullptr;
@ -1035,8 +1003,7 @@ ValPtr ParaglobVal::DoClone(CloneState* state)
broker::expected<broker::data> TelemetryVal::DoSerialize() const broker::expected<broker::data> TelemetryVal::DoSerialize() const
{ {
return broker::make_error(broker::ec::invalid_data, return broker::make_error(broker::ec::invalid_data, "cannot serialize metric handles");
"cannot serialize metric handles");
} }
bool TelemetryVal::DoUnserialize(const broker::data&) bool TelemetryVal::DoUnserialize(const broker::data&)
@ -1044,52 +1011,38 @@ bool TelemetryVal::DoUnserialize(const broker::data&)
return false; return false;
} }
TelemetryVal::TelemetryVal(telemetry::IntCounter) :OpaqueVal(int_counter_metric_type) TelemetryVal::TelemetryVal(telemetry::IntCounter) : OpaqueVal(int_counter_metric_type) { }
TelemetryVal::TelemetryVal(telemetry::IntCounterFamily) : OpaqueVal(int_counter_metric_family_type)
{ {
} }
TelemetryVal::TelemetryVal(telemetry::IntCounterFamily) :OpaqueVal(int_counter_metric_family_type) TelemetryVal::TelemetryVal(telemetry::DblCounter) : OpaqueVal(dbl_counter_metric_type) { }
TelemetryVal::TelemetryVal(telemetry::DblCounterFamily) : OpaqueVal(dbl_counter_metric_family_type)
{ {
} }
TelemetryVal::TelemetryVal(telemetry::DblCounter) :OpaqueVal(dbl_counter_metric_type) TelemetryVal::TelemetryVal(telemetry::IntGauge) : OpaqueVal(int_gauge_metric_type) { }
TelemetryVal::TelemetryVal(telemetry::IntGaugeFamily) : OpaqueVal(int_gauge_metric_family_type) { }
TelemetryVal::TelemetryVal(telemetry::DblGauge) : OpaqueVal(dbl_gauge_metric_type) { }
TelemetryVal::TelemetryVal(telemetry::DblGaugeFamily) : OpaqueVal(dbl_gauge_metric_family_type) { }
TelemetryVal::TelemetryVal(telemetry::IntHistogram) : OpaqueVal(int_histogram_metric_type) { }
TelemetryVal::TelemetryVal(telemetry::IntHistogramFamily)
: OpaqueVal(int_histogram_metric_family_type)
{ {
} }
TelemetryVal::TelemetryVal(telemetry::DblCounterFamily) :OpaqueVal(dbl_counter_metric_family_type) TelemetryVal::TelemetryVal(telemetry::DblHistogram) : OpaqueVal(dbl_histogram_metric_type) { }
TelemetryVal::TelemetryVal(telemetry::DblHistogramFamily)
: OpaqueVal(dbl_histogram_metric_family_type)
{ {
} }
TelemetryVal::TelemetryVal(telemetry::IntGauge) :OpaqueVal(int_gauge_metric_type)
{
} }
TelemetryVal::TelemetryVal(telemetry::IntGaugeFamily) :OpaqueVal(int_gauge_metric_family_type)
{
}
TelemetryVal::TelemetryVal(telemetry::DblGauge) :OpaqueVal(dbl_gauge_metric_type)
{
}
TelemetryVal::TelemetryVal(telemetry::DblGaugeFamily) :OpaqueVal(dbl_gauge_metric_family_type)
{
}
TelemetryVal::TelemetryVal(telemetry::IntHistogram) :OpaqueVal(int_histogram_metric_type)
{
}
TelemetryVal::TelemetryVal(telemetry::IntHistogramFamily) :OpaqueVal(int_histogram_metric_family_type)
{
}
TelemetryVal::TelemetryVal(telemetry::DblHistogram) :OpaqueVal(dbl_histogram_metric_type)
{
}
TelemetryVal::TelemetryVal(telemetry::DblHistogramFamily) :OpaqueVal(dbl_histogram_metric_family_type)
{
}
}

View file

@ -2,9 +2,9 @@
#pragma once #pragma once
#include <sys/types.h> // for u_char
#include <broker/expected.hh> #include <broker/expected.hh>
#include <paraglob/paraglob.h> #include <paraglob/paraglob.h>
#include <sys/types.h> // for u_char
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
#include "zeek/RandTest.h" #include "zeek/RandTest.h"
@ -14,12 +14,22 @@
#include "zeek/telemetry/Gauge.h" #include "zeek/telemetry/Gauge.h"
#include "zeek/telemetry/Histogram.h" #include "zeek/telemetry/Histogram.h"
namespace broker { class data; } namespace broker
{
class data;
}
namespace zeek { namespace zeek
{
namespace probabilistic { class BloomFilter; } namespace probabilistic
namespace probabilistic::detail { class CardinalityCounter; } {
class BloomFilter;
}
namespace probabilistic::detail
{
class CardinalityCounter;
}
class OpaqueVal; class OpaqueVal;
using OpaqueValPtr = IntrusivePtr<OpaqueVal>; using OpaqueValPtr = IntrusivePtr<OpaqueVal>;
@ -31,9 +41,10 @@ using BloomFilterValPtr = IntrusivePtr<BloomFilterVal>;
* Singleton that registers all available all available types of opaque * Singleton that registers all available all available types of opaque
* values. This faciliates their serialization into Broker values. * values. This faciliates their serialization into Broker values.
*/ */
class OpaqueMgr { class OpaqueMgr
{
public: public:
using Factory = OpaqueValPtr (); using Factory = OpaqueValPtr();
/** /**
* Return's a unique ID for the type of an opaque value. * Return's a unique ID for the type of an opaque value.
@ -66,16 +77,15 @@ public:
* Internal helper class to register an OpaqueVal-derived classes * Internal helper class to register an OpaqueVal-derived classes
* with the manager. * with the manager.
*/ */
template<class T> template <class T> class Register
class Register { {
public: public:
Register(const char* id) Register(const char* id) { OpaqueMgr::mgr()->_types.emplace(id, &T::OpaqueInstantiate); }
{ OpaqueMgr::mgr()->_types.emplace(id, &T::OpaqueInstantiate); }
}; };
private: private:
std::unordered_map<std::string, Factory*> _types; std::unordered_map<std::string, Factory*> _types;
}; };
/** Macro to insert into an OpaqueVal-derived class's declaration. */ /** Macro to insert into an OpaqueVal-derived class's declaration. */
#define DECLARE_OPAQUE_VALUE(T) \ #define DECLARE_OPAQUE_VALUE(T) \
@ -86,7 +96,7 @@ private:
const char* OpaqueName() const override { return #T; } \ const char* OpaqueName() const override { return #T; } \
static zeek::OpaqueValPtr OpaqueInstantiate() { return zeek::make_intrusive<T>(); } static zeek::OpaqueValPtr OpaqueInstantiate() { return zeek::make_intrusive<T>(); }
#define __OPAQUE_MERGE(a, b) a ## b #define __OPAQUE_MERGE(a, b) a##b
#define __OPAQUE_ID(x) __OPAQUE_MERGE(_opaque, x) #define __OPAQUE_ID(x) __OPAQUE_MERGE(_opaque, x)
/** Macro to insert into an OpaqueVal-derived class's implementation file. */ /** Macro to insert into an OpaqueVal-derived class's implementation file. */
@ -97,7 +107,8 @@ private:
* completely internally, with no further script-level operators provided * completely internally, with no further script-level operators provided
* (other than bif functions). See OpaqueVal.h for derived classes. * (other than bif functions). See OpaqueVal.h for derived classes.
*/ */
class OpaqueVal : public Val { class OpaqueVal : public Val
{
public: public:
explicit OpaqueVal(OpaqueTypePtr t); explicit OpaqueVal(OpaqueTypePtr t);
~OpaqueVal() override; ~OpaqueVal() override;
@ -164,9 +175,10 @@ protected:
* during unserialization. Returns the type at reference count +1. * during unserialization. Returns the type at reference count +1.
*/ */
static TypePtr UnserializeType(const broker::data& data); static TypePtr UnserializeType(const broker::data& data);
}; };
class HashVal : public OpaqueVal { class HashVal : public OpaqueVal
{
public: public:
template <class T> template <class T>
static void digest_all(detail::HashAlgorithm alg, const T& vlist, u_char* result) static void digest_all(detail::HashAlgorithm alg, const T& vlist, u_char* result)
@ -197,17 +209,18 @@ protected:
private: private:
// This flag exists because Get() can only be called once. // This flag exists because Get() can only be called once.
bool valid; bool valid;
}; };
class MD5Val : public HashVal { class MD5Val : public HashVal
{
public: public:
template <class T> template <class T> static void digest(const T& vlist, u_char result[MD5_DIGEST_LENGTH])
static void digest(const T& vlist, u_char result[MD5_DIGEST_LENGTH]) {
{ digest_all(detail::Hash_MD5, vlist, result); } digest_all(detail::Hash_MD5, vlist, result);
}
template <class T> template <class T>
static void hmac(const T& vlist, static void hmac(const T& vlist, u_char key[MD5_DIGEST_LENGTH],
u_char key[MD5_DIGEST_LENGTH],
u_char result[MD5_DIGEST_LENGTH]) u_char result[MD5_DIGEST_LENGTH])
{ {
digest(vlist, result); digest(vlist, result);
@ -233,13 +246,15 @@ protected:
DECLARE_OPAQUE_VALUE(MD5Val) DECLARE_OPAQUE_VALUE(MD5Val)
private: private:
EVP_MD_CTX* ctx; EVP_MD_CTX* ctx;
}; };
class SHA1Val : public HashVal { class SHA1Val : public HashVal
{
public: public:
template <class T> template <class T> static void digest(const T& vlist, u_char result[SHA_DIGEST_LENGTH])
static void digest(const T& vlist, u_char result[SHA_DIGEST_LENGTH]) {
{ digest_all(detail::Hash_SHA1, vlist, result); } digest_all(detail::Hash_SHA1, vlist, result);
}
SHA1Val(); SHA1Val();
~SHA1Val(); ~SHA1Val();
@ -256,13 +271,15 @@ protected:
DECLARE_OPAQUE_VALUE(SHA1Val) DECLARE_OPAQUE_VALUE(SHA1Val)
private: private:
EVP_MD_CTX* ctx; EVP_MD_CTX* ctx;
}; };
class SHA256Val : public HashVal { class SHA256Val : public HashVal
{
public: public:
template <class T> template <class T> static void digest(const T& vlist, u_char result[SHA256_DIGEST_LENGTH])
static void digest(const T& vlist, u_char result[SHA256_DIGEST_LENGTH]) {
{ digest_all(detail::Hash_SHA256, vlist, result); } digest_all(detail::Hash_SHA256, vlist, result);
}
SHA256Val(); SHA256Val();
~SHA256Val(); ~SHA256Val();
@ -279,15 +296,15 @@ protected:
DECLARE_OPAQUE_VALUE(SHA256Val) DECLARE_OPAQUE_VALUE(SHA256Val)
private: private:
EVP_MD_CTX* ctx; EVP_MD_CTX* ctx;
}; };
class EntropyVal : public OpaqueVal { class EntropyVal : public OpaqueVal
{
public: public:
EntropyVal(); EntropyVal();
bool Feed(const void* data, size_t size); bool Feed(const void* data, size_t size);
bool Get(double *r_ent, double *r_chisq, double *r_mean, bool Get(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc, double* r_scc);
double *r_montepicalc, double *r_scc);
protected: protected:
friend class Val; friend class Val;
@ -295,17 +312,17 @@ protected:
DECLARE_OPAQUE_VALUE(EntropyVal) DECLARE_OPAQUE_VALUE(EntropyVal)
private: private:
detail::RandTest state; detail::RandTest state;
}; };
class BloomFilterVal : public OpaqueVal { class BloomFilterVal : public OpaqueVal
{
public: public:
explicit BloomFilterVal(probabilistic::BloomFilter* bf); explicit BloomFilterVal(probabilistic::BloomFilter* bf);
~BloomFilterVal() override; ~BloomFilterVal() override;
ValPtr DoClone(CloneState* state) override; ValPtr DoClone(CloneState* state) override;
const TypePtr& Type() const const TypePtr& Type() const { return type; }
{ return type; }
bool Typify(TypePtr type); bool Typify(TypePtr type);
@ -315,8 +332,7 @@ public:
bool Empty() const; bool Empty() const;
std::string InternalState() const; std::string InternalState() const;
static BloomFilterValPtr Merge(const BloomFilterVal* x, static BloomFilterValPtr Merge(const BloomFilterVal* x, const BloomFilterVal* y);
const BloomFilterVal* y);
protected: protected:
friend class Val; friend class Val;
@ -331,10 +347,10 @@ private:
TypePtr type; TypePtr type;
detail::CompositeHash* hash; detail::CompositeHash* hash;
probabilistic::BloomFilter* bloom_filter; probabilistic::BloomFilter* bloom_filter;
}; };
class CardinalityVal : public OpaqueVal
class CardinalityVal : public OpaqueVal { {
public: public:
explicit CardinalityVal(probabilistic::detail::CardinalityCounter*); explicit CardinalityVal(probabilistic::detail::CardinalityCounter*);
~CardinalityVal() override; ~CardinalityVal() override;
@ -343,8 +359,7 @@ public:
void Add(const Val* val); void Add(const Val* val);
const TypePtr& Type() const const TypePtr& Type() const { return type; }
{ return type; }
bool Typify(TypePtr type); bool Typify(TypePtr type);
@ -358,28 +373,30 @@ private:
TypePtr type; TypePtr type;
detail::CompositeHash* hash; detail::CompositeHash* hash;
probabilistic::detail::CardinalityCounter* c; probabilistic::detail::CardinalityCounter* c;
}; };
class ParaglobVal : public OpaqueVal { class ParaglobVal : public OpaqueVal
{
public: public:
explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p); explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p);
VectorValPtr Get(StringVal* &pattern); VectorValPtr Get(StringVal*& pattern);
ValPtr DoClone(CloneState* state) override; ValPtr DoClone(CloneState* state) override;
bool operator==(const ParaglobVal& other) const; bool operator==(const ParaglobVal& other) const;
protected: protected:
ParaglobVal() : OpaqueVal(paraglob_type) {} ParaglobVal() : OpaqueVal(paraglob_type) { }
DECLARE_OPAQUE_VALUE(ParaglobVal) DECLARE_OPAQUE_VALUE(ParaglobVal)
private: private:
std::unique_ptr<paraglob::Paraglob> internal_paraglob; std::unique_ptr<paraglob::Paraglob> internal_paraglob;
}; };
/** /**
* Base class for metric handles. Handle types are not serializable. * Base class for metric handles. Handle types are not serializable.
*/ */
class TelemetryVal : public OpaqueVal { class TelemetryVal : public OpaqueVal
{
protected: protected:
explicit TelemetryVal(telemetry::IntCounter); explicit TelemetryVal(telemetry::IntCounter);
explicit TelemetryVal(telemetry::IntCounterFamily); explicit TelemetryVal(telemetry::IntCounterFamily);
@ -396,34 +413,25 @@ protected:
broker::expected<broker::data> DoSerialize() const override; broker::expected<broker::data> DoSerialize() const override;
bool DoUnserialize(const broker::data& data) override; bool DoUnserialize(const broker::data& data) override;
}; };
template <class Handle> template <class Handle> class TelemetryValImpl : public TelemetryVal
class TelemetryValImpl : public TelemetryVal { {
public: public:
using HandleType = Handle; using HandleType = Handle;
explicit TelemetryValImpl(Handle hdl) : TelemetryVal(hdl), hdl(hdl) { } explicit TelemetryValImpl(Handle hdl) : TelemetryVal(hdl), hdl(hdl) { }
Handle GetHandle() const noexcept Handle GetHandle() const noexcept { return hdl; }
{
return hdl;
}
protected: protected:
ValPtr DoClone(CloneState*) override ValPtr DoClone(CloneState*) override { return make_intrusive<TelemetryValImpl>(hdl); }
{
return make_intrusive<TelemetryValImpl>(hdl);
}
const char* OpaqueName() const override const char* OpaqueName() const override { return Handle::OpaqueName; }
{
return Handle::OpaqueName;
}
private: private:
Handle hdl; Handle hdl;
}; };
using IntCounterMetricVal = TelemetryValImpl<telemetry::IntCounter>; using IntCounterMetricVal = TelemetryValImpl<telemetry::IntCounter>;
using IntCounterMetricFamilyVal = TelemetryValImpl<telemetry::IntCounterFamily>; using IntCounterMetricFamilyVal = TelemetryValImpl<telemetry::IntCounterFamily>;
@ -438,4 +446,4 @@ using IntHistogramMetricFamilyVal = TelemetryValImpl<telemetry::IntHistogramFami
using DblHistogramMetricVal = TelemetryValImpl<telemetry::DblHistogram>; using DblHistogramMetricVal = TelemetryValImpl<telemetry::DblHistogram>;
using DblHistogramMetricFamilyVal = TelemetryValImpl<telemetry::DblHistogramFamily>; using DblHistogramMetricFamilyVal = TelemetryValImpl<telemetry::DblHistogramFamily>;
} // namespace zeek } // namespace zeek

View file

@ -1,12 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Options.h" #include "zeek/Options.h"
#include "zeek/script_opt/ScriptOpt.h"
#include <unistd.h> #include <unistd.h>
#include "zeek/script_opt/ScriptOpt.h"
#include "zeek/zeek-config.h"
#ifdef HAVE_GETOPT_H #ifdef HAVE_GETOPT_H
#include <getopt.h> #include <getopt.h>
#endif #endif
@ -19,7 +19,8 @@
#include "zeek/bsd-getopt-long.h" #include "zeek/bsd-getopt-long.h"
#include "zeek/logging/writers/ascii/Ascii.h" #include "zeek/logging/writers/ascii/Ascii.h"
namespace zeek { namespace zeek
{
void Options::filter_supervisor_options() void Options::filter_supervisor_options()
{ {
@ -84,22 +85,30 @@ void usage(const char* prog, int code)
fprintf(stderr, "usage: %s [options] [file ...]\n", prog); fprintf(stderr, "usage: %s [options] [file ...]\n", prog);
fprintf(stderr, "usage: %s --test [doctest-options] -- [options] [file ...]\n", prog); fprintf(stderr, "usage: %s --test [doctest-options] -- [options] [file ...]\n", prog);
fprintf(stderr, " <file> | Zeek script file, or read stdin\n"); fprintf(stderr, " <file> | Zeek script file, or read stdin\n");
fprintf(stderr, " -a|--parse-only | exit immediately after parsing scripts\n"); fprintf(stderr,
fprintf(stderr, " -b|--bare-mode | don't load scripts from the base/ directory\n"); " -a|--parse-only | exit immediately after parsing scripts\n");
fprintf(stderr,
" -b|--bare-mode | don't load scripts from the base/ directory\n");
fprintf(stderr, " -d|--debug-script | activate Zeek script debugging\n"); fprintf(stderr, " -d|--debug-script | activate Zeek script debugging\n");
fprintf(stderr, " -e|--exec <zeek code> | augment loaded scripts by given code\n"); fprintf(stderr, " -e|--exec <zeek code> | augment loaded scripts by given code\n");
fprintf(stderr, " -f|--filter <filter> | tcpdump filter\n"); fprintf(stderr, " -f|--filter <filter> | tcpdump filter\n");
fprintf(stderr, " -h|--help | command line help\n"); fprintf(stderr, " -h|--help | command line help\n");
fprintf(stderr, " -i|--iface <interface> | read from given interface (only one allowed)\n"); fprintf(stderr,
fprintf(stderr, " -p|--prefix <prefix> | add given prefix to Zeek script file resolution\n"); " -i|--iface <interface> | read from given interface (only one allowed)\n");
fprintf(stderr, " -r|--readfile <readfile> | read from given tcpdump file (only one allowed, pass '-' as the filename to read from stdin)\n"); fprintf(
stderr,
" -p|--prefix <prefix> | add given prefix to Zeek script file resolution\n");
fprintf(stderr, " -r|--readfile <readfile> | read from given tcpdump file (only one "
"allowed, pass '-' as the filename to read from stdin)\n");
fprintf(stderr, " -s|--rulefile <rulefile> | read rules from given file\n"); fprintf(stderr, " -s|--rulefile <rulefile> | read rules from given file\n");
fprintf(stderr, " -t|--tracefile <tracefile> | activate execution tracing\n"); fprintf(stderr, " -t|--tracefile <tracefile> | activate execution tracing\n");
fprintf(stderr, " -u|--usage-issues | find variable usage issues and exit; use -uu for deeper/more expensive analysis\n"); fprintf(stderr, " -u|--usage-issues | find variable usage issues and exit; use "
"-uu for deeper/more expensive analysis\n");
fprintf(stderr, " -v|--version | print version and exit\n"); fprintf(stderr, " -v|--version | print version and exit\n");
fprintf(stderr, " -w|--writefile <writefile> | write to given tcpdump file\n"); fprintf(stderr, " -w|--writefile <writefile> | write to given tcpdump file\n");
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, " -B|--debug <dbgstreams> | Enable debugging output for selected streams ('-B help' for help)\n"); fprintf(stderr, " -B|--debug <dbgstreams> | Enable debugging output for selected "
"streams ('-B help' for help)\n");
#endif #endif
fprintf(stderr, " -C|--no-checksums | ignore checksums\n"); fprintf(stderr, " -C|--no-checksums | ignore checksums\n");
fprintf(stderr, " -D|--deterministic | initialize random seeds to zero\n"); fprintf(stderr, " -D|--deterministic | initialize random seeds to zero\n");
@ -107,35 +116,57 @@ void usage(const char* prog, int code)
fprintf(stderr, " -G|--load-seeds <file> | load seeds from given file\n"); fprintf(stderr, " -G|--load-seeds <file> | load seeds from given file\n");
fprintf(stderr, " -H|--save-seeds <file> | save seeds to given file\n"); fprintf(stderr, " -H|--save-seeds <file> | save seeds to given file\n");
fprintf(stderr, " -I|--print-id <ID name> | print out given ID\n"); fprintf(stderr, " -I|--print-id <ID name> | print out given ID\n");
fprintf(stderr, " -N|--print-plugins | print available plugins and exit (-NN for verbose)\n"); fprintf(stderr, " -N|--print-plugins | print available plugins and exit (-NN "
fprintf(stderr, " -O|--optimize[=<option>] | enable script optimization (use -O help for options)\n"); "for verbose)\n");
fprintf(stderr, " -o|--optimize-only=<func> | enable script optimization only for the given function\n"); fprintf(stderr, " -O|--optimize[=<option>] | enable script optimization (use -O help "
"for options)\n");
fprintf(stderr, " -o|--optimize-only=<func> | enable script optimization only for the "
"given function\n");
fprintf(stderr, " -P|--prime-dns | prime DNS\n"); fprintf(stderr, " -P|--prime-dns | prime DNS\n");
fprintf(stderr, " -Q|--time | print execution time summary to stderr\n"); fprintf(stderr,
" -Q|--time | print execution time summary to stderr\n");
fprintf(stderr, " -S|--debug-rules | enable rule debugging\n"); fprintf(stderr, " -S|--debug-rules | enable rule debugging\n");
fprintf(stderr, " -T|--re-level <level> | set 'RE_level' for rules\n"); fprintf(stderr, " -T|--re-level <level> | set 'RE_level' for rules\n");
fprintf(stderr, " -U|--status-file <file> | Record process status in file\n"); fprintf(stderr, " -U|--status-file <file> | Record process status in file\n");
fprintf(stderr, " -W|--watchdog | activate watchdog timer\n"); fprintf(stderr, " -W|--watchdog | activate watchdog timer\n");
fprintf(stderr, " -X|--zeekygen <cfgfile> | generate documentation based on config file\n"); fprintf(stderr,
" -X|--zeekygen <cfgfile> | generate documentation based on config file\n");
#ifdef USE_PERFTOOLS_DEBUG #ifdef USE_PERFTOOLS_DEBUG
fprintf(stderr, " -m|--mem-leaks | show leaks [perftools]\n"); fprintf(stderr, " -m|--mem-leaks | show leaks [perftools]\n");
fprintf(stderr, " -M|--mem-profile | record heap [perftools]\n"); fprintf(stderr, " -M|--mem-profile | record heap [perftools]\n");
#endif #endif
fprintf(stderr, " --pseudo-realtime[=<speedup>] | enable pseudo-realtime for performance evaluation (default 1)\n"); fprintf(stderr, " --pseudo-realtime[=<speedup>] | enable pseudo-realtime for performance "
"evaluation (default 1)\n");
fprintf(stderr, " -j|--jobs | enable supervisor mode\n"); fprintf(stderr, " -j|--jobs | enable supervisor mode\n");
fprintf(stderr, " --test | run unit tests ('--test -h' for help, only when compiling with ENABLE_ZEEK_UNIT_TESTS)\n"); fprintf(stderr, " --test | run unit tests ('--test -h' for help, "
fprintf(stderr, " $ZEEKPATH | file search path (%s)\n", util::zeek_path().c_str()); "only when compiling with ENABLE_ZEEK_UNIT_TESTS)\n");
fprintf(stderr, " $ZEEK_PLUGIN_PATH | plugin search path (%s)\n", util::zeek_plugin_path()); fprintf(stderr, " $ZEEKPATH | file search path (%s)\n",
fprintf(stderr, " $ZEEK_PLUGIN_ACTIVATE | plugins to always activate (%s)\n", util::zeek_plugin_activate()); util::zeek_path().c_str());
fprintf(stderr, " $ZEEK_PREFIXES | prefix list (%s)\n", util::zeek_prefixes().c_str()); fprintf(stderr, " $ZEEK_PLUGIN_PATH | plugin search path (%s)\n",
fprintf(stderr, " $ZEEK_DNS_FAKE | disable DNS lookups (%s)\n", fake_dns() ? "on" : "off"); util::zeek_plugin_path());
fprintf(stderr, " $ZEEK_PLUGIN_ACTIVATE | plugins to always activate (%s)\n",
util::zeek_plugin_activate());
fprintf(stderr, " $ZEEK_PREFIXES | prefix list (%s)\n",
util::zeek_prefixes().c_str());
fprintf(stderr, " $ZEEK_DNS_FAKE | disable DNS lookups (%s)\n",
fake_dns() ? "on" : "off");
fprintf(stderr, " $ZEEK_SEED_FILE | file to load seeds from (not set)\n"); fprintf(stderr, " $ZEEK_SEED_FILE | file to load seeds from (not set)\n");
fprintf(stderr, " $ZEEK_LOG_SUFFIX | ASCII log file extension (.%s)\n", logging::writer::detail::Ascii::LogExt().c_str()); fprintf(stderr, " $ZEEK_LOG_SUFFIX | ASCII log file extension (.%s)\n",
fprintf(stderr, " $ZEEK_PROFILER_FILE | Output file for script execution statistics (not set)\n"); logging::writer::detail::Ascii::LogExt().c_str());
fprintf(stderr, " $ZEEK_DISABLE_ZEEKYGEN | Disable Zeekygen documentation support (%s)\n", getenv("ZEEK_DISABLE_ZEEKYGEN") ? "set" : "not set"); fprintf(stderr, " $ZEEK_PROFILER_FILE | Output file for script execution "
fprintf(stderr, " $ZEEK_DNS_RESOLVER | IPv4/IPv6 address of DNS resolver to use (%s)\n", getenv("ZEEK_DNS_RESOLVER") ? getenv("ZEEK_DNS_RESOLVER") : "not set, will use first IPv4 address from /etc/resolv.conf"); "statistics (not set)\n");
fprintf(stderr, " $ZEEK_DEBUG_LOG_STDERR | Use stderr for debug logs generated via the -B flag"); fprintf(stderr,
" $ZEEK_DISABLE_ZEEKYGEN | Disable Zeekygen documentation support (%s)\n",
getenv("ZEEK_DISABLE_ZEEKYGEN") ? "set" : "not set");
fprintf(stderr,
" $ZEEK_DNS_RESOLVER | IPv4/IPv6 address of DNS resolver to use (%s)\n",
getenv("ZEEK_DNS_RESOLVER")
? getenv("ZEEK_DNS_RESOLVER")
: "not set, will use first IPv4 address from /etc/resolv.conf");
fprintf(
stderr,
" $ZEEK_DEBUG_LOG_STDERR | Use stderr for debug logs generated via the -B flag");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -152,7 +183,8 @@ static void print_analysis_help()
fprintf(stderr, " dump-uds dump use-defs to stdout; implies xform\n"); fprintf(stderr, " dump-uds dump use-defs to stdout; implies xform\n");
fprintf(stderr, " dump-xform dump transformed scripts to stdout; implies xform\n"); fprintf(stderr, " dump-xform dump transformed scripts to stdout; implies xform\n");
fprintf(stderr, " dump-ZAM dump generated ZAM code; implies gen-ZAM-code\n"); fprintf(stderr, " dump-ZAM dump generated ZAM code; implies gen-ZAM-code\n");
fprintf(stderr, " gen-ZAM-code generate ZAM code (without turning on additional optimizations)\n"); fprintf(stderr,
" gen-ZAM-code generate ZAM code (without turning on additional optimizations)\n");
fprintf(stderr, " inline inline function calls\n"); fprintf(stderr, " inline inline function calls\n");
fprintf(stderr, " no-ZAM-opt omit low-level ZAM optimization\n"); fprintf(stderr, " no-ZAM-opt omit low-level ZAM optimization\n");
fprintf(stderr, " optimize-all optimize all scripts, even inlined ones\n"); fprintf(stderr, " optimize-all optimize all scripts, even inlined ones\n");
@ -229,8 +261,7 @@ static void set_analysis_option(const char* opt, Options& opts)
else else
{ {
fprintf(stderr,"zeek: unrecognized -O/--optimize option: %s\n\n", fprintf(stderr, "zeek: unrecognized -O/--optimize option: %s\n\n", opt);
opt);
print_analysis_help(); print_analysis_help();
exit(1); exit(1);
} }
@ -251,12 +282,12 @@ Options parse_cmdline(int argc, char** argv)
if ( argc > 1 && strcmp(argv[1], "--test") == 0 ) if ( argc > 1 && strcmp(argv[1], "--test") == 0 )
{ {
#ifdef DOCTEST_CONFIG_DISABLE #ifdef DOCTEST_CONFIG_DISABLE
fprintf(stderr, "ERROR: C++ unit tests are disabled for this build.\n" fprintf(stderr, "ERROR: C++ unit tests are disabled for this build.\n"
" Please re-compile with ENABLE_ZEEK_UNIT_TESTS " " Please re-compile with ENABLE_ZEEK_UNIT_TESTS "
"to run the C++ unit tests.\n"); "to run the C++ unit tests.\n");
usage(argv[0], 1); usage(argv[0], 1);
#endif #endif
auto is_separator = [](const char* cstr) auto is_separator = [](const char* cstr)
{ {
@ -286,7 +317,8 @@ Options parse_cmdline(int argc, char** argv)
{ {
auto endsWith = [](const std::string& str, const std::string& suffix) auto endsWith = [](const std::string& str, const std::string& suffix)
{ {
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix); return str.size() >= suffix.size() &&
0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
}; };
auto i = 0; auto i = 0;
@ -385,8 +417,10 @@ Options parse_cmdline(int argc, char** argv)
for ( size_t i = 0; i < zeek_args.size(); ++i ) for ( size_t i = 0; i < zeek_args.size(); ++i )
zargs[i] = zeek_args[i].data(); zargs[i] = zeek_args[i].data();
while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) != EOF ) while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) !=
switch ( op ) { EOF )
switch ( op )
{
case 'a': case 'a':
rval.parse_only = true; rval.parse_only = true;
break; break;
@ -469,7 +503,7 @@ Options parse_cmdline(int argc, char** argv)
#else #else
if ( util::streq(optarg, "help") ) if ( util::streq(optarg, "help") )
{ {
fprintf(stderr,"debug streams unavailable\n"); fprintf(stderr, "debug streams unavailable\n");
exit(1); exit(1);
} }
#endif #endif
@ -605,8 +639,7 @@ Options parse_cmdline(int argc, char** argv)
if ( ! getcwd(cwd, sizeof(cwd)) ) if ( ! getcwd(cwd, sizeof(cwd)) )
{ {
fprintf(stderr, "failed to get current directory: %s\n", fprintf(stderr, "failed to get current directory: %s\n", strerror(errno));
strerror(errno));
exit(1); exit(1);
} }
@ -625,4 +658,4 @@ Options parse_cmdline(int argc, char** argv)
return rval; return rval;
} }
} // namespace zeek } // namespace zeek

View file

@ -9,13 +9,15 @@
#include "zeek/DNS_Mgr.h" #include "zeek/DNS_Mgr.h"
#include "zeek/script_opt/ScriptOpt.h" #include "zeek/script_opt/ScriptOpt.h"
namespace zeek { namespace zeek
{
/** /**
* Options that define general Zeek processing behavior, usually determined * Options that define general Zeek processing behavior, usually determined
* from command-line arguments. * from command-line arguments.
*/ */
struct Options { struct Options
{
/** /**
* Unset options that aren't meant to be used by the supervisor, but may * Unset options that aren't meant to be used by the supervisor, but may
* make sense for supervised nodes to inherit (as opposed to flagging * make sense for supervised nodes to inherit (as opposed to flagging
@ -40,7 +42,7 @@ struct Options {
std::optional<std::string> identifier_to_print; std::optional<std::string> identifier_to_print;
std::optional<std::string> script_code_to_exec; std::optional<std::string> script_code_to_exec;
std::vector<std::string> script_prefixes = { "" }; // "" = "no prefix" std::vector<std::string> script_prefixes = {""}; // "" = "no prefix"
int signature_re_level = 4; int signature_re_level = 4;
bool ignore_checksums = false; bool ignore_checksums = false;
@ -79,7 +81,7 @@ struct Options {
// For script optimization: // For script optimization:
detail::AnalyOpt analysis_options; detail::AnalyOpt analysis_options;
}; };
/** /**
* Parse Zeek command-line arguments. * Parse Zeek command-line arguments.
@ -101,4 +103,4 @@ void usage(const char* prog, int code = 1);
*/ */
bool fake_dns(); bool fake_dns();
} // namespace zeek } // namespace zeek

View file

@ -1,12 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/Overflow.h" #include "zeek/Overflow.h"
#include "zeek/Val.h" #include "zeek/Val.h"
namespace zeek::detail { namespace zeek::detail
{
bool would_overflow(const zeek::Type* from_type, const zeek::Type* to_type, bool would_overflow(const zeek::Type* from_type, const zeek::Type* to_type, const Val* val)
const Val* val)
{ {
if ( ! to_type || ! from_type ) if ( ! to_type || ! from_type )
return true; return true;
@ -36,4 +37,4 @@ bool would_overflow(const zeek::Type* from_type, const zeek::Type* to_type,
return false; return false;
} }
} }

View file

@ -4,7 +4,8 @@
#include "zeek/Type.h" #include "zeek/Type.h"
namespace zeek::detail { namespace zeek::detail
{
inline bool double_to_count_would_overflow(double v) inline bool double_to_count_would_overflow(double v)
{ {
@ -18,8 +19,7 @@ inline bool int_to_count_would_overflow(bro_int_t v)
inline bool double_to_int_would_overflow(double v) inline bool double_to_int_would_overflow(double v)
{ {
return v < static_cast<double>(INT64_MIN) || return v < static_cast<double>(INT64_MIN) || v > static_cast<double>(INT64_MAX);
v > static_cast<double>(INT64_MAX);
} }
inline bool count_to_int_would_overflow(bro_uint_t v) inline bool count_to_int_would_overflow(bro_uint_t v)
@ -27,7 +27,6 @@ inline bool count_to_int_would_overflow(bro_uint_t v)
return v > INT64_MAX; return v > INT64_MAX;
} }
extern bool would_overflow(const zeek::Type* from_type, extern bool would_overflow(const zeek::Type* from_type, const zeek::Type* to_type, const Val* val);
const zeek::Type* to_type, const Val* val);
} }

View file

@ -1,7 +1,9 @@
#include "zeek/PacketFilter.h" #include "zeek/PacketFilter.h"
#include "zeek/IP.h" #include "zeek/IP.h"
namespace zeek::detail { namespace zeek::detail
{
void PacketFilter::DeleteFilter(void* data) void PacketFilter::DeleteFilter(void* data)
{ {
@ -82,19 +84,18 @@ bool PacketFilter::RemoveDst(Val* dst)
bool PacketFilter::Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen) bool PacketFilter::Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen)
{ {
Filter* f = (Filter*) src_filter.Lookup(ip->SrcAddr(), 128); Filter* f = (Filter*)src_filter.Lookup(ip->SrcAddr(), 128);
if ( f ) if ( f )
return MatchFilter(*f, *ip, len, caplen); return MatchFilter(*f, *ip, len, caplen);
f = (Filter*) dst_filter.Lookup(ip->DstAddr(), 128); f = (Filter*)dst_filter.Lookup(ip->DstAddr(), 128);
if ( f ) if ( f )
return MatchFilter(*f, *ip, len, caplen); return MatchFilter(*f, *ip, len, caplen);
return default_match; return default_match;
} }
bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip, bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip, int len, int caplen)
int len, int caplen)
{ {
if ( ip.NextProto() == IPPROTO_TCP && f.tcp_flags ) if ( ip.NextProto() == IPPROTO_TCP && f.tcp_flags )
{ {
@ -103,12 +104,12 @@ bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip,
len -= ip_hdr_len; // remove IP header len -= ip_hdr_len; // remove IP header
caplen -= ip_hdr_len; caplen -= ip_hdr_len;
if ( (unsigned int) len < sizeof(struct tcphdr) || if ( (unsigned int)len < sizeof(struct tcphdr) ||
(unsigned int) caplen < sizeof(struct tcphdr) ) (unsigned int)caplen < sizeof(struct tcphdr) )
// Packet too short, will be dropped anyway. // Packet too short, will be dropped anyway.
return false; return false;
const struct tcphdr* tp = (const struct tcphdr*) ip.Payload(); const struct tcphdr* tp = (const struct tcphdr*)ip.Payload();
if ( tp->th_flags & f.tcp_flags ) if ( tp->th_flags & f.tcp_flags )
// At least one of the flags is set, so don't drop // At least one of the flags is set, so don't drop
@ -118,4 +119,4 @@ bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip,
return util::detail::random_number() < f.probability; return util::detail::random_number() < f.probability;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -7,17 +7,20 @@
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
#include "zeek/PrefixTable.h" #include "zeek/PrefixTable.h"
namespace zeek { namespace zeek
{
class IP_Hdr; class IP_Hdr;
class Val; class Val;
namespace detail { namespace detail
{
class PacketFilter { class PacketFilter
{
public: public:
explicit PacketFilter(bool arg_default); explicit PacketFilter(bool arg_default);
~PacketFilter() {} ~PacketFilter() { }
// Drops all packets from a particular source (which may be given // Drops all packets from a particular source (which may be given
// as an AddrVal or a SubnetVal) which hasn't any of TCP flags set // as an AddrVal or a SubnetVal) which hasn't any of TCP flags set
@ -38,7 +41,8 @@ public:
bool Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen); bool Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen);
private: private:
struct Filter { struct Filter
{
uint32_t tcp_flags; uint32_t tcp_flags;
double probability; double probability;
}; };
@ -50,7 +54,7 @@ private:
bool default_match; bool default_match;
PrefixTable src_filter; PrefixTable src_filter;
PrefixTable dst_filter; PrefixTable dst_filter;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -2,14 +2,15 @@
#include "zeek/Pipe.h" #include "zeek/Pipe.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio> #include <cstdio>
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
namespace zeek::detail { namespace zeek::detail
{
static void pipe_fail(int eno) static void pipe_fail(int eno)
{ {
@ -88,8 +89,7 @@ static int dup_or_fail(int fd, int flags, int status_flags)
return rval; return rval;
} }
Pipe::Pipe(int flags0, int flags1, int status_flags0, int status_flags1, Pipe::Pipe(int flags0, int flags1, int status_flags0, int status_flags1, int* arg_fds)
int* arg_fds)
{ {
if ( arg_fds ) if ( arg_fds )
{ {
@ -159,4 +159,4 @@ PipePair::PipePair(int flags, int status_flags, int* fds)
{ {
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,11 +2,12 @@
#pragma once #pragma once
namespace zeek::detail { namespace zeek::detail
{
class Pipe { class Pipe
{
public: public:
/** /**
* Create a pair of file descriptors via pipe(), or aborts if it cannot. * Create a pair of file descriptors via pipe(), or aborts if it cannot.
* @param flags0 file descriptor flags to set on read end of pipe. * @param flags0 file descriptor flags to set on read end of pipe.
@ -17,8 +18,8 @@ public:
* than create ones from a new pipe. Should point to memory containing * than create ones from a new pipe. Should point to memory containing
* two consecutive file descriptors, the "read" one and then the "write" one. * two consecutive file descriptors, the "read" one and then the "write" one.
*/ */
explicit Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0, explicit Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0, int status_flags1 = 0,
int status_flags1 = 0, int* fds = nullptr); int* fds = nullptr);
/** /**
* Close the pair of file descriptors owned by the object. * Close the pair of file descriptors owned by the object.
@ -39,14 +40,12 @@ public:
/** /**
* @return the file descriptor associated with the read-end of the pipe. * @return the file descriptor associated with the read-end of the pipe.
*/ */
int ReadFD() const int ReadFD() const { return fds[0]; }
{ return fds[0]; }
/** /**
* @return the file descriptor associated with the write-end of the pipe. * @return the file descriptor associated with the write-end of the pipe.
*/ */
int WriteFD() const int WriteFD() const { return fds[1]; }
{ return fds[1]; }
/** /**
* Sets the given file descriptor flags for both the read and write end * Sets the given file descriptor flags for both the read and write end
@ -64,14 +63,14 @@ private:
int fds[2]; int fds[2];
int flags[2]; int flags[2];
int status_flags[2]; int status_flags[2];
}; };
/** /**
* A pair of pipes that can be used for bi-directinoal IPC. * A pair of pipes that can be used for bi-directinoal IPC.
*/ */
class PipePair { class PipePair
{
public: public:
/** /**
* Create a pair of pipes * Create a pair of pipes
* @param flags file descriptor flags to set on pipes * @param flags file descriptor flags to set on pipes
@ -87,53 +86,45 @@ public:
/** /**
* @return the pipe used for receiving input * @return the pipe used for receiving input
*/ */
Pipe& In() Pipe& In() { return pipes[swapped]; }
{ return pipes[swapped]; }
/** /**
* @return the pipe used for sending output * @return the pipe used for sending output
*/ */
Pipe& Out() Pipe& Out() { return pipes[! swapped]; }
{ return pipes[!swapped]; }
/** /**
* @return the pipe used for receiving input * @return the pipe used for receiving input
*/ */
const Pipe& In() const const Pipe& In() const { return pipes[swapped]; }
{ return pipes[swapped]; }
/** /**
* @return the pipe used for sending output * @return the pipe used for sending output
*/ */
const Pipe& Out() const const Pipe& Out() const { return pipes[! swapped]; }
{ return pipes[!swapped]; }
/** /**
* @return a file descriptor that may used for receiving messages by * @return a file descriptor that may used for receiving messages by
* polling/reading it. * polling/reading it.
*/ */
int InFD() const int InFD() const { return In().ReadFD(); }
{ return In().ReadFD(); }
/** /**
* @return a file descriptor that may be used for sending messages by * @return a file descriptor that may be used for sending messages by
* writing to it. * writing to it.
*/ */
int OutFD() const int OutFD() const { return Out().WriteFD(); }
{ return Out().WriteFD(); }
/** /**
* Swaps the meaning of the pipes in the pair. E.g. call this after * Swaps the meaning of the pipes in the pair. E.g. call this after
* fork()'ing so that the child process uses the right pipe for * fork()'ing so that the child process uses the right pipe for
* reading/writing. * reading/writing.
*/ */
void Swap() void Swap() { swapped = ! swapped; }
{ swapped = ! swapped; }
private: private:
Pipe pipes[2]; Pipe pipes[2];
bool swapped = false; bool swapped = false;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,35 +1,44 @@
#include "zeek/zeek-config.h"
#include "zeek/PolicyFile.h" #include "zeek/PolicyFile.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include "zeek/Debug.h" #include "zeek/Debug.h"
#include "zeek/util.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/util.h"
#include "zeek/zeek-config.h"
using namespace std; using namespace std;
struct PolicyFile { struct PolicyFile
PolicyFile () { filedata = nullptr; lmtime = 0; } {
~PolicyFile () { delete [] filedata; filedata = nullptr; } PolicyFile()
{
filedata = nullptr;
lmtime = 0;
}
~PolicyFile()
{
delete[] filedata;
filedata = nullptr;
}
time_t lmtime; time_t lmtime;
char* filedata; char* filedata;
vector<const char*> lines; vector<const char*> lines;
}; };
typedef map<string, PolicyFile*> PolicyFileMap; typedef map<string, PolicyFile*> PolicyFileMap;
static PolicyFileMap policy_files; static PolicyFileMap policy_files;
namespace zeek::detail { namespace zeek::detail
{
int how_many_lines_in(const char* policy_filename) int how_many_lines_in(const char* policy_filename)
{ {
@ -97,7 +106,7 @@ bool LoadPolicyFileText(const char* policy_filename)
// ### This code is not necessarily Unicode safe! // ### This code is not necessarily Unicode safe!
// (probably fine with UTF-8) // (probably fine with UTF-8)
pf->filedata = new char[size+1]; pf->filedata = new char[size + 1];
if ( fread(pf->filedata, size, 1, f) != 1 ) if ( fread(pf->filedata, size, 1, f) != 1 )
reporter->InternalError("Failed to fread() file data"); reporter->InternalError("Failed to fread() file data");
pf->filedata[size] = 0; pf->filedata[size] = 0;
@ -122,8 +131,8 @@ bool LoadPolicyFileText(const char* policy_filename)
} }
// REMEMBER: line number arguments are indexed from 0. // REMEMBER: line number arguments are indexed from 0.
bool PrintLines(const char* policy_filename, unsigned int start_line, bool PrintLines(const char* policy_filename, unsigned int start_line, unsigned int how_many_lines,
unsigned int how_many_lines, bool show_numbers) bool show_numbers)
{ {
if ( ! policy_filename ) if ( ! policy_filename )
return true; return true;
@ -157,8 +166,8 @@ bool PrintLines(const char* policy_filename, unsigned int start_line,
if ( start_line > pf->lines.size() ) if ( start_line > pf->lines.size() )
{ {
debug_msg("Line number %d out of range; %s has %d lines\n", debug_msg("Line number %d out of range; %s has %d lines\n", start_line, policy_filename,
start_line, policy_filename, int(pf->lines.size())); int(pf->lines.size()));
return false; return false;
} }
@ -177,4 +186,4 @@ bool PrintLines(const char* policy_filename, unsigned int start_line,
return true; return true;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -14,14 +14,15 @@
// policy_filename arguments should be absolute or relative paths; // policy_filename arguments should be absolute or relative paths;
// no expansion is done. // no expansion is done.
namespace zeek::detail { namespace zeek::detail
{
int how_many_lines_in(const char* policy_filename); int how_many_lines_in(const char* policy_filename);
bool LoadPolicyFileText(const char* policy_filename); bool LoadPolicyFileText(const char* policy_filename);
// start_line is 1-based (the intuitive way) // start_line is 1-based (the intuitive way)
bool PrintLines(const char* policy_filename, unsigned int start_line, bool PrintLines(const char* policy_filename, unsigned int start_line, unsigned int how_many_lines,
unsigned int how_many_lines, bool show_numbers); bool show_numbers);
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,12 +1,14 @@
#include "zeek/PrefixTable.h" #include "zeek/PrefixTable.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/Val.h" #include "zeek/Val.h"
namespace zeek::detail { namespace zeek::detail
{
prefix_t* PrefixTable::MakePrefix(const IPAddr& addr, int width) prefix_t* PrefixTable::MakePrefix(const IPAddr& addr, int width)
{ {
prefix_t* prefix = (prefix_t*) util::safe_malloc(sizeof(prefix_t)); prefix_t* prefix = (prefix_t*)util::safe_malloc(sizeof(prefix_t));
addr.CopyIPv6(&prefix->add.sin6); addr.CopyIPv6(&prefix->add.sin6);
prefix->family = AF_INET6; prefix->family = AF_INET6;
@ -18,8 +20,9 @@ prefix_t* PrefixTable::MakePrefix(const IPAddr& addr, int width)
IPPrefix PrefixTable::PrefixToIPPrefix(prefix_t* prefix) IPPrefix PrefixTable::PrefixToIPPrefix(prefix_t* prefix)
{ {
return IPPrefix(IPAddr(IPv6, reinterpret_cast<const uint32_t*>(&prefix->add.sin6), return IPPrefix(
IPAddr::Network), prefix->bitlen, true); IPAddr(IPv6, reinterpret_cast<const uint32_t*>(&prefix->add.sin6), IPAddr::Network),
prefix->bitlen, true);
} }
void* PrefixTable::Insert(const IPAddr& addr, int width, void* data) void* PrefixTable::Insert(const IPAddr& addr, int width, void* data)
@ -46,18 +49,17 @@ void* PrefixTable::Insert(const IPAddr& addr, int width, void* data)
void* PrefixTable::Insert(const Val* value, void* data) void* PrefixTable::Insert(const Val* value, void* data)
{ {
// [elem] -> elem // [elem] -> elem
if ( value->GetType()->Tag() == TYPE_LIST && if ( value->GetType()->Tag() == TYPE_LIST && value->AsListVal()->Length() == 1 )
value->AsListVal()->Length() == 1 )
value = value->AsListVal()->Idx(0).get(); value = value->AsListVal()->Idx(0).get();
switch ( value->GetType()->Tag() ) { switch ( value->GetType()->Tag() )
{
case TYPE_ADDR: case TYPE_ADDR:
return Insert(value->AsAddr(), 128, data); return Insert(value->AsAddr(), 128, data);
break; break;
case TYPE_SUBNET: case TYPE_SUBNET:
return Insert(value->AsSubNet().Prefix(), return Insert(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6(), data);
value->AsSubNet().LengthIPv6(), data);
break; break;
default: default:
@ -66,9 +68,9 @@ void* PrefixTable::Insert(const Val* value, void* data)
} }
} }
std::list<std::tuple<IPPrefix,void*>> PrefixTable::FindAll(const IPAddr& addr, int width) const std::list<std::tuple<IPPrefix, void*>> PrefixTable::FindAll(const IPAddr& addr, int width) const
{ {
std::list<std::tuple<IPPrefix,void*>> out; std::list<std::tuple<IPPrefix, void*>> out;
prefix_t* prefix = MakePrefix(addr, width); prefix_t* prefix = MakePrefix(addr, width);
int elems = 0; int elems = 0;
@ -84,7 +86,7 @@ std::list<std::tuple<IPPrefix,void*>> PrefixTable::FindAll(const IPAddr& addr, i
return out; return out;
} }
std::list<std::tuple<IPPrefix,void*>> PrefixTable::FindAll(const SubNetVal* value) const std::list<std::tuple<IPPrefix, void*>> PrefixTable::FindAll(const SubNetVal* value) const
{ {
return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6()); return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6());
} }
@ -93,8 +95,7 @@ void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const
{ {
prefix_t* prefix = MakePrefix(addr, width); prefix_t* prefix = MakePrefix(addr, width);
patricia_node_t* node = patricia_node_t* node =
exact ? patricia_search_exact(tree, prefix) : exact ? patricia_search_exact(tree, prefix) : patricia_search_best(tree, prefix);
patricia_search_best(tree, prefix);
int elems = 0; int elems = 0;
patricia_node_t** list = nullptr; patricia_node_t** list = nullptr;
@ -106,18 +107,17 @@ void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const
void* PrefixTable::Lookup(const Val* value, bool exact) const void* PrefixTable::Lookup(const Val* value, bool exact) const
{ {
// [elem] -> elem // [elem] -> elem
if ( value->GetType()->Tag() == TYPE_LIST && if ( value->GetType()->Tag() == TYPE_LIST && value->AsListVal()->Length() == 1 )
value->AsListVal()->Length() == 1 )
value = value->AsListVal()->Idx(0).get(); value = value->AsListVal()->Idx(0).get();
switch ( value->GetType()->Tag() ) { switch ( value->GetType()->Tag() )
{
case TYPE_ADDR: case TYPE_ADDR:
return Lookup(value->AsAddr(), 128, exact); return Lookup(value->AsAddr(), 128, exact);
break; break;
case TYPE_SUBNET: case TYPE_SUBNET:
return Lookup(value->AsSubNet().Prefix(), return Lookup(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6(), exact);
value->AsSubNet().LengthIPv6(), exact);
break; break;
default: default:
@ -145,18 +145,17 @@ void* PrefixTable::Remove(const IPAddr& addr, int width)
void* PrefixTable::Remove(const Val* value) void* PrefixTable::Remove(const Val* value)
{ {
// [elem] -> elem // [elem] -> elem
if ( value->GetType()->Tag() == TYPE_LIST && if ( value->GetType()->Tag() == TYPE_LIST && value->AsListVal()->Length() == 1 )
value->AsListVal()->Length() == 1 )
value = value->AsListVal()->Idx(0).get(); value = value->AsListVal()->Idx(0).get();
switch ( value->GetType()->Tag() ) { switch ( value->GetType()->Tag() )
{
case TYPE_ADDR: case TYPE_ADDR:
return Remove(value->AsAddr(), 128); return Remove(value->AsAddr(), 128);
break; break;
case TYPE_SUBNET: case TYPE_SUBNET:
return Remove(value->AsSubNet().Prefix(), return Remove(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6());
value->AsSubNet().LengthIPv6());
break; break;
default: default:
@ -184,7 +183,7 @@ void* PrefixTable::GetNext(iterator* i)
if ( i->Xrn->l ) if ( i->Xrn->l )
{ {
if (i->Xrn->r) if ( i->Xrn->r )
*i->Xsp++ = i->Xrn->r; *i->Xsp++ = i->Xrn->r;
i->Xrn = i->Xrn->l; i->Xrn = i->Xrn->l;
@ -193,17 +192,17 @@ void* PrefixTable::GetNext(iterator* i)
else if ( i->Xrn->r ) else if ( i->Xrn->r )
i->Xrn = i->Xrn->r; i->Xrn = i->Xrn->r;
else if (i->Xsp != i->Xstack) else if ( i->Xsp != i->Xstack )
i->Xrn = *(--i->Xsp); i->Xrn = *(--i->Xsp);
else else
i->Xrn = (patricia_node_t*) nullptr; i->Xrn = (patricia_node_t*)nullptr;
if ( i->Xnode->prefix ) if ( i->Xnode->prefix )
return (void*) i->Xnode->data; return (void*)i->Xnode->data;
} }
// Not reached. // Not reached.
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,32 +1,41 @@
#pragma once #pragma once
extern "C" { extern "C"
#include "zeek/patricia.h" {
} #include "zeek/patricia.h"
}
#include <tuple>
#include <list> #include <list>
#include <tuple>
#include "zeek/IPAddr.h" #include "zeek/IPAddr.h"
namespace zeek { namespace zeek
{
class Val; class Val;
class SubNetVal; class SubNetVal;
namespace detail { namespace detail
{
class PrefixTable { class PrefixTable
{
private: private:
struct iterator { struct iterator
patricia_node_t* Xstack[PATRICIA_MAXBITS+1]; {
patricia_node_t* Xstack[PATRICIA_MAXBITS + 1];
patricia_node_t** Xsp; patricia_node_t** Xsp;
patricia_node_t* Xrn; patricia_node_t* Xrn;
patricia_node_t* Xnode; patricia_node_t* Xnode;
}; };
public: public:
PrefixTable() { tree = New_Patricia(128); delete_function = nullptr; } PrefixTable()
{
tree = New_Patricia(128);
delete_function = nullptr;
}
~PrefixTable() { Destroy_Patricia(tree, delete_function); } ~PrefixTable() { Destroy_Patricia(tree, delete_function); }
// Addr in network byte order. If data is zero, acts like a set. // Addr in network byte order. If data is zero, acts like a set.
@ -65,7 +74,7 @@ private:
patricia_tree_t* tree; patricia_tree_t* tree;
data_fn_t delete_function; data_fn_t delete_function;
}; };
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,6 +1,5 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/PriorityQueue.h" #include "zeek/PriorityQueue.h"
#include <stdio.h> #include <stdio.h>
@ -8,8 +7,10 @@
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/util.h" #include "zeek/util.h"
#include "zeek/zeek-config.h"
namespace zeek::detail { namespace zeek::detail
{
PriorityQueue::PriorityQueue(int initial_size) : max_heap_size(initial_size) PriorityQueue::PriorityQueue(int initial_size) : max_heap_size(initial_size)
{ {
@ -21,7 +22,7 @@ PriorityQueue::~PriorityQueue()
for ( int i = 0; i < heap_size; ++i ) for ( int i = 0; i < heap_size; ++i )
delete heap[i]; delete heap[i];
delete [] heap; delete[] heap;
} }
PQ_Element* PriorityQueue::Remove() PQ_Element* PriorityQueue::Remove()
@ -41,8 +42,7 @@ PQ_Element* PriorityQueue::Remove()
PQ_Element* PriorityQueue::Remove(PQ_Element* e) PQ_Element* PriorityQueue::Remove(PQ_Element* e)
{ {
if ( e->Offset() < 0 || e->Offset() >= heap_size || if ( e->Offset() < 0 || e->Offset() >= heap_size || heap[e->Offset()] != e )
heap[e->Offset()] != e )
return nullptr; // not in heap return nullptr; // not in heap
e->MinimizeTime(); e->MinimizeTime();
@ -79,7 +79,7 @@ bool PriorityQueue::Resize(int new_size)
for ( int i = 0; i < max_heap_size; ++i ) for ( int i = 0; i < max_heap_size; ++i )
tmp[i] = heap[i]; tmp[i] = heap[i];
delete [] heap; delete[] heap;
heap = tmp; heap = tmp;
max_heap_size = new_size; max_heap_size = new_size;
@ -138,4 +138,4 @@ void PriorityQueue::BubbleDown(int bin)
} }
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -2,18 +2,20 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
namespace zeek::detail { #include "zeek/zeek-config.h"
namespace zeek::detail
{
class PriorityQueue; class PriorityQueue;
class PQ_Element { class PQ_Element
{
public: public:
explicit PQ_Element(double t) : time(t) {} explicit PQ_Element(double t) : time(t) { }
virtual ~PQ_Element() = default; virtual ~PQ_Element() = default;
double Time() const { return time; } double Time() const { return time; }
@ -27,9 +29,10 @@ protected:
PQ_Element() = default; PQ_Element() = default;
double time = 0.0; double time = 0.0;
int offset = -1; int offset = -1;
}; };
class PriorityQueue { class PriorityQueue
{
public: public:
explicit PriorityQueue(int initial_size = 16); explicit PriorityQueue(int initial_size = 16);
~PriorityQueue(); ~PriorityQueue();
@ -65,20 +68,11 @@ protected:
void BubbleUp(int bin); void BubbleUp(int bin);
void BubbleDown(int bin); void BubbleDown(int bin);
int Parent(int bin) const int Parent(int bin) const { return bin >> 1; }
{
return bin >> 1;
}
int LeftChild(int bin) const int LeftChild(int bin) const { return bin << 1; }
{
return bin << 1;
}
int RightChild(int bin) const int RightChild(int bin) const { return LeftChild(bin) + 1; }
{
return LeftChild(bin) + 1;
}
void SetElement(int bin, PQ_Element* e) void SetElement(int bin, PQ_Element* e)
{ {
@ -98,6 +92,6 @@ protected:
int peak_heap_size = 0; int peak_heap_size = 0;
int max_heap_size = 0; int max_heap_size = 0;
uint64_t cumulative_num = 0; uint64_t cumulative_num = 0;
}; };
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -23,10 +23,13 @@
// Entries must be either a pointer to the data or nonzero data with // Entries must be either a pointer to the data or nonzero data with
// sizeof(data) <= sizeof(void*). // sizeof(data) <= sizeof(void*).
namespace zeek { namespace zeek
{
template<typename T> template <typename T>
class [[deprecated("Remove in v5.1. This class is deprecated (and is likely broken, see #1528). Use std::vector<T>.")]] Queue { class [[deprecated("Remove in v5.1. This class is deprecated (and is likely broken, see #1528). "
"Use std::vector<T>.")]] Queue
{
public: public:
explicit Queue(int size = 0) explicit Queue(int size = 0)
{ {
@ -42,7 +45,7 @@ public:
} }
else else
{ {
if ( (entries = new T[chunk_size+1]) ) if ( (entries = new T[chunk_size + 1]) )
max_entries = chunk_size; max_entries = chunk_size;
else else
{ {
@ -66,22 +69,19 @@ public:
// Note, allocate extra space, so that we can always // Note, allocate extra space, so that we can always
// use the [max_entries] element. // use the [max_entries] element.
// ### Yin, why not use realloc()? // ### Yin, why not use realloc()?
T* new_entries = new T[new_size+1]; T* new_entries = new T[new_size + 1];
if ( new_entries ) if ( new_entries )
{ {
if ( head <= tail ) if ( head <= tail )
memcpy( new_entries, entries + head, memcpy(new_entries, entries + head, sizeof(T) * num_entries);
sizeof(T) * num_entries );
else else
{ {
int len = num_entries - tail; int len = num_entries - tail;
memcpy( new_entries, entries + head, memcpy(new_entries, entries + head, sizeof(T) * len);
sizeof(T) * len ); memcpy(new_entries + len, entries, sizeof(T) * tail);
memcpy( new_entries + len, entries,
sizeof(T) * tail );
} }
delete [] entries; delete[] entries;
entries = new_entries; entries = new_entries;
max_entries = new_size; max_entries = new_size;
head = 0; head = 0;
@ -108,7 +108,7 @@ public:
{ {
if ( num_entries == max_entries ) if ( num_entries == max_entries )
{ {
resize(max_entries+chunk_size); // make more room resize(max_entries + chunk_size); // make more room
chunk_size *= 2; chunk_size *= 2;
} }
@ -126,7 +126,7 @@ public:
{ {
if ( num_entries == max_entries ) if ( num_entries == max_entries )
{ {
resize(max_entries+chunk_size); // make more room resize(max_entries + chunk_size); // make more room
chunk_size *= 2; chunk_size *= 2;
} }
@ -187,7 +187,6 @@ public:
const_reverse_iterator crend() const { return rend(); } const_reverse_iterator crend() const { return rend(); }
protected: protected:
T* entries; T* entries;
int chunk_size; // increase size by this amount when necessary int chunk_size; // increase size by this amount when necessary
int max_entries; // entry's index range: 0 .. max_entries int max_entries; // entry's index range: 0 .. max_entries
@ -196,8 +195,8 @@ protected:
int tail; // just beyond the end of the queue in the ring int tail; // just beyond the end of the queue in the ring
}; };
template <typename T>
using PQueue [[deprecated("Remove in v5.1. This class is deprecated (and is likely broken, see "
"#1528). Use std::vector<T*>.")]] = Queue<T*>;
template<typename T> } // namespace zeek
using PQueue [[deprecated("Remove in v5.1. This class is deprecated (and is likely broken, see #1528). Use std::vector<T*>.")]] = Queue<T*>;
} // namespace zeek

View file

@ -1,16 +1,16 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/RE.h" #include "zeek/RE.h"
#include <stdlib.h> #include <stdlib.h>
#include <utility> #include <utility>
#include "zeek/DFA.h"
#include "zeek/CCL.h" #include "zeek/CCL.h"
#include "zeek/DFA.h"
#include "zeek/EquivClass.h" #include "zeek/EquivClass.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
#include "zeek/ZeekString.h" #include "zeek/ZeekString.h"
#include "zeek/zeek-config.h"
zeek::detail::CCL* zeek::detail::curr_ccl = nullptr; zeek::detail::CCL* zeek::detail::curr_ccl = nullptr;
zeek::detail::Specific_RE_Matcher* zeek::detail::rem = nullptr; zeek::detail::Specific_RE_Matcher* zeek::detail::rem = nullptr;
@ -21,11 +21,13 @@ extern int RE_parse(void);
extern void RE_set_input(const char* str); extern void RE_set_input(const char* str);
extern void RE_done_with_scan(); extern void RE_done_with_scan();
namespace zeek { namespace zeek
namespace detail { {
namespace detail
{
Specific_RE_Matcher::Specific_RE_Matcher(match_type arg_mt, int arg_multiline) Specific_RE_Matcher::Specific_RE_Matcher(match_type arg_mt, int arg_multiline)
: equiv_class(NUM_SYM) : equiv_class(NUM_SYM)
{ {
mt = arg_mt; mt = arg_mt;
multiline = arg_multiline; multiline = arg_multiline;
@ -42,7 +44,7 @@ Specific_RE_Matcher::~Specific_RE_Matcher()
delete ccl_list[i]; delete ccl_list[i];
Unref(dfa); Unref(dfa);
delete [] pattern_text; delete[] pattern_text;
delete accepted; delete accepted;
} }
@ -84,8 +86,7 @@ void Specific_RE_Matcher::AddExactPat(const char* new_pat)
AddPat(new_pat, "^?(%s)$?", "(%s)|(^?(%s)$?)"); AddPat(new_pat, "^?(%s)$?", "(%s)|(^?(%s)$?)");
} }
void Specific_RE_Matcher::AddPat(const char* new_pat, void Specific_RE_Matcher::AddPat(const char* new_pat, const char* orig_fmt, const char* app_fmt)
const char* orig_fmt, const char* app_fmt)
{ {
int n = strlen(new_pat); int n = strlen(new_pat);
@ -101,7 +102,7 @@ void Specific_RE_Matcher::AddPat(const char* new_pat,
else else
sprintf(s, orig_fmt, new_pat); sprintf(s, orig_fmt, new_pat);
delete [] pattern_text; delete[] pattern_text;
pattern_text = s; pattern_text = s;
} }
@ -114,7 +115,7 @@ void Specific_RE_Matcher::MakeCaseInsensitive()
snprintf(s, n + 5, fmt, pattern_text); snprintf(s, n + 5, fmt, pattern_text);
delete [] pattern_text; delete[] pattern_text;
pattern_text = s; pattern_text = s;
} }
@ -186,7 +187,7 @@ bool Specific_RE_Matcher::CompileSet(const string_list& set, const int_list& idx
nfa = new NFA_Machine(new NFA_State(SYM_BOL, rem->EC())); nfa = new NFA_Machine(new NFA_State(SYM_BOL, rem->EC()));
nfa->MakeOptional(); nfa->MakeOptional();
if ( set_nfa ) if ( set_nfa )
nfa->AppendMachine( set_nfa ); nfa->AppendMachine(set_nfa);
EC()->BuildECs(); EC()->BuildECs();
ConvertCCLs(); ConvertCCLs();
@ -262,7 +263,6 @@ bool Specific_RE_Matcher::MatchAll(const u_char* bv, int n)
return d && d->Accept() != nullptr; return d && d->Accept() != nullptr;
} }
int Specific_RE_Matcher::Match(const u_char* bv, int n) int Specific_RE_Matcher::Match(const u_char* bv, int n)
{ {
if ( ! dfa ) if ( ! dfa )
@ -272,7 +272,8 @@ int Specific_RE_Matcher::Match(const u_char* bv, int n)
DFA_State* d = dfa->StartState(); DFA_State* d = dfa->StartState();
d = d->Xtion(ecs[SYM_BOL], dfa); d = d->Xtion(ecs[SYM_BOL], dfa);
if ( ! d ) return 0; if ( ! d )
return 0;
for ( int i = 0; i < n; ++i ) for ( int i = 0; i < n; ++i )
{ {
@ -295,14 +296,12 @@ int Specific_RE_Matcher::Match(const u_char* bv, int n)
return 0; return 0;
} }
void Specific_RE_Matcher::Dump(FILE* f) void Specific_RE_Matcher::Dump(FILE* f)
{ {
dfa->Dump(f); dfa->Dump(f);
} }
inline void RE_Match_State::AddMatches(const AcceptingSet& as, inline void RE_Match_State::AddMatches(const AcceptingSet& as, MatchPos position)
MatchPos position)
{ {
typedef std::pair<AcceptIdx, MatchPos> am_idx; typedef std::pair<AcceptIdx, MatchPos> am_idx;
@ -310,8 +309,7 @@ inline void RE_Match_State::AddMatches(const AcceptingSet& as,
accepted_matches.insert(am_idx(*it, position)); accepted_matches.insert(am_idx(*it, position));
} }
bool RE_Match_State::Match(const u_char* bv, int n, bool RE_Match_State::Match(const u_char* bv, int n, bool bol, bool eol, bool clear)
bool bol, bool eol, bool clear)
{ {
if ( current_pos == -1 ) if ( current_pos == -1 )
{ {
@ -352,7 +350,7 @@ bool RE_Match_State::Match(const u_char* bv, int n,
else else
ec = ecs[*(bv++)]; ec = ecs[*(bv++)];
DFA_State* next_state = current_state->Xtion(ec,dfa); DFA_State* next_state = current_state->Xtion(ec, dfa);
if ( ! next_state ) if ( ! next_state )
{ {
@ -425,7 +423,8 @@ unsigned int Specific_RE_Matcher::MemoryAllocation() const
size += util::pad_size(sizeof(CCL*) * ccl_dict.size()); size += util::pad_size(sizeof(CCL*) * ccl_dict.size());
for ( const auto& entry : ccl_dict ) for ( const auto& entry : ccl_dict )
{ {
size += padded_sizeof(std::string) + util::pad_size(sizeof(std::string::value_type) * entry.first.size()); size += padded_sizeof(std::string) +
util::pad_size(sizeof(std::string::value_type) * entry.first.size());
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
size += entry.second->MemoryAllocation(); size += entry.second->MemoryAllocation();
@ -434,36 +433,36 @@ unsigned int Specific_RE_Matcher::MemoryAllocation() const
for ( const auto& entry : defs ) for ( const auto& entry : defs )
{ {
size += padded_sizeof(std::string) + util::pad_size(sizeof(std::string::value_type) * entry.first.size()); size += padded_sizeof(std::string) +
size += padded_sizeof(std::string) + util::pad_size(sizeof(std::string::value_type) * entry.second.size()); util::pad_size(sizeof(std::string::value_type) * entry.first.size());
size += padded_sizeof(std::string) +
util::pad_size(sizeof(std::string::value_type) * entry.second.size());
} }
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return size + padded_sizeof(*this) return size + padded_sizeof(*this) +
+ (pattern_text ? util::pad_size(strlen(pattern_text) + 1) : 0) (pattern_text ? util::pad_size(strlen(pattern_text) + 1) : 0) +
+ ccl_list.MemoryAllocation() - padded_sizeof(ccl_list) ccl_list.MemoryAllocation() - padded_sizeof(ccl_list) + equiv_class.Size() -
+ equiv_class.Size() - padded_sizeof(EquivClass) padded_sizeof(EquivClass) +
+ (dfa ? dfa->MemoryAllocation() : 0) // this is ref counted; consider the bytes here? (dfa ? dfa->MemoryAllocation() : 0) // this is ref counted; consider the bytes here?
+ padded_sizeof(*any_ccl) + padded_sizeof(*any_ccl) + padded_sizeof(*accepted) // NOLINT(bugprone-sizeof-container)
+ padded_sizeof(*accepted) // NOLINT(bugprone-sizeof-container)
+ accepted->size() * padded_sizeof(AcceptingSet::key_type); + accepted->size() * padded_sizeof(AcceptingSet::key_type);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
static RE_Matcher* matcher_merge(const RE_Matcher* re1, const RE_Matcher* re2, static RE_Matcher* matcher_merge(const RE_Matcher* re1, const RE_Matcher* re2, const char* merge_op)
const char* merge_op)
{ {
const char* text1 = re1->PatternText(); const char* text1 = re1->PatternText();
const char* text2 = re2->PatternText(); const char* text2 = re2->PatternText();
int n = strlen(text1) + strlen(text2) + strlen(merge_op) + 32 /* slop */ ; int n = strlen(text1) + strlen(text2) + strlen(merge_op) + 32 /* slop */;
char* merge_text = new char[n]; char* merge_text = new char[n];
snprintf(merge_text, n, "(%s)%s(%s)", text1, merge_op, text2); snprintf(merge_text, n, "(%s)%s(%s)", text1, merge_op, text2);
RE_Matcher* merge = new RE_Matcher(merge_text); RE_Matcher* merge = new RE_Matcher(merge_text);
delete [] merge_text; delete[] merge_text;
merge->Compile(); merge->Compile();
@ -480,7 +479,7 @@ RE_Matcher* RE_Matcher_disjunction(const RE_Matcher* re1, const RE_Matcher* re2)
return matcher_merge(re1, re2, "|"); return matcher_merge(re1, re2, "|");
} }
} // namespace detail } // namespace detail
RE_Matcher::RE_Matcher() RE_Matcher::RE_Matcher()
{ {
@ -529,4 +528,4 @@ bool RE_Matcher::Compile(bool lazy)
return re_anywhere->Compile(lazy) && re_exact->Compile(lazy); return re_anywhere->Compile(lazy) && re_exact->Compile(lazy);
} }
} // namespace zeek } // namespace zeek

View file

@ -2,27 +2,29 @@
#pragma once #pragma once
#include <sys/types.h> // for u_char
#include <ctype.h> #include <ctype.h>
#include <set> #include <sys/types.h> // for u_char
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "zeek/List.h"
#include "zeek/CCL.h" #include "zeek/CCL.h"
#include "zeek/EquivClass.h" #include "zeek/EquivClass.h"
#include "zeek/List.h"
typedef int (*cce_func)(int); typedef int (*cce_func)(int);
// This method is automatically generated by flex and shouldn't be namespaced // This method is automatically generated by flex and shouldn't be namespaced
extern int re_lex(void); extern int re_lex(void);
namespace zeek { namespace zeek
{
class String; class String;
class RE_Matcher; class RE_Matcher;
namespace detail { namespace detail
{
class NFA_Machine; class NFA_Machine;
class DFA_Machine; class DFA_Machine;
@ -45,14 +47,19 @@ using MatchPos = uint64_t;
using AcceptingMatchSet = std::map<AcceptIdx, MatchPos>; using AcceptingMatchSet = std::map<AcceptIdx, MatchPos>;
using string_list = name_list; using string_list = name_list;
enum match_type { MATCH_ANYWHERE, MATCH_EXACTLY }; enum match_type
{
MATCH_ANYWHERE,
MATCH_EXACTLY
};
// A "specific" RE matcher will match one type of pattern: either // A "specific" RE matcher will match one type of pattern: either
// MATCH_ANYWHERE or MATCH_EXACTLY. // MATCH_ANYWHERE or MATCH_EXACTLY.
class Specific_RE_Matcher { class Specific_RE_Matcher
{
public: public:
explicit Specific_RE_Matcher(match_type mt, int multiline=0); explicit Specific_RE_Matcher(match_type mt, int multiline = 0);
~Specific_RE_Matcher(); ~Specific_RE_Matcher();
void AddPat(const char* pat); void AddPat(const char* pat);
@ -115,8 +122,9 @@ public:
void Dump(FILE* f); void Dump(FILE* f);
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const; "GHI-572.")]] unsigned int
MemoryAllocation() const;
protected: protected:
void AddAnywherePat(const char* pat); void AddAnywherePat(const char* pat);
@ -142,9 +150,10 @@ protected:
DFA_Machine* dfa; DFA_Machine* dfa;
CCL* any_ccl; CCL* any_ccl;
AcceptingSet* accepted; AcceptingSet* accepted;
}; };
class RE_Match_State { class RE_Match_State
{
public: public:
explicit RE_Match_State(Specific_RE_Matcher* matcher) explicit RE_Match_State(Specific_RE_Matcher* matcher)
{ {
@ -154,8 +163,7 @@ public:
current_state = nullptr; current_state = nullptr;
} }
const AcceptingMatchSet& AcceptedMatches() const const AcceptingMatchSet& AcceptedMatches() const { return accepted_matches; }
{ return accepted_matches; }
// Returns the number of bytes feeded into the matcher so far // Returns the number of bytes feeded into the matcher so far
int Length() { return current_pos; } int Length() { return current_pos; }
@ -180,14 +188,15 @@ protected:
AcceptingMatchSet accepted_matches; AcceptingMatchSet accepted_matches;
DFA_State* current_state; DFA_State* current_state;
int current_pos; int current_pos;
}; };
extern RE_Matcher* RE_Matcher_conjunction(const RE_Matcher* re1, const RE_Matcher* re2); extern RE_Matcher* RE_Matcher_conjunction(const RE_Matcher* re1, const RE_Matcher* re2);
extern RE_Matcher* RE_Matcher_disjunction(const RE_Matcher* re1, const RE_Matcher* re2); extern RE_Matcher* RE_Matcher_disjunction(const RE_Matcher* re1, const RE_Matcher* re2);
} // namespace detail } // namespace detail
class RE_Matcher final { class RE_Matcher final
{
public: public:
RE_Matcher(); RE_Matcher();
explicit RE_Matcher(const char* pat); explicit RE_Matcher(const char* pat);
@ -203,28 +212,21 @@ public:
bool Compile(bool lazy = false); bool Compile(bool lazy = false);
// Returns true if s exactly matches the pattern, false otherwise. // Returns true if s exactly matches the pattern, false otherwise.
bool MatchExactly(const char* s) bool MatchExactly(const char* s) { return re_exact->MatchAll(s); }
{ return re_exact->MatchAll(s); } bool MatchExactly(const String* s) { return re_exact->MatchAll(s); }
bool MatchExactly(const String* s)
{ return re_exact->MatchAll(s); }
// Returns the position in s just beyond where the first match // Returns the position in s just beyond where the first match
// occurs, or 0 if there is no such position in s. Note that // occurs, or 0 if there is no such position in s. Note that
// if the pattern matches empty strings, matching continues // if the pattern matches empty strings, matching continues
// in an attempt to match at least one character. // in an attempt to match at least one character.
int MatchAnywhere(const char* s) int MatchAnywhere(const char* s) { return re_anywhere->Match(s); }
{ return re_anywhere->Match(s); } int MatchAnywhere(const String* s) { return re_anywhere->Match(s); }
int MatchAnywhere(const String* s)
{ return re_anywhere->Match(s); }
// Note: it matches the *longest* prefix and returns the // Note: it matches the *longest* prefix and returns the
// length of matched prefix. It returns -1 on mismatch. // length of matched prefix. It returns -1 on mismatch.
int MatchPrefix(const char* s) int MatchPrefix(const char* s) { return re_exact->LongestMatch(s); }
{ return re_exact->LongestMatch(s); } int MatchPrefix(const String* s) { return re_exact->LongestMatch(s); }
int MatchPrefix(const String* s) int MatchPrefix(const u_char* s, int n) { return re_exact->LongestMatch(s, n); }
{ return re_exact->LongestMatch(s); }
int MatchPrefix(const u_char* s, int n)
{ return re_exact->LongestMatch(s, n); }
const char* PatternText() const { return re_exact->PatternText(); } const char* PatternText() const { return re_exact->PatternText(); }
const char* AnywherePatternText() const { return re_anywhere->PatternText(); } const char* AnywherePatternText() const { return re_anywhere->PatternText(); }
@ -233,14 +235,14 @@ public:
// the main ("explicit") constructor was used. // the main ("explicit") constructor was used.
const char* OrigText() const { return orig_text.c_str(); } const char* OrigText() const { return orig_text.c_str(); }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
unsigned int MemoryAllocation() const "GHI-572.")]] unsigned int
MemoryAllocation() const
{ {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return padded_sizeof(*this) return padded_sizeof(*this) + (re_anywhere ? re_anywhere->MemoryAllocation() : 0) +
+ (re_anywhere ? re_anywhere->MemoryAllocation() : 0) (re_exact ? re_exact->MemoryAllocation() : 0);
+ (re_exact ? re_exact->MemoryAllocation() : 0);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
@ -251,6 +253,6 @@ protected:
detail::Specific_RE_Matcher* re_exact; detail::Specific_RE_Matcher* re_exact;
bool is_case_insensitive = false; bool is_case_insensitive = false;
}; };
} // namespace zeek } // namespace zeek

View file

@ -20,14 +20,15 @@ constexpr double log2of10 = 3.32192809488736234787;
/* RT_LOG2 -- Calculate log to the base 2 */ /* RT_LOG2 -- Calculate log to the base 2 */
static double rt_log2(double x) static double rt_log2(double x)
{ {
return log2of10 * log10(x); return log2of10 * log10(x);
} }
// RT_INCIRC = pow(pow(256.0, (double) (RT_MONTEN / 2)) - 1, 2.0); // RT_INCIRC = pow(pow(256.0, (double) (RT_MONTEN / 2)) - 1, 2.0);
constexpr double RT_INCIRC = 281474943156225.0; constexpr double RT_INCIRC = 281474943156225.0;
namespace zeek::detail { namespace zeek::detail
{
RandTest::RandTest() RandTest::RandTest()
{ {
@ -37,18 +38,18 @@ RandTest::RandTest()
inmont = mcount = 0; inmont = mcount = 0;
cexp = montex = montey = montepi = sccu0 = scclast = scct1 = scct2 = scct3 = 0.0; cexp = montex = montey = montepi = sccu0 = scclast = scct1 = scct2 = scct3 = 0.0;
for (int i = 0; i < 256; i++) for ( int i = 0; i < 256; i++ )
{ {
ccount[i] = 0; ccount[i] = 0;
} }
} }
void RandTest::add(const void *buf, int bufl) void RandTest::add(const void* buf, int bufl)
{ {
const unsigned char *bp = static_cast<const unsigned char*>(buf); const unsigned char* bp = static_cast<const unsigned char*>(buf);
int oc; int oc;
while (bufl-- > 0) while ( bufl-- > 0 )
{ {
oc = *bp++; oc = *bp++;
ccount[oc]++; /* Update counter for this bin */ ccount[oc]++; /* Update counter for this bin */
@ -57,25 +58,25 @@ void RandTest::add(const void *buf, int bufl)
/* Update inside / outside circle counts for Monte Carlo /* Update inside / outside circle counts for Monte Carlo
computation of PI */ computation of PI */
monte[mp++] = oc; /* Save character for Monte Carlo */ monte[mp++] = oc; /* Save character for Monte Carlo */
if (mp >= RT_MONTEN) /* Calculate every RT_MONTEN character */ if ( mp >= RT_MONTEN ) /* Calculate every RT_MONTEN character */
{ {
mp = 0; mp = 0;
mcount++; mcount++;
montex = 0; montex = 0;
montey = 0; montey = 0;
for (int mj=0; mj < RT_MONTEN/2; mj++) for ( int mj = 0; mj < RT_MONTEN / 2; mj++ )
{ {
montex = (montex * 256.0) + monte[mj]; montex = (montex * 256.0) + monte[mj];
montey = (montey * 256.0) + monte[(RT_MONTEN / 2) + mj]; montey = (montey * 256.0) + monte[(RT_MONTEN / 2) + mj];
} }
if (montex*montex + montey*montey <= RT_INCIRC) if ( montex * montex + montey * montey <= RT_INCIRC )
{ {
inmont++; inmont++;
} }
} }
/* Update calculation of serial correlation coefficient */ /* Update calculation of serial correlation coefficient */
if (sccfirst) if ( sccfirst )
{ {
sccfirst = 0; sccfirst = 0;
scclast = 0; scclast = 0;
@ -93,19 +94,22 @@ void RandTest::add(const void *buf, int bufl)
} }
} }
void RandTest::end(double* r_ent, double* r_chisq, void RandTest::end(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc,
double* r_mean, double* r_montepicalc, double* r_scc) double* r_scc)
{ {
int i; int i;
double ent, chisq, scc, datasum; double ent, chisq, scc, datasum;
ent = 0.0; chisq = 0.0; scc = 0.0; datasum = 0.0; ent = 0.0;
chisq = 0.0;
scc = 0.0;
datasum = 0.0;
double prob[256]; /* Probabilities per bin for entropy */ double prob[256]; /* Probabilities per bin for entropy */
/* Complete calculation of serial correlation coefficient */ /* Complete calculation of serial correlation coefficient */
scct1 = scct1 + scclast * sccu0; scct1 = scct1 + scclast * sccu0;
scct2 = scct2 * scct2; scct2 = scct2 * scct2;
scc = totalc * scct3 - scct2; scc = totalc * scct3 - scct2;
if (scc == 0.0) if ( scc == 0.0 )
scc = -100000; scc = -100000;
else else
scc = (totalc * scct1 - scct2) / scc; scc = (totalc * scct1 - scct2) / scc;
@ -116,19 +120,19 @@ void RandTest::end(double* r_ent, double* r_chisq,
we sum of all the data which will be used to compute the we sum of all the data which will be used to compute the
mean. */ mean. */
cexp = totalc / 256.0; /* Expected count per bin */ cexp = totalc / 256.0; /* Expected count per bin */
for (i = 0; i < 256; i++) for ( i = 0; i < 256; i++ )
{ {
double a = ccount[i] - cexp; double a = ccount[i] - cexp;
prob[i] = ((double) ccount[i]) / totalc; prob[i] = ((double)ccount[i]) / totalc;
chisq += (a * a) / cexp; chisq += (a * a) / cexp;
datasum += ((double) i) * ccount[i]; datasum += ((double)i) * ccount[i];
} }
/* Calculate entropy */ /* Calculate entropy */
for (i = 0; i < 256; i++) for ( i = 0; i < 256; i++ )
{ {
if (prob[i] > 0.0) if ( prob[i] > 0.0 )
{ {
ent += prob[i] * rt_log2(1 / prob[i]); ent += prob[i] * rt_log2(1 / prob[i]);
} }
@ -136,7 +140,7 @@ void RandTest::end(double* r_ent, double* r_chisq,
/* Calculate Monte Carlo value for PI from percentage of hits /* Calculate Monte Carlo value for PI from percentage of hits
within the circle */ within the circle */
montepi = mcount == 0 ? 0 : 4.0 * (((double) inmont) / mcount); montepi = mcount == 0 ? 0 : 4.0 * (((double)inmont) / mcount);
/* Return results through arguments */ /* Return results through arguments */
*r_ent = ent; *r_ent = ent;
@ -146,4 +150,4 @@ void RandTest::end(double* r_ent, double* r_chisq,
*r_scc = scc; *r_scc = scc;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -1,25 +1,29 @@
#pragma once #pragma once
#include "zeek/zeek-config.h"
#include <stdint.h> #include <stdint.h>
#define RT_MONTEN 6 /* Bytes used as Monte Carlo #include "zeek/zeek-config.h"
co-ordinates. This should be no more
bits than the mantissa of your "double" #define RT_MONTEN \
6 /* Bytes used as Monte Carlo \
co-ordinates. This should be no more \
bits than the mantissa of your "double" \
floating point type. */ floating point type. */
namespace zeek { namespace zeek
{
class EntropyVal; class EntropyVal;
namespace detail { namespace detail
{
class RandTest { class RandTest
{
public: public:
RandTest(); RandTest();
void add(const void* buf, int bufl); void add(const void* buf, int bufl);
void end(double* r_ent, double* r_chisq, double* r_mean, void end(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc, double* r_scc);
double* r_montepicalc, double* r_scc);
private: private:
friend class zeek::EntropyVal; friend class zeek::EntropyVal;
@ -30,9 +34,8 @@ private:
int sccfirst; int sccfirst;
unsigned int monte[RT_MONTEN]; unsigned int monte[RT_MONTEN];
int64_t inmont, mcount; int64_t inmont, mcount;
double cexp, montex, montey, montepi, double cexp, montex, montey, montepi, sccu0, scclast, scct1, scct2, scct3;
sccu0, scclast, scct1, scct2, scct3; };
};
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1,15 +1,16 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Reassem.h" #include "zeek/Reassem.h"
#include <algorithm> #include <algorithm>
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/zeek-config.h"
using std::min; using std::min;
namespace zeek { namespace zeek
{
uint64_t Reassembler::total_size = 0; uint64_t Reassembler::total_size = 0;
uint64_t Reassembler::sizes[REASSEM_NUM]; uint64_t Reassembler::sizes[REASSEM_NUM];
@ -100,8 +101,7 @@ DataBlockMap::const_iterator DataBlockList::FirstBlockAtOrBefore(uint64_t seq) c
return std::prev(it); return std::prev(it);
} }
DataBlockMap::const_iterator DataBlockMap::const_iterator DataBlockList::Insert(uint64_t seq, uint64_t upper, const u_char* data,
DataBlockList::Insert(uint64_t seq, uint64_t upper, const u_char* data,
DataBlockMap::const_iterator hint) DataBlockMap::const_iterator hint)
{ {
auto size = upper - seq; auto size = upper - seq;
@ -114,8 +114,7 @@ DataBlockList::Insert(uint64_t seq, uint64_t upper, const u_char* data,
return rval; return rval;
} }
DataBlockMap::const_iterator DataBlockMap::const_iterator DataBlockList::Insert(uint64_t seq, uint64_t upper, const u_char* data,
DataBlockList::Insert(uint64_t seq, uint64_t upper, const u_char* data,
DataBlockMap::const_iterator* hint) DataBlockMap::const_iterator* hint)
{ {
// Empty list. // Empty list.
@ -191,8 +190,7 @@ DataBlockList::Insert(uint64_t seq, uint64_t upper, const u_char* data,
return rval; return rval;
} }
uint64_t DataBlockList::Trim(uint64_t seq, uint64_t max_old, uint64_t DataBlockList::Trim(uint64_t seq, uint64_t max_old, DataBlockList* old_list)
DataBlockList* old_list)
{ {
uint64_t num_missing = 0; uint64_t num_missing = 0;
@ -267,14 +265,12 @@ uint64_t DataBlockList::Trim(uint64_t seq, uint64_t max_old,
} }
Reassembler::Reassembler(uint64_t init_seq, ReassemblerType reassem_type) Reassembler::Reassembler(uint64_t init_seq, ReassemblerType reassem_type)
: block_list(this), old_block_list(this), : block_list(this), old_block_list(this), last_reassem_seq(init_seq), trim_seq(init_seq),
last_reassem_seq(init_seq), trim_seq(init_seq),
max_old_blocks(0), rtype(reassem_type) max_old_blocks(0), rtype(reassem_type)
{ {
} }
void Reassembler::CheckOverlap(const DataBlockList& list, void Reassembler::CheckOverlap(const DataBlockList& list, uint64_t seq, uint64_t len,
uint64_t seq, uint64_t len,
const u_char* data) const u_char* data)
{ {
if ( list.Empty() ) if ( list.Empty() )
@ -347,7 +343,8 @@ void Reassembler::NewBlock(double t, uint64_t seq, uint64_t len, const u_char* d
len -= amount_old; len -= amount_old;
} }
auto it = block_list.Insert(seq, upper_seq, data);; auto it = block_list.Insert(seq, upper_seq, data);
;
BlockInserted(it); BlockInserted(it);
} }
@ -387,4 +384,4 @@ uint64_t Reassembler::MemoryAllocation(ReassemblerType rtype)
return Reassembler::sizes[rtype]; return Reassembler::sizes[rtype];
} }
} // namespace zeek } // namespace zeek

Some files were not shown because too many files have changed in this diff Show more