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 <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include "zeek/util.h"
#include "zeek/net_util.h"
#include "zeek/Val.h"
#include "zeek/Event.h"
#include "zeek/ID.h"
#include "zeek/IPAddr.h"
#include "zeek/NetVar.h"
#include "zeek/Reporter.h"
#include "zeek/Scope.h"
#include "zeek/ID.h"
#include "zeek/IPAddr.h"
#include "zeek/Event.h"
#include "zeek/Val.h"
#include "zeek/net_util.h"
#include "zeek/util.h"
namespace zeek::detail {
namespace zeek::detail
{
AnonymizeIPAddr* ip_anonymizer[NUM_ADDR_ANONYMIZATION_METHODS] = {nullptr};
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.
static int bi_ffs(uint32_t value)
{
int add = 0;
static uint8_t bvals[] = {
0, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
};
static uint8_t bvals[] = {0, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1};
if ( (value & 0xFFFF0000) == 0 )
{
@ -57,7 +57,7 @@ static int bi_ffs(uint32_t value)
return add + bvals[value & 0xf];
}
#define first_n_bit_mask(n) (~(0xFFFFFFFFU >> n))
#define first_n_bit_mask(n) (~(0xFFFFFFFFU >> n))
ipaddr32_t AnonymizeIPAddr::Anonymize(ipaddr32_t addr)
{
@ -82,16 +82,17 @@ bool AnonymizeIPAddr::PreservePrefix(ipaddr32_t /* input */, int /* num_bits */)
bool AnonymizeIPAddr::PreserveNet(ipaddr32_t input)
{
switch ( addr_to_class(ntohl(input)) ) {
case 'A':
return PreservePrefix(input, 8);
case 'B':
return PreservePrefix(input, 16);
case 'C':
return PreservePrefix(input, 24);
default:
return false;
}
switch ( addr_to_class(ntohl(input)) )
{
case 'A':
return PreservePrefix(input, 8);
case 'B':
return PreservePrefix(input, 16);
case 'C':
return PreservePrefix(input, 24);
default:
return false;
}
}
ipaddr32_t AnonymizeIPAddr_Seq::anonymize(ipaddr32_t /* input */)
@ -113,7 +114,6 @@ ipaddr32_t AnonymizeIPAddr_RandomMD5::anonymize(ipaddr32_t input)
return output;
}
// This code is from "On the Design and Performance of Prefix-Preserving
// 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 .
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})).
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}))).
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}.
output ^= bit_mask;
@ -148,7 +148,7 @@ ipaddr32_t AnonymizeIPAddr_PrefixMD5::anonymize(ipaddr32_t input)
AnonymizeIPAddr_A50::~AnonymizeIPAddr_A50()
{
for ( auto& b : blocks )
delete [] b;
delete[] b;
}
void AnonymizeIPAddr_A50::init()
@ -167,9 +167,7 @@ void AnonymizeIPAddr_A50::init()
bool AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits)
{
DEBUG_MSG("%s/%d\n",
IPAddr(IPv4, &input, IPAddr::Network).AsString().c_str(),
num_bits);
DEBUG_MSG("%s/%d\n", IPAddr(IPv4, &input, IPAddr::Network).AsString().c_str(), num_bits);
if ( ! before_anonymization )
{
@ -225,7 +223,7 @@ AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::new_node_block()
blocks.push_back(block);
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;
next_free_node = &block[1];
@ -247,7 +245,7 @@ inline AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::new_node()
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;
next_free_node = n;
@ -261,8 +259,7 @@ ipaddr32_t AnonymizeIPAddr_A50::make_output(ipaddr32_t old_output, int swivel) c
else
{
// Bits up to swivel are unchanged; bit swivel is flipped.
ipaddr32_t known_part =
((old_output >> (32 - swivel)) ^ 1) << (32 - swivel);
ipaddr32_t known_part = ((old_output >> (32 - swivel)) ^ 1) << (32 - swivel);
// Remainder of bits are random.
return known_part | ((rand32() & 0x7FFFFFFF) >> swivel);
@ -299,11 +296,11 @@ AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::make_peer(ipaddr32_t a, Node* n)
down[bitvalue]->output = make_output(n->output, swivel);
down[bitvalue]->child[0] = down[bitvalue]->child[1] = nullptr;
*down[1 - bitvalue] = *n; // copy orig node down one level
*down[1 - bitvalue] = *n; // copy orig node down one level
n->input = down[1]->input; // NB: 1s to the right (0s to the left)
n->input = down[1]->input; // NB: 1s to the right (0s to the left)
n->output = down[1]->output;
n->child[0] = down[0]; // point to children
n->child[0] = down[0]; // point to children
n->child[1] = down[1];
return down[bitvalue];
@ -340,8 +337,7 @@ AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::find_node(ipaddr32_t a)
{
// swivel is the first bit in which the two children
// differ.
int swivel =
bi_ffs(n->child[0]->input ^ n->child[1]->input);
int swivel = bi_ffs(n->child[0]->input ^ n->child[1]->input);
if ( bi_ffs(a ^ n->input) < swivel )
// Input differs earlier.
@ -394,22 +390,23 @@ ipaddr32_t anonymize_ip(ipaddr32_t ip, enum ip_addr_anonymization_class_t cl)
int method = -1;
switch ( cl ) {
case ORIG_ADDR: // client address
preserve_addr = anon_preserve_orig_addr.get();
method = orig_addr_anonymization;
break;
switch ( cl )
{
case ORIG_ADDR: // client address
preserve_addr = anon_preserve_orig_addr.get();
method = orig_addr_anonymization;
break;
case RESP_ADDR: // server address
preserve_addr = anon_preserve_resp_addr.get();
method = resp_addr_anonymization;
break;
case RESP_ADDR: // server address
preserve_addr = anon_preserve_resp_addr.get();
method = resp_addr_anonymization;
break;
default:
preserve_addr = anon_preserve_other_addr.get();
method = other_addr_anonymization;
break;
}
default:
preserve_addr = anon_preserve_other_addr.get();
method = other_addr_anonymization;
break;
}
ipaddr32_t new_ip = 0;
@ -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)
{
if ( anonymization_mapping )
event_mgr.Enqueue(anonymization_mapping,
make_intrusive<AddrVal>(input),
make_intrusive<AddrVal>(output)
);
event_mgr.Enqueue(anonymization_mapping, make_intrusive<AddrVal>(input),
make_intrusive<AddrVal>(output));
}
#endif
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -10,36 +10,40 @@
#pragma once
#include <vector>
#include <map>
#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 ...
enum ip_addr_anonymization_class_t {
ORIG_ADDR, // client address
RESP_ADDR, // server address
enum ip_addr_anonymization_class_t
{
ORIG_ADDR, // client address
RESP_ADDR, // server address
OTHER_ADDR,
NUM_ADDR_ANONYMIZATION_CLASSES,
};
};
enum ip_addr_anonymization_method_t {
enum ip_addr_anonymization_method_t
{
KEEP_ORIG_ADDR,
SEQUENTIALLY_NUMBERED,
RANDOM_MD5,
PREFIX_PRESERVING_A50,
PREFIX_PRESERVING_MD5,
NUM_ADDR_ANONYMIZATION_METHODS,
};
};
typedef uint32_t ipaddr32_t;
// NOTE: all addresses in parameters of *public* functions are in
// network order.
class AnonymizeIPAddr {
class AnonymizeIPAddr
{
public:
virtual ~AnonymizeIPAddr() = default;
@ -53,47 +57,53 @@ public:
protected:
std::map<ipaddr32_t, ipaddr32_t> mapping;
};
};
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr {
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr
{
public:
AnonymizeIPAddr_Seq() { seq = 1; }
AnonymizeIPAddr_Seq() { seq = 1; }
ipaddr32_t anonymize(ipaddr32_t addr) override;
protected:
ipaddr32_t seq;
};
};
class AnonymizeIPAddr_RandomMD5 : public AnonymizeIPAddr {
class AnonymizeIPAddr_RandomMD5 : public AnonymizeIPAddr
{
public:
ipaddr32_t anonymize(ipaddr32_t addr) override;
};
};
class AnonymizeIPAddr_PrefixMD5 : public AnonymizeIPAddr {
class AnonymizeIPAddr_PrefixMD5 : public AnonymizeIPAddr
{
public:
ipaddr32_t anonymize(ipaddr32_t addr) override;
protected:
struct anon_prefix {
struct anon_prefix
{
int len;
ipaddr32_t prefix;
} prefix;
};
} prefix;
};
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr {
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr
{
public:
AnonymizeIPAddr_A50() { init(); }
AnonymizeIPAddr_A50() { init(); }
~AnonymizeIPAddr_A50() override;
ipaddr32_t anonymize(ipaddr32_t addr) override;
bool PreservePrefix(ipaddr32_t input, int num_bits) override;
protected:
struct Node {
struct Node
{
ipaddr32_t input;
ipaddr32_t output;
Node* child[2];
};
};
int method;
int before_anonymization;
@ -118,7 +128,7 @@ protected:
ipaddr32_t make_output(ipaddr32_t, int) const;
Node* make_peer(ipaddr32_t, Node*);
Node* find_node(ipaddr32_t);
};
};
// The global IP anonymizers.
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
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.
#include "zeek/zeek-config.h"
#include "zeek/Attr.h"
#include "zeek/Expr.h"
#include "zeek/Desc.h"
#include "zeek/Val.h"
#include "zeek/Expr.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/Val.h"
#include "zeek/input/Manager.h"
#include "zeek/threading/SerialTypes.h"
#include "zeek/zeek-config.h"
namespace zeek::detail {
namespace zeek::detail
{
const char* attr_name(AttrTag t)
{
static const char* attr_names[int(NUM_ATTRS)] = {
"&optional", "&default", "&redef",
"&add_func", "&delete_func", "&expire_func",
"&read_expire", "&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",
"&optional",
"&default",
"&redef",
"&add_func",
"&delete_func",
"&expire_func",
"&read_expire",
"&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)];
}
Attr::Attr(AttrTag t, ExprPtr e)
: expr(std::move(e))
Attr::Attr(AttrTag t, ExprPtr e) : expr(std::move(e))
{
tag = t;
SetLocationInfo(&start_location, &end_location);
}
Attr::Attr(AttrTag t)
: Attr(t, nullptr)
{
}
Attr::Attr(AttrTag t) : Attr(t, nullptr) { }
void Attr::SetAttrExpr(ExprPtr e)
{ expr = std::move(e); }
{
expr = std::move(e);
}
std::string Attr::DeprecationMessage() const
{
@ -71,7 +85,7 @@ void Attr::Describe(ODesc* d) const
void Attr::DescribeReST(ODesc* d, bool shorten) const
{
auto add_long_expr_string = [](ODesc* d, const std::string& s, bool shorten)
{
{
constexpr auto max_expr_chars = 32;
constexpr auto shortened_expr = "*...*";
@ -93,7 +107,7 @@ void Attr::DescribeReST(ODesc* d, bool shorten) const
d->Add(s);
d->Add("``");
}
};
};
d->Add(":zeek:attr:`");
AddTag(d);
@ -152,12 +166,11 @@ void Attr::AddTag(ODesc* d) const
}
Attributes::Attributes(TypePtr t, bool arg_in_record, bool is_global)
: Attributes(std::vector<AttrPtr>{}, std::move(t),
arg_in_record, is_global)
{}
: Attributes(std::vector<AttrPtr>{}, std::move(t), arg_in_record, is_global)
{
}
Attributes::Attributes(std::vector<AttrPtr> a,
TypePtr t, bool arg_in_record, bool is_global)
Attributes::Attributes(std::vector<AttrPtr> a, TypePtr t, bool arg_in_record, bool is_global)
: type(std::move(t))
{
attrs.reserve(a.size());
@ -177,22 +190,22 @@ Attributes::Attributes(std::vector<AttrPtr> a,
void Attributes::AddAttr(AttrPtr attr, bool is_redef)
{
auto acceptable_duplicate_attr = [](const AttrPtr& attr, const AttrPtr& existing) -> bool
{
{
AttrTag new_tag = attr->Tag();
if ( new_tag == ATTR_DEPRECATED )
{
if ( ! attr->DeprecationMessage().empty() ||
( existing && ! existing->DeprecationMessage().empty() ) )
(existing && ! existing->DeprecationMessage().empty()) )
return false;
return true;
}
return new_tag == ATTR_LOG || new_tag == ATTR_OPTIONAL || new_tag == ATTR_REDEF ||
new_tag == ATTR_BROKER_STORE_ALLOW_COMPLEX || new_tag == ATTR_RAW_OUTPUT ||
new_tag == ATTR_ERROR_HANDLER;
};
new_tag == ATTR_BROKER_STORE_ALLOW_COMPLEX || new_tag == ATTR_RAW_OUTPUT ||
new_tag == ATTR_ERROR_HANDLER;
};
// A `redef` is allowed to overwrite an existing attribute instead of
// flagging it as ambiguous.
@ -216,16 +229,14 @@ void Attributes::AddAttr(AttrPtr attr, bool is_redef)
// For ADD_FUNC or DEL_FUNC, add in an implicit REDEF, since
// those attributes only have meaning for a redefinable value.
if ( (attr->Tag() == ATTR_ADD_FUNC || attr->Tag() == ATTR_DEL_FUNC) &&
! Find(ATTR_REDEF) )
if ( (attr->Tag() == ATTR_ADD_FUNC || attr->Tag() == ATTR_DEL_FUNC) && ! Find(ATTR_REDEF) )
{
auto a = make_intrusive<Attr>(ATTR_REDEF);
attrs.emplace_back(std::move(a));
}
// For DEFAULT, add an implicit OPTIONAL if it's not a global.
if ( ! global_var && attr->Tag() == ATTR_DEFAULT &&
! Find(ATTR_OPTIONAL) )
if ( ! global_var && attr->Tag() == ATTR_DEFAULT && ! Find(ATTR_OPTIONAL) )
{
auto a = make_intrusive<Attr>(ATTR_OPTIONAL);
attrs.emplace_back(std::move(a));
@ -290,425 +301,420 @@ void Attributes::DescribeReST(ODesc* d, bool shorten) const
void Attributes::CheckAttr(Attr* a)
{
switch ( a->Tag() ) {
case ATTR_DEPRECATED:
case ATTR_REDEF:
case ATTR_IS_ASSIGNED:
case ATTR_IS_USED:
break;
case ATTR_OPTIONAL:
if ( global_var )
Error("&optional is not valid for global variables");
break;
case ATTR_ADD_FUNC:
case ATTR_DEL_FUNC:
switch ( a->Tag() )
{
bool is_add = a->Tag() == ATTR_ADD_FUNC;
const auto& at = a->GetExpr()->GetType();
if ( at->Tag() != TYPE_FUNC )
{
a->GetExpr()->Error(
is_add ?
"&add_func must be a function" :
"&delete_func must be a function");
case ATTR_DEPRECATED:
case ATTR_REDEF:
case ATTR_IS_ASSIGNED:
case ATTR_IS_USED:
break;
}
FuncType* aft = at->AsFuncType();
if ( ! same_type(aft->Yield(), type) )
{
a->GetExpr()->Error(
is_add ?
"&add_func function must yield same type as variable" :
"&delete_func function must yield same type as variable");
case ATTR_OPTIONAL:
if ( global_var )
Error("&optional is not valid for global variables");
break;
}
}
break;
case ATTR_DEFAULT:
{
// &default is allowed for global tables, since it's used in initialization
// of table fields. it's not allowed otherwise.
if ( global_var && ! type->IsTable() )
{
Error("&default is not valid for global variables except for tables");
break;
}
const auto& atype = a->GetExpr()->GetType();
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) )
{
if ( same_type(atype, type) )
// Ok.
break;
// Record defaults may be promotable.
if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(),
type->AsRecordType())) )
// Ok.
break;
if ( type->Tag() == TYPE_TABLE &&
type->AsTableType()->IsUnspecifiedTable() )
// Ok.
break;
auto e = check_and_promote_expr(a->GetExpr(), type);
if ( e )
case ATTR_ADD_FUNC:
case ATTR_DEL_FUNC:
{
a->SetAttrExpr(std::move(e));
// Ok.
break;
}
bool is_add = a->Tag() == ATTR_ADD_FUNC;
a->GetExpr()->Error("&default value has inconsistent type", type.get());
return;
}
TableType* tt = type->AsTableType();
const auto& ytype = tt->Yield();
if ( ! in_record )
{
// &default applies to the type itself.
if ( ! same_type(atype, ytype) )
{
// It can still be a default function.
if ( atype->Tag() == TYPE_FUNC )
const auto& at = a->GetExpr()->GetType();
if ( at->Tag() != TYPE_FUNC )
{
FuncType* f = atype->AsFuncType();
if ( ! f->CheckArgs(tt->GetIndexTypes()) ||
! same_type(f->Yield(), ytype) )
Error("&default function type clash");
a->GetExpr()->Error(is_add ? "&add_func must be a function"
: "&delete_func must be a function");
break;
}
FuncType* aft = at->AsFuncType();
if ( ! same_type(aft->Yield(), type) )
{
a->GetExpr()->Error(
is_add ? "&add_func function must yield same type as variable"
: "&delete_func function must yield same type as variable");
break;
}
}
break;
case ATTR_DEFAULT:
{
// &default is allowed for global tables, since it's used in initialization
// of table fields. it's not allowed otherwise.
if ( global_var && ! type->IsTable() )
{
Error("&default is not valid for global variables except for tables");
break;
}
const auto& atype = a->GetExpr()->GetType();
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) )
{
if ( same_type(atype, type) )
// Ok.
break;
// Record defaults may be promotable.
if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(),
type->AsRecordType())) )
// Ok.
break;
if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() )
// Ok.
break;
auto e = check_and_promote_expr(a->GetExpr(), type);
if ( e )
{
a->SetAttrExpr(std::move(e));
// Ok.
break;
}
a->GetExpr()->Error("&default value has inconsistent type", type.get());
return;
}
TableType* tt = type->AsTableType();
const auto& ytype = tt->Yield();
if ( ! in_record )
{
// &default applies to the type itself.
if ( ! same_type(atype, ytype) )
{
// It can still be a default function.
if ( atype->Tag() == TYPE_FUNC )
{
FuncType* f = atype->AsFuncType();
if ( ! f->CheckArgs(tt->GetIndexTypes()) ||
! same_type(f->Yield(), ytype) )
Error("&default function type clash");
// Ok.
break;
}
// Table defaults may be promotable.
if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(),
ytype->AsRecordType())) )
// Ok.
break;
auto e = check_and_promote_expr(a->GetExpr(), ytype);
if ( e )
{
a->SetAttrExpr(std::move(e));
// Ok.
break;
}
Error("&default value has inconsistent type 2");
}
// Ok.
break;
}
// Table defaults may be promotable.
if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(),
ytype->AsRecordType())) )
// Ok.
break;
auto e = check_and_promote_expr(a->GetExpr(), ytype);
if ( e )
else
{
a->SetAttrExpr(std::move(e));
// Ok.
break;
// &default applies to record field.
if ( same_type(atype, type) )
// Ok.
break;
if ( (atype->Tag() == TYPE_TABLE &&
atype->AsTableType()->IsUnspecifiedTable()) )
{
auto e = check_and_promote_expr(a->GetExpr(), type);
if ( e )
{
a->SetAttrExpr(std::move(e));
break;
}
}
// Table defaults may be promotable.
if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) )
// Ok.
break;
Error("&default value has inconsistent type");
}
Error("&default value has inconsistent type 2");
}
// Ok.
break;
}
else
{
// &default applies to record field.
if ( same_type(atype, type) )
// Ok.
break;
if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) )
case ATTR_EXPIRE_READ:
{
auto e = check_and_promote_expr(a->GetExpr(), type);
if ( Find(ATTR_BROKER_STORE) )
Error("&broker_store and &read_expire cannot be used simultaneously");
if ( e )
if ( Find(ATTR_BACKEND) )
Error("&backend and &read_expire cannot be used simultaneously");
}
// fallthrough
case ATTR_EXPIRE_WRITE:
case ATTR_EXPIRE_CREATE:
{
if ( type->Tag() != TYPE_TABLE )
{
a->SetAttrExpr(std::move(e));
Error("expiration only applicable to sets/tables");
break;
}
int num_expires = 0;
for ( const auto& a : attrs )
{
if ( a->Tag() == ATTR_EXPIRE_READ || a->Tag() == ATTR_EXPIRE_WRITE ||
a->Tag() == ATTR_EXPIRE_CREATE )
num_expires++;
}
if ( num_expires > 1 )
{
Error("set/table can only have one of &read_expire, &write_expire, "
"&create_expire");
break;
}
}
// Table defaults may be promotable.
if ( ytype && ytype->Tag() == TYPE_RECORD &&
atype->Tag() == TYPE_RECORD &&
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) )
// Ok.
break;
Error("&default value has inconsistent type");
}
}
break;
case ATTR_EXPIRE_READ:
{
if ( Find(ATTR_BROKER_STORE) )
Error("&broker_store and &read_expire cannot be used simultaneously");
if ( Find(ATTR_BACKEND) )
Error("&backend and &read_expire cannot be used simultaneously");
}
// fallthrough
case ATTR_EXPIRE_WRITE:
case ATTR_EXPIRE_CREATE:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("expiration only applicable to sets/tables");
break;
}
int num_expires = 0;
for ( const auto& a : attrs )
{
if ( a->Tag() == ATTR_EXPIRE_READ ||
a->Tag() == ATTR_EXPIRE_WRITE ||
a->Tag() == ATTR_EXPIRE_CREATE )
num_expires++;
}
if ( num_expires > 1 )
{
Error("set/table can only have one of &read_expire, &write_expire, &create_expire");
break;
}
}
#if 0
//### not easy to test this w/o knowing the ID.
if ( ! global_var )
Error("expiration not supported for local variables");
#endif
break;
case ATTR_EXPIRE_FUNC:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("expiration only applicable to tables");
break;
}
type->AsTableType()->CheckExpireFuncCompatibility({NewRef{}, a});
if ( Find(ATTR_BROKER_STORE ) )
Error("&broker_store and &expire_func cannot be used simultaneously");
if ( Find(ATTR_BACKEND ) )
Error("&backend and &expire_func cannot be used simultaneously");
break;
}
case ATTR_ON_CHANGE:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("&on_change only applicable to sets/tables");
break;
}
const auto& change_func = a->GetExpr();
if ( change_func->GetType()->Tag() != TYPE_FUNC || change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
Error("&on_change attribute is not a function");
const FuncType* c_ft = change_func->GetType()->AsFuncType();
if ( c_ft->Yield()->Tag() != TYPE_VOID )
{
Error("&on_change must not return a value");
break;
}
const TableType* the_table = type->AsTableType();
if ( the_table->IsUnspecifiedTable() )
break;
const auto& args = c_ft->ParamList()->GetTypes();
const auto& t_indexes = the_table->GetIndexTypes();
if ( args.size() != ( type->IsSet() ? 2 : 3 ) + t_indexes.size() )
{
Error("&on_change function has incorrect number of arguments");
break;
}
if ( ! same_type(args[0], the_table->AsTableType()) )
{
Error("&on_change: first argument must be of same type as table");
break;
}
// can't check exact type here yet - the data structures don't exist yet.
if ( args[1]->Tag() != TYPE_ENUM )
{
Error("&on_change: second argument must be a TableChange enum");
break;
}
for ( size_t i = 0; i < t_indexes.size(); i++ )
{
if ( ! same_type(args[2+i], t_indexes[i]) )
case ATTR_EXPIRE_FUNC:
{
Error("&on_change: index types do not match table");
if ( type->Tag() != TYPE_TABLE )
{
Error("expiration only applicable to tables");
break;
}
type->AsTableType()->CheckExpireFuncCompatibility({NewRef{}, a});
if ( Find(ATTR_BROKER_STORE) )
Error("&broker_store and &expire_func cannot be used simultaneously");
if ( Find(ATTR_BACKEND) )
Error("&backend and &expire_func cannot be used simultaneously");
break;
}
}
if ( ! type->IsSet() )
if ( ! same_type(args[2+t_indexes.size()], the_table->Yield()) )
case ATTR_ON_CHANGE:
{
Error("&on_change: value type does not match table");
if ( type->Tag() != TYPE_TABLE )
{
Error("&on_change only applicable to sets/tables");
break;
}
const auto& change_func = a->GetExpr();
if ( change_func->GetType()->Tag() != TYPE_FUNC ||
change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
Error("&on_change attribute is not a function");
const FuncType* c_ft = change_func->GetType()->AsFuncType();
if ( c_ft->Yield()->Tag() != TYPE_VOID )
{
Error("&on_change must not return a value");
break;
}
const TableType* the_table = type->AsTableType();
if ( the_table->IsUnspecifiedTable() )
break;
const auto& args = c_ft->ParamList()->GetTypes();
const auto& t_indexes = the_table->GetIndexTypes();
if ( args.size() != (type->IsSet() ? 2 : 3) + t_indexes.size() )
{
Error("&on_change function has incorrect number of arguments");
break;
}
if ( ! same_type(args[0], the_table->AsTableType()) )
{
Error("&on_change: first argument must be of same type as table");
break;
}
// can't check exact type here yet - the data structures don't exist yet.
if ( args[1]->Tag() != TYPE_ENUM )
{
Error("&on_change: second argument must be a TableChange enum");
break;
}
for ( size_t i = 0; i < t_indexes.size(); i++ )
{
if ( ! same_type(args[2 + i], t_indexes[i]) )
{
Error("&on_change: index types do not match table");
break;
}
}
if ( ! type->IsSet() )
if ( ! same_type(args[2 + t_indexes.size()], the_table->Yield()) )
{
Error("&on_change: value type does not match table");
break;
}
}
break;
case ATTR_BACKEND:
{
if ( ! global_var || type->Tag() != TYPE_TABLE )
{
Error("&backend only applicable to global sets/tables");
break;
}
// cannot do better equality check - the Broker types are not
// actually existing yet when we are here. We will do that
// later - before actually attaching to a broker store
if ( a->GetExpr()->GetType()->Tag() != TYPE_ENUM )
{
Error("&backend must take an enum argument");
break;
}
// Only support atomic types for the moment, unless
// explicitly overriden
if ( ! type->AsTableType()->IsSet() &&
! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) &&
! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) )
{
Error("&backend only supports atomic types as table value");
}
if ( Find(ATTR_EXPIRE_FUNC) )
Error("&backend and &expire_func cannot be used simultaneously");
if ( Find(ATTR_EXPIRE_READ) )
Error("&backend and &read_expire cannot be used simultaneously");
if ( Find(ATTR_BROKER_STORE) )
Error("&backend and &broker_store cannot be used simultaneously");
break;
}
case ATTR_BROKER_STORE:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("&broker_store only applicable to sets/tables");
break;
}
if ( a->GetExpr()->GetType()->Tag() != TYPE_STRING )
{
Error("&broker_store must take a string argument");
break;
}
// Only support atomic types for the moment, unless
// explicitly overriden
if ( ! type->AsTableType()->IsSet() &&
! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) &&
! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) )
{
Error("&broker_store only supports atomic types as table value");
}
if ( Find(ATTR_EXPIRE_FUNC) )
Error("&broker_store and &expire_func cannot be used simultaneously");
if ( Find(ATTR_EXPIRE_READ) )
Error("&broker_store and &read_expire cannot be used simultaneously");
if ( Find(ATTR_BACKEND) )
Error("&backend and &broker_store cannot be used simultaneously");
break;
}
case ATTR_BROKER_STORE_ALLOW_COMPLEX:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("&broker_allow_complex_type only applicable to sets/tables");
break;
}
}
case ATTR_TRACKED:
// FIXME: Check here for global ID?
break;
case ATTR_RAW_OUTPUT:
if ( type->Tag() != TYPE_FILE )
Error("&raw_output only applicable to files");
break;
case ATTR_PRIORITY:
Error("&priority only applicable to event bodies");
break;
case ATTR_GROUP:
if ( type->Tag() != TYPE_FUNC || type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
Error("&group only applicable to events");
break;
case ATTR_ERROR_HANDLER:
if ( type->Tag() != TYPE_FUNC || type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
Error("&error_handler only applicable to events");
break;
case ATTR_LOG:
if ( ! threading::Value::IsCompatibleType(type.get()) )
Error("&log applied to a type that cannot be logged");
break;
case ATTR_TYPE_COLUMN:
{
if ( type->Tag() != TYPE_PORT )
{
Error("type_column tag only applicable to ports");
break;
}
const auto& atype = a->GetExpr()->GetType();
if ( atype->Tag() != TYPE_STRING )
{
Error("type column needs to have a string argument");
break;
}
break;
}
default:
BadTag("Attributes::CheckAttr", attr_name(a->Tag()));
}
break;
case ATTR_BACKEND:
{
if ( ! global_var || type->Tag() != TYPE_TABLE )
{
Error("&backend only applicable to global sets/tables");
break;
}
// cannot do better equality check - the Broker types are not
// actually existing yet when we are here. We will do that
// later - before actually attaching to a broker store
if ( a->GetExpr()->GetType()->Tag() != TYPE_ENUM )
{
Error("&backend must take an enum argument");
break;
}
// Only support atomic types for the moment, unless
// explicitly overriden
if ( ! type->AsTableType()->IsSet() &&
! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) &&
! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) )
{
Error("&backend only supports atomic types as table value");
}
if ( Find(ATTR_EXPIRE_FUNC ) )
Error("&backend and &expire_func cannot be used simultaneously");
if ( Find(ATTR_EXPIRE_READ) )
Error("&backend and &read_expire cannot be used simultaneously");
if ( Find(ATTR_BROKER_STORE) )
Error("&backend and &broker_store cannot be used simultaneously");
break;
}
case ATTR_BROKER_STORE:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("&broker_store only applicable to sets/tables");
break;
}
if ( a->GetExpr()->GetType()->Tag() != TYPE_STRING )
{
Error("&broker_store must take a string argument");
break;
}
// Only support atomic types for the moment, unless
// explicitly overriden
if ( ! type->AsTableType()->IsSet() &&
! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) &&
! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) )
{
Error("&broker_store only supports atomic types as table value");
}
if ( Find(ATTR_EXPIRE_FUNC ) )
Error("&broker_store and &expire_func cannot be used simultaneously");
if ( Find(ATTR_EXPIRE_READ) )
Error("&broker_store and &read_expire cannot be used simultaneously");
if ( Find(ATTR_BACKEND) )
Error("&backend and &broker_store cannot be used simultaneously");
break;
}
case ATTR_BROKER_STORE_ALLOW_COMPLEX:
{
if ( type->Tag() != TYPE_TABLE )
{
Error("&broker_allow_complex_type only applicable to sets/tables");
break;
}
}
case ATTR_TRACKED:
// FIXME: Check here for global ID?
break;
case ATTR_RAW_OUTPUT:
if ( type->Tag() != TYPE_FILE )
Error("&raw_output only applicable to files");
break;
case ATTR_PRIORITY:
Error("&priority only applicable to event bodies");
break;
case ATTR_GROUP:
if ( type->Tag() != TYPE_FUNC ||
type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
Error("&group only applicable to events");
break;
case ATTR_ERROR_HANDLER:
if ( type->Tag() != TYPE_FUNC ||
type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
Error("&error_handler only applicable to events");
break;
case ATTR_LOG:
if ( ! threading::Value::IsCompatibleType(type.get()) )
Error("&log applied to a type that cannot be logged");
break;
case ATTR_TYPE_COLUMN:
{
if ( type->Tag() != TYPE_PORT )
{
Error("type_column tag only applicable to ports");
break;
}
const auto& atype = a->GetExpr()->GetType();
if ( atype->Tag() != TYPE_STRING ) {
Error("type column needs to have a string argument");
break;
}
break;
}
default:
BadTag("Attributes::CheckAttr", attr_name(a->Tag()));
}
}
bool Attributes::operator==(const Attributes& other) const
@ -744,4 +750,4 @@ bool Attributes::operator==(const Attributes& other) const
return true;
}
}
}

View file

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

View file

@ -1,21 +1,23 @@
#include "zeek/zeek-config.h"
#include "zeek/Base64.h"
#include <math.h>
#include "zeek/Base64.h"
#include "zeek/ZeekString.h"
#include "zeek/Reporter.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];
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)
{
int blen;
char *buf;
char* buf;
if ( ! pbuf )
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;
}
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;
bit32 += (i++ < len ? data[i-1] : 0) << 8;
bit32 += i++ < len ? data[i-1] : 0;
uint32_t bit32 = data[i++] << 16;
bit32 += (i++ < len ? data[i - 1] : 0) << 8;
bit32 += i++ < len ? data[i - 1] : 0;
buf[j++] = alphabet[(bit32 >> 18) & 0x3f];
buf[j++] = alphabet[(bit32 >> 12) & 0x3f];
buf[j++] = (i == (len+2)) ? '=' : alphabet[(bit32 >> 6) & 0x3f];
buf[j++] = (i >= (len+1)) ? '=' : alphabet[bit32 & 0x3f];
buf[j++] = alphabet[(bit32 >> 18) & 0x3f];
buf[j++] = alphabet[(bit32 >> 12) & 0x3f];
buf[j++] = (i == (len + 2)) ? '=' : alphabet[(bit32 >> 6) & 0x3f];
buf[j++] = (i >= (len + 1)) ? '=' : alphabet[bit32 & 0x3f];
}
}
int* Base64Converter::InitBase64Table(const std::string& alphabet)
{
assert(alphabet.size() == 64);
@ -111,7 +112,7 @@ Base64Converter::Base64Converter(Connection* arg_conn, const std::string& arg_al
Base64Converter::~Base64Converter()
{
if ( base64_table != default_base64_table )
delete [] base64_table;
delete[] base64_table;
}
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 )
break;
uint32_t bit32 =
((base64_group[0] & 0x3f) << 18) |
((base64_group[1] & 0x3f) << 12) |
((base64_group[2] & 0x3f) << 6) |
((base64_group[3] & 0x3f));
uint32_t bit32 = ((base64_group[0] & 0x3f) << 18) | ((base64_group[1] & 0x3f) << 12) |
((base64_group[2] & 0x3f) << 6) | ((base64_group[3] & 0x3f));
if ( --num_octets >= 0 )
*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);
if ( --num_octets >= 0 )
*buf++ = char((bit32) & 0xff);
*buf++ = char((bit32)&0xff);
if ( base64_padding > 0 )
base64_after_padding = 1;
@ -188,13 +186,14 @@ int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf)
if ( data[dlen] == '=' )
++base64_padding;
int k = base64_table[(unsigned char) data[dlen]];
int k = base64_table[(unsigned char)data[dlen]];
if ( k >= 0 )
base64_group[base64_group_next++] = k;
else
{
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;
@ -212,7 +211,7 @@ int Base64Converter::Done(int* pblen, char** pbuf)
{
if ( base64_group_next < 4 )
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);
return -1;
}
@ -224,29 +223,28 @@ int Base64Converter::Done(int* pblen, char** pbuf)
}
void Base64Converter::IllegalEncoding(const char* msg)
{
// strncpy(error_msg, msg, sizeof(error_msg));
if ( conn )
conn->Weird("base64_illegal_encoding", msg);
else
reporter->Error("%s", msg);
}
{
// strncpy(error_msg, msg, sizeof(error_msg));
if ( conn )
conn->Weird("base64_illegal_encoding", msg);
else
reporter->Error("%s", msg);
}
String* decode_base64(const String* s, const String* a, Connection* conn)
{
if ( a && a->Len() != 0 && a->Len() != 64 )
{
reporter->Error("base64 decoding alphabet is not 64 characters: %s",
a->CheckString());
reporter->Error("base64 decoding alphabet is not 64 characters: %s", a->CheckString());
return nullptr;
}
int buf_len = int((s->Len() + 3) / 4) * 3 + 1;
int rlen2, rlen = buf_len;
char* rbuf2, *rbuf = new char[rlen];
char *rbuf2, *rbuf = new char[rlen];
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() )
goto err;
@ -259,10 +257,10 @@ String* decode_base64(const String* s, const String* a, Connection* conn)
rlen += rlen2;
rbuf[rlen] = '\0';
return new String(true, (u_char*) rbuf, rlen);
return new String(true, (u_char*)rbuf, rlen);
err:
delete [] rbuf;
delete[] rbuf;
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 )
{
reporter->Error("base64 alphabet is not 64 characters: %s",
a->CheckString());
reporter->Error("base64 alphabet is not 64 characters: %s", a->CheckString());
return nullptr;
}
char* outbuf = nullptr;
int outlen = 0;
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);
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -1,17 +1,21 @@
#pragma once
#include "zeek/zeek-config.h"
#include <string>
namespace zeek {
#include "zeek/zeek-config.h"
namespace zeek
{
class String;
class Connection;
namespace detail {
namespace detail
{
// Maybe we should have a base class for generic decoders?
class Base64Converter {
class Base64Converter
{
public:
// <conn> is used for error reporting. If it is set to zero (as,
// e.g., done by the built-in functions decode_base64() and
@ -38,9 +42,9 @@ public:
bool HasData() const { return base64_group_next != 0; }
// True if an error has occurred.
int Errored() const { return errored; }
int Errored() const { return errored; }
const char* ErrorMsg() const { return error_msg; }
const char* ErrorMsg() const { return error_msg; }
void IllegalEncoding(const char* msg);
protected:
@ -57,13 +61,12 @@ protected:
int base64_padding;
int base64_after_padding;
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;
};
};
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);
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

@ -1,11 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/BifReturnVal.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
#include "zeek/zeek-config.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/zeek-config.h"
namespace zeek {
namespace zeek
{
class Val;
using ValPtr = IntrusivePtr<Val>;
namespace detail {
namespace detail
{
/**
* 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
* potentially be deprecated).
*/
class BifReturnVal {
class BifReturnVal
{
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;
ValPtr rval;
};
};
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

@ -1,14 +1,15 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/CCL.h"
#include <algorithm>
#include "zeek/RE.h"
#include "zeek/DFA.h"
#include "zeek/RE.h"
#include "zeek/zeek-config.h"
namespace zeek::detail {
namespace zeek::detail
{
CCL::CCL()
{
@ -48,7 +49,8 @@ void CCL::Sort()
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,34 +5,40 @@
#include <cstdint>
#include <vector>
namespace zeek::detail {
namespace zeek::detail
{
using int_list = std::vector<std::intptr_t>;
class CCL {
class CCL
{
public:
CCL();
~CCL();
void Add(int sym);
void Negate();
bool IsNegated() { return negated != 0; }
int Index() { return index; }
bool IsNegated() { return negated != 0; }
int Index() { return index; }
void Sort();
int_list* Syms() { return syms; }
int_list* Syms() { return 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.")]]
unsigned int MemoryAllocation() const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const;
protected:
int_list* syms;
int negated;
int index;
};
};
} // namespace zeek::detail
} // namespace zeek::detail

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

@ -3,26 +3,25 @@
#pragma once
#include <sys/types.h>
#include <string>
#include <tuple>
#include <type_traits>
#include "zeek/Dict.h"
#include "zeek/Timer.h"
#include "zeek/Rule.h"
#include "zeek/IPAddr.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/Rule.h"
#include "zeek/Timer.h"
#include "zeek/UID.h"
#include "zeek/WeirdState.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/Tag.h"
#include "zeek/iosource/Packet.h"
#include "zeek/session/Session.h"
namespace zeek {
namespace zeek
{
class Connection;
class EncapsulationStack;
@ -32,47 +31,59 @@ class RecordVal;
using ValPtr = IntrusivePtr<Val>;
using RecordValPtr = IntrusivePtr<RecordVal>;
namespace session { class Manager; }
namespace detail {
namespace session
{
class Manager;
}
namespace detail
{
class Specific_RE_Matcher;
class RuleEndpointState;
class RuleHdrTest;
} // namespace detail
} // namespace detail
namespace analyzer { class Analyzer; }
namespace packet_analysis::IP { class SessionAdapter; }
namespace analyzer
{
class Analyzer;
}
namespace packet_analysis::IP
{
class SessionAdapter;
}
enum ConnEventToFlag {
enum ConnEventToFlag
{
NUL_IN_LINE,
SINGULAR_CR,
SINGULAR_LF,
NUM_EVENTS_TO_FLAG,
};
};
struct ConnTuple {
struct ConnTuple
{
IPAddr src_addr;
IPAddr dst_addr;
uint32_t src_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;
};
};
using ConnID [[deprecated("Remove in v5.1. Use zeek::ConnTuple.")]] = ConnTuple;
static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1,
const IPAddr& addr2, uint32_t p2)
static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1, const IPAddr& addr2,
uint32_t p2)
{
return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
}
class Connection final : public session::Session {
class Connection final : public session::Session
{
public:
Connection(const detail::ConnKey& k, double t, const ConnTuple* id,
uint32_t flow, const Packet* pkt);
Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow,
const Packet* pkt);
~Connection() override;
/**
@ -101,34 +112,32 @@ public:
// If record_content is true, then its entire contents should
// be recorded, otherwise just up through the transport header.
// Both are assumed set to true when called.
void NextPacket(double t, bool is_orig,
const IP_Hdr* ip, int len, int caplen,
const u_char*& data,
int& record_packet, int& record_content,
void NextPacket(double t, bool is_orig, const IP_Hdr* ip, int len, int caplen,
const u_char*& data, int& record_packet, int& record_content,
// arguments for reproducing packets
const Packet *pkt);
const Packet* pkt);
// Keys are only considered valid for a connection when a
// connection is in the session map. If it is removed, the key
// should be marked invalid.
const detail::ConnKey& Key() const { return key; }
const detail::ConnKey& Key() const { return key; }
session::detail::Key SessionKey(bool copy) const override
{
return session::detail::Key{
&key, sizeof(key), session::detail::Key::CONNECTION_KEY_TYPE, copy};
return session::detail::Key{&key, sizeof(key), session::detail::Key::CONNECTION_KEY_TYPE,
copy};
}
const IPAddr& OrigAddr() const { return orig_addr; }
const IPAddr& RespAddr() const { return resp_addr; }
const IPAddr& OrigAddr() const { return orig_addr; }
const IPAddr& RespAddr() const { return resp_addr; }
uint32_t OrigPort() const { return orig_port; }
uint32_t RespPort() const { return resp_port; }
uint32_t OrigPort() const { return orig_port; }
uint32_t RespPort() const { return resp_port; }
void FlipRoles();
analyzer::Analyzer* FindAnalyzer(analyzer::ID id);
analyzer::Analyzer* FindAnalyzer(const analyzer::Tag& tag); // find first in tree.
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
analyzer::Analyzer* FindAnalyzer(const analyzer::Tag& tag); // find first in tree.
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
TransportProto ConnTransport() const { return proto; }
std::string TransportIdentifier() const override
@ -158,8 +167,8 @@ public:
*/
void AppendAddl(const char* str);
void Match(detail::Rule::PatternType type, const u_char* data, int len,
bool is_orig, bool bol, bool eol, bool clear_state);
void Match(detail::Rule::PatternType type, const u_char* data, int len, bool is_orig, bool bol,
bool eol, bool clear_state);
/**
* Generates connection removal event(s).
@ -167,7 +176,7 @@ public:
void RemovalEvent() override;
void Weird(const char* name, const char* addl = "", const char* source = "");
bool DidWeird() const { return weird != 0; }
bool DidWeird() const { return weird != 0; }
inline bool FlagEvent(ConnEventToFlag e)
{
@ -187,15 +196,15 @@ public:
// Statistics.
// Just a lower bound.
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const override;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocationVal() const override;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() 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()
{ return total_connections; }
static uint64_t CurrentConnections()
{ return current_connections; }
static uint64_t TotalConnections() { return total_connections; }
static uint64_t CurrentConnections() { return current_connections; }
// Returns true if the history was already seen, false otherwise.
bool CheckHistory(uint32_t mask, char code)
@ -214,59 +223,54 @@ public:
// code if it has crossed the next scaling threshold. Scaling
// is done in terms of powers of the third argument.
// Returns true if the threshold was crossed, false otherwise.
bool ScaledHistoryEntry(char code, uint32_t& counter,
uint32_t& scaling_threshold,
bool ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold,
uint32_t scaling_base = 10);
void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig,
uint32_t threshold);
void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold);
void AddHistory(char code) { history += code; }
void AddHistory(char code) { history += code; }
// Sets the root of the analyzer tree as well as the primary PIA.
void SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, analyzer::pia::PIA* pia);
packet_analysis::IP::SessionAdapter* GetSessionAdapter() { return adapter; }
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
packet_analysis::IP::SessionAdapter* GetSessionAdapter() { return adapter; }
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
// 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; }
std::shared_ptr<EncapsulationStack> GetEncapsulation() const
{ return encapsulation; }
std::shared_ptr<EncapsulationStack> GetEncapsulation() const { return encapsulation; }
void CheckFlowLabel(bool is_orig, uint32_t flow_label);
uint32_t GetOrigFlowLabel() { return orig_flow_label; }
uint32_t GetRespFlowLabel() { return resp_flow_label; }
bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate,
double duration);
bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration);
private:
friend class session::detail::Timer;
IPAddr orig_addr;
IPAddr resp_addr;
uint32_t orig_port, resp_port; // in network order
uint32_t orig_port, resp_port; // in network order
TransportProto proto;
uint32_t orig_flow_label, resp_flow_label; // most recent IPv6 flow labels
uint32_t vlan, inner_vlan; // VLAN this connection traverses, if available
u_char orig_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer originator address, if available
u_char resp_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer responder address, if available
int suppress_event; // suppress certain events to once per conn.
uint32_t orig_flow_label, resp_flow_label; // most recent IPv6 flow labels
uint32_t vlan, inner_vlan; // VLAN this connection traverses, if available
u_char orig_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer originator address, if available
u_char resp_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer responder address, if available
int suppress_event; // suppress certain events to once per conn.
RecordValPtr conn_val;
std::shared_ptr<EncapsulationStack> encapsulation; // tunnels
detail::ConnKey key;
unsigned int weird:1;
unsigned int finished:1;
unsigned int saw_first_orig_packet:1, saw_first_resp_packet:1;
unsigned int weird : 1;
unsigned int finished : 1;
unsigned int saw_first_orig_packet : 1, saw_first_resp_packet : 1;
uint32_t hist_seen;
std::string history;
@ -274,12 +278,12 @@ private:
packet_analysis::IP::SessionAdapter* adapter;
analyzer::pia::PIA* primary_PIA;
UID uid; // Globally unique connection ID.
UID uid; // Globally unique connection ID.
detail::WeirdStateMap weird_state;
// Count number of connections.
static uint64_t total_connections;
static uint64_t current_connections;
};
};
} // namespace zeek
} // namespace zeek

View file

@ -1,19 +1,19 @@
// 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/DFA.h"
#include "zeek/EquivClass.h"
#include "zeek/Desc.h"
#include "zeek/Hash.h"
namespace zeek::detail {
namespace zeek::detail
{
unsigned int DFA_State::transition_counter = 0;
DFA_State::DFA_State(int arg_state_num, const EquivClass* ec,
NFA_state_list* arg_nfa_states,
AcceptingSet* arg_accept)
DFA_State::DFA_State(int arg_state_num, const EquivClass* ec, NFA_state_list* arg_nfa_states,
AcceptingSet* arg_accept)
{
state_num = arg_state_num;
num_sym = ec->NumClasses();
@ -31,7 +31,7 @@ DFA_State::DFA_State(int arg_state_num, const EquivClass* ec,
DFA_State::~DFA_State()
{
delete [] xtions;
delete[] xtions;
delete nfa_states;
delete accept;
delete meta_ec;
@ -98,7 +98,7 @@ DFA_State* DFA_State::ComputeXtion(int sym, DFA_Machine* machine)
else
{
delete ns;
next_d = nullptr; // Jam
next_d = nullptr; // Jam
}
AddXtion(equiv_sym, next_d);
@ -163,7 +163,7 @@ NFA_state_list* DFA_State::SymFollowSet(int ec_sym, const EquivClass* ec)
break;
}
}
}
}
else if ( n->TransSym() == SYM_EPSILON )
{ // do nothing
@ -241,15 +241,14 @@ void DFA_State::Dump(FILE* f, DFA_Machine* m)
if ( i == sym + 1 )
sprintf(xbuf, "'%c'", r);
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 )
fprintf(f, "%stransition on %s to <uncomputed>",
++num_trans == 1 ? "\t" : "\n\t", xbuf);
fprintf(f, "%stransition on %s to <uncomputed>", ++num_trans == 1 ? "\t" : "\n\t",
xbuf);
else
fprintf(f, "%stransition on %s to state %d",
++num_trans == 1 ? "\t" : "\n\t", xbuf,
s->StateNum());
fprintf(f, "%stransition on %s to state %d", ++num_trans == 1 ? "\t" : "\n\t", xbuf,
s->StateNum());
sym = i - 1;
}
@ -283,11 +282,10 @@ void DFA_State::Stats(unsigned int* computed, unsigned int* uncomputed)
unsigned int DFA_State::Size()
{
return sizeof(*this)
+ util::pad_size(sizeof(DFA_State*) * num_sym)
+ (accept ? util::pad_size(sizeof(int) * accept->size()) : 0)
+ (nfa_states ? util::pad_size(sizeof(NFA_State*) * nfa_states->length()) : 0)
+ (meta_ec ? meta_ec->Size() : 0);
return sizeof(*this) + util::pad_size(sizeof(DFA_State*) * num_sym) +
(accept ? util::pad_size(sizeof(int) * accept->size()) : 0) +
(nfa_states ? util::pad_size(sizeof(NFA_State*) * nfa_states->length()) : 0) +
(meta_ec ? meta_ec->Size() : 0);
}
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);
id /= 10;
}
while ( id > 0 );
} while ( id > 0 );
*p++ = '&';
}
}
@ -428,15 +425,12 @@ unsigned int DFA_Machine::MemoryAllocation() const
// FIXME: Count *ec?
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return padded_sizeof(*this)
+ s.mem
+ padded_sizeof(*start_state)
+ nfa->MemoryAllocation();
return padded_sizeof(*this) + s.mem + padded_sizeof(*start_state) + nfa->MemoryAllocation();
#pragma GCC diagnostic pop
}
bool DFA_Machine::StateSetToDFA_State(NFA_state_list* state_set,
DFA_State*& d, const EquivClass* ec)
bool DFA_Machine::StateSetToDFA_State(NFA_state_list* state_set, DFA_State*& d,
const EquivClass* ec)
{
DigestStr digest;
d = dfa_state_cache->Lookup(*state_set, &digest);
@ -475,4 +469,4 @@ int DFA_Machine::Rep(int sym)
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.
#pragma once
#include <assert.h>
@ -9,10 +8,11 @@
#include <string>
#include "zeek/NFA.h"
#include "zeek/RE.h" // for typedef AcceptingSet
#include "zeek/Obj.h"
#include "zeek/RE.h" // for typedef AcceptingSet
namespace zeek::detail {
namespace zeek::detail
{
class DFA_State;
class DFA_Machine;
@ -20,32 +20,33 @@ class DFA_Machine;
// Transitions to the uncomputed state indicate that we haven't yet
// computed the state to go to.
#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:
DFA_State(int state_num, const EquivClass* ec,
NFA_state_list* nfa_states, AcceptingSet* accept);
DFA_State(int state_num, const EquivClass* ec, NFA_state_list* nfa_states,
AcceptingSet* accept);
~DFA_State() override;
int StateNum() const { return state_num; }
int NFAStateNum() const { return nfa_states->length(); }
int StateNum() const { return state_num; }
int NFAStateNum() const { return nfa_states->length(); }
void AddXtion(int sym, DFA_State* next_state);
inline DFA_State* Xtion(int sym, DFA_Machine* machine);
const AcceptingSet* Accept() const { return accept; }
const AcceptingSet* Accept() const { return accept; }
void SymPartition(const EquivClass* ec);
// ec_sym is an equivalence class, not a character.
NFA_state_list* SymFollowSet(int ec_sym, const EquivClass* ec);
void SetMark(DFA_State* m) { mark = m; }
DFA_State* Mark() const { return mark; }
void SetMark(DFA_State* m) { mark = m; }
DFA_State* Mark() const { return mark; }
void ClearMarks();
// Returns the equivalence classes of ec's corresponding to this state.
const EquivClass* MetaECs() const { return meta_ec; }
const EquivClass* MetaECs() const { return meta_ec; }
void Describe(ODesc* d) const override;
void Dump(FILE* f, DFA_Machine* m);
@ -65,15 +66,16 @@ protected:
AcceptingSet* accept;
NFA_state_list* nfa_states;
EquivClass* meta_ec; // which ec's make same transition
EquivClass* meta_ec; // which ec's make same transition
DFA_State* mark;
static unsigned int transition_counter; // see Xtion()
};
static unsigned int transition_counter; // see Xtion()
};
using DigestStr = std::basic_string<u_char>;
class DFA_State_Cache {
class DFA_State_Cache
{
public:
DFA_State_Cache();
~DFA_State_Cache();
@ -84,9 +86,10 @@ public:
// Takes ownership of state; digest is the one returned by Lookup().
DFA_State* Insert(DFA_State* state, DigestStr digest);
int NumEntries() const { return states.size(); }
int NumEntries() const { return states.size(); }
struct Stats {
struct Stats
{
// Sum of all NFA states
unsigned int nfa_states;
unsigned int dfa_states;
@ -95,54 +98,55 @@ public:
unsigned int mem;
unsigned int hits;
unsigned int misses;
};
};
void GetStats(Stats* s);
private:
int hits; // Statistics
int hits; // Statistics
int misses;
// Hash indexed by NFA states (MD5s of them, actually).
std::map<DigestStr, DFA_State*> states;
};
};
class DFA_Machine : public Obj {
class DFA_Machine : public Obj
{
public:
DFA_Machine(NFA_Machine* n, EquivClass* ec);
~DFA_Machine() override;
DFA_State* StartState() const { return start_state; }
DFA_State* StartState() const { return start_state; }
int NumStates() const { return dfa_state_cache->NumEntries(); }
int NumStates() const { return dfa_state_cache->NumEntries(); }
DFA_State_Cache* Cache() { return dfa_state_cache; }
DFA_State_Cache* Cache() { return dfa_state_cache; }
int Rep(int sym);
void Describe(ODesc* d) const override;
void Dump(FILE* f);
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const;
protected:
friend class DFA_State; // for DFA_State::ComputeXtion
friend class DFA_State; // for DFA_State::ComputeXtion
friend class DFA_State_Cache;
int state_count;
// The state list has to be sorted according to IDs.
bool StateSetToDFA_State(NFA_state_list* state_set, DFA_State*& d,
const EquivClass* ec);
const EquivClass* EC() const { return ec; }
bool StateSetToDFA_State(NFA_state_list* state_set, DFA_State*& d, const EquivClass* ec);
const EquivClass* EC() const { return ec; }
EquivClass* ec; // equivalence classes corresponding to NFAs
EquivClass* ec; // equivalence classes corresponding to NFAs
DFA_State* start_state;
DFA_State_Cache* dfa_state_cache;
NFA_Machine* nfa;
};
};
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];
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -1,88 +1,87 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/DNS_Mgr.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "zeek/zeek-config.h"
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#include <sys/time.h>
#include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <stdlib.h>
#include <algorithm>
#include "zeek/ZeekString.h"
#include "zeek/Expr.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/Val.h"
#include "zeek/NetVar.h"
#include "zeek/ID.h"
#include "zeek/Reporter.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/ZeekString.h"
#include "zeek/iosource/Manager.h"
#include "zeek/Hash.h"
extern "C" {
extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
extern "C"
{
extern int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
#include <netdb.h>
#include "zeek/nb_dns.h"
}
}
using namespace std;
namespace zeek::detail {
namespace zeek::detail
{
class DNS_Mgr_Request {
class DNS_Mgr_Request
{
public:
DNS_Mgr_Request(const char* h, int af, bool is_txt)
: host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr(),
request_pending()
{ }
: host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr(), request_pending()
{
}
DNS_Mgr_Request(const IPAddr& a)
: host(), fam(), qtype(), addr(a), request_pending()
{ }
DNS_Mgr_Request(const IPAddr& a) : 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.
const char* ReqHost() const { return host; }
const IPAddr& ReqAddr() const { return addr; }
bool ReqIsTxt() const { return qtype == 16; }
const char* ReqHost() const { return host; }
const IPAddr& ReqAddr() const { return addr; }
bool ReqIsTxt() const { return qtype == 16; }
int MakeRequest(nb_dns_info* nb_dns);
int RequestPending() const { return request_pending; }
void RequestDone() { request_pending = 0; }
int RequestPending() const { return request_pending; }
void RequestDone() { request_pending = 0; }
protected:
char* host; // if non-nil, this is a host request
int fam; // address family query type for host requests
int qtype; // Query type
char* host; // if non-nil, this is a host request
int fam; // address family query type for host requests
int qtype; // Query type
IPAddr addr;
int request_pending;
};
};
int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
{
@ -93,49 +92,47 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
char err[NB_DNS_ERRSIZE];
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
{
const uint32_t* bytes;
int len = addr.GetBytes(&bytes);
return nb_dns_addr_request2(nb_dns, (char*) bytes,
len == 1 ? AF_INET : AF_INET6, (void*) this, err) >= 0;
return nb_dns_addr_request2(nb_dns, (char*)bytes, len == 1 ? AF_INET : AF_INET6,
(void*)this, err) >= 0;
}
}
class DNS_Mapping {
class DNS_Mapping
{
public:
DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl);
DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl);
DNS_Mapping(FILE* f);
bool NoMapping() const { return no_mapping; }
bool InitFailed() const { return init_failed; }
bool NoMapping() const { return no_mapping; }
bool InitFailed() const { return init_failed; }
~DNS_Mapping();
// Returns nil if this was an address request.
const char* ReqHost() const { return req_host; }
IPAddr ReqAddr() const { return req_addr; }
string ReqStr() const
{
return req_host ? req_host : req_addr.AsString();
}
const char* ReqHost() const { return req_host; }
IPAddr ReqAddr() const { return req_addr; }
string ReqStr() const { return req_host ? req_host : req_addr.AsString(); }
ListValPtr Addrs();
TableValPtr AddrsSet(); // addresses returned as a set
TableValPtr AddrsSet(); // addresses returned as a set
StringValPtr Host();
double CreationTime() const { return creation_time; }
double CreationTime() const { return creation_time; }
void Save(FILE* f) const;
bool Failed() const { return failed; }
bool Valid() const { return ! failed; }
bool Failed() const { return failed; }
bool Valid() const { return ! failed; }
bool Expired() const
{
if ( req_host && num_addrs == 0)
if ( req_host && num_addrs == 0 )
return false; // nothing to expire
return util::current_time() > (creation_time + req_ttl);
@ -163,14 +160,14 @@ protected:
double creation_time;
int map_type;
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 failed;
};
};
void DNS_Mgr_mapping_delete_func(void* v)
{
delete (DNS_Mapping*) v;
delete (DNS_Mapping*)v;
}
static TableValPtr empty_addr_set()
@ -217,13 +214,12 @@ DNS_Mapping::DNS_Mapping(FILE* f)
return;
}
char req_buf[512+1], name_buf[512+1];
char req_buf[512 + 1], name_buf[512 + 1];
int is_req_host;
int failed_local;
if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time,
&is_req_host, req_buf, &failed_local, name_buf, &map_type, &num_addrs,
&req_ttl) != 8 )
if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, &is_req_host, req_buf,
&failed_local, name_buf, &map_type, &num_addrs, &req_ttl) != 8 )
return;
failed = static_cast<bool>(failed_local);
@ -264,16 +260,16 @@ DNS_Mapping::DNS_Mapping(FILE* f)
DNS_Mapping::~DNS_Mapping()
{
delete [] req_host;
delete[] req_host;
if ( names )
{
for ( int i = 0; i < num_names; ++i )
delete [] names[i];
delete [] names;
delete[] names[i];
delete[] names;
}
delete [] addrs;
delete[] addrs;
}
ListValPtr DNS_Mapping::Addrs()
@ -292,7 +288,8 @@ ListValPtr DNS_Mapping::Addrs()
return addrs_val;
}
TableValPtr DNS_Mapping::AddrsSet() {
TableValPtr DNS_Mapping::AddrsSet()
{
auto l = Addrs();
if ( ! l )
@ -327,7 +324,7 @@ void DNS_Mapping::Init(struct hostent* h)
}
map_type = h->h_addrtype;
num_names = 1; // for now, just use official name
num_names = 1; // for now, just use official name
names = new char*[num_names];
names[0] = h->h_name ? util::copy_string(h->h_name) : nullptr;
@ -339,11 +336,9 @@ void DNS_Mapping::Init(struct hostent* h)
addrs = new IPAddr[num_addrs];
for ( int i = 0; i < num_addrs; ++i )
if ( h->h_addrtype == AF_INET )
addrs[i] = IPAddr(IPv4, (uint32_t*)h->h_addr_list[i],
IPAddr::Network);
addrs[i] = IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], IPAddr::Network);
else if ( h->h_addrtype == AF_INET6 )
addrs[i] = IPAddr(IPv6, (uint32_t*)h->h_addr_list[i],
IPAddr::Network);
addrs[i] = IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], IPAddr::Network);
}
else
addrs = nullptr;
@ -365,16 +360,14 @@ void DNS_Mapping::Clear()
void DNS_Mapping::Save(FILE* f) const
{
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(),
failed, (names && names[0]) ? names[0] : "*",
map_type, num_addrs, req_ttl);
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(), failed,
(names && names[0]) ? names[0] : "*", map_type, num_addrs, req_ttl);
for ( int i = 0; i < num_addrs; ++i )
fprintf(f, "%s\n", addrs[i].AsString().c_str());
}
DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode)
{
did_init = false;
@ -395,8 +388,8 @@ DNS_Mgr::~DNS_Mgr()
if ( nb_dns )
nb_dns_finish(nb_dns);
delete [] cache_name;
delete [] dir;
delete[] cache_name;
delete[] dir;
}
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 char tmp[128];
snprintf(tmp, sizeof(tmp), "fake_addr_lookup_result_%s",
addr.AsString().c_str());
snprintf(tmp, sizeof(tmp), "fake_addr_lookup_result_%s", addr.AsString().c_str());
return tmp;
}
@ -520,26 +512,27 @@ TableValPtr DNS_Mgr::LookupHost(const char* name)
}
// Not found, or priming.
switch ( mode ) {
case DNS_PRIME:
requests.push_back(new DNS_Mgr_Request(name, AF_INET, false));
requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false));
return empty_addr_set();
switch ( mode )
{
case DNS_PRIME:
requests.push_back(new DNS_Mgr_Request(name, AF_INET, false));
requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false));
return empty_addr_set();
case DNS_FORCE:
reporter->FatalError("can't find DNS entry for %s in cache", name);
return nullptr;
case DNS_FORCE:
reporter->FatalError("can't find DNS entry for %s in cache", name);
return nullptr;
case DNS_DEFAULT:
requests.push_back(new DNS_Mgr_Request(name, AF_INET, false));
requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false));
Resolve();
return LookupHost(name);
case DNS_DEFAULT:
requests.push_back(new DNS_Mgr_Request(name, AF_INET, false));
requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false));
Resolve();
return LookupHost(name);
default:
reporter->InternalError("bad mode in DNS_Mgr::LookupHost");
return nullptr;
}
default:
reporter->InternalError("bad mode in DNS_Mgr::LookupHost");
return nullptr;
}
}
ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr)
@ -565,30 +558,28 @@ ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr)
}
// Not found, or priming.
switch ( mode ) {
case DNS_PRIME:
requests.push_back(new DNS_Mgr_Request(addr));
return make_intrusive<StringVal>("<none>");
switch ( mode )
{
case DNS_PRIME:
requests.push_back(new DNS_Mgr_Request(addr));
return make_intrusive<StringVal>("<none>");
case DNS_FORCE:
reporter->FatalError("can't find DNS entry for %s in cache",
addr.AsString().c_str());
return nullptr;
case DNS_FORCE:
reporter->FatalError("can't find DNS entry for %s in cache", addr.AsString().c_str());
return nullptr;
case DNS_DEFAULT:
requests.push_back(new DNS_Mgr_Request(addr));
Resolve();
return LookupAddr(addr);
case DNS_DEFAULT:
requests.push_back(new DNS_Mgr_Request(addr));
Resolve();
return LookupAddr(addr);
default:
reporter->InternalError("bad mode in DNS_Mgr::LookupAddr");
return nullptr;
}
default:
reporter->InternalError("bad mode in DNS_Mgr::LookupAddr");
return nullptr;
}
}
void DNS_Mgr::Verify()
{
}
void DNS_Mgr::Verify() { }
#define MAX_PENDING_REQUESTS 20
@ -628,8 +619,7 @@ void DNS_Mgr::Resolve()
}
first_req = last_req + 1;
num_pending = min(requests.length() - first_req,
MAX_PENDING_REQUESTS);
num_pending = min(requests.length() - first_req, MAX_PENDING_REQUESTS);
last_req = first_req + num_pending - 1;
for ( i = first_req; i <= last_req; ++i )
@ -642,12 +632,10 @@ void DNS_Mgr::Resolve()
struct nb_dns_result r;
status = nb_dns_activity(nb_dns, &r, err);
if ( status < 0 )
reporter->Warning(
"NB-DNS error in DNS_Mgr::WaitForReplies (%s)",
err);
reporter->Warning("NB-DNS error in DNS_Mgr::WaitForReplies (%s)", err);
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() )
{
AddResult(dr, &r);
@ -697,8 +685,7 @@ void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm)
event_mgr.Enqueue(e, BuildMappingVal(dm));
}
void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm,
ListValPtr l1, ListValPtr l2)
void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2)
{
if ( ! e )
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());
if ( it == host_mappings.end() )
{
host_mappings[dr->ReqHost()].first =
new_dm->Type() == AF_INET ? new_dm : nullptr;
host_mappings[dr->ReqHost()].first = new_dm->Type() == AF_INET ? new_dm : nullptr;
host_mappings[dr->ReqHost()].second =
new_dm->Type() == AF_INET ? nullptr : new_dm;
host_mappings[dr->ReqHost()].second = new_dm->Type() == AF_INET ? nullptr : new_dm;
}
else
{
@ -1029,15 +1014,13 @@ const char* DNS_Mgr::LookupTextInCache(const string& name)
return d->names ? d->names[0] : "<\?\?\?>";
}
static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback,
TableValPtr result)
static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, TableValPtr result)
{
callback->Resolved(result.get());
delete callback;
}
static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback,
const char* result)
static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, const char* result)
{
callback->Resolved(result);
delete callback;
@ -1184,15 +1167,16 @@ void DNS_Mgr::IssueAsyncRequests()
if ( req->IsAddrReq() )
success = DoRequest(nb_dns, new DNS_Mgr_Request(req->host));
else if ( req->is_txt )
success = 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(), AF_INET, req->is_txt));
else
{
// If only one request type succeeds, don't consider it a failure.
success = 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(),
AF_INET6, req->is_txt)) || success;
success =
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(), AF_INET6, req->is_txt)) ||
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
// eventually times out.
}
}
void DNS_Mgr::CheckAsyncTextRequest(const char* host, bool timeout)
@ -1378,11 +1361,10 @@ void DNS_Mgr::Process()
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;
if ( dr->ReqHost() &&
host_mappings.find(dr->ReqHost()) == host_mappings.end() )
if ( dr->ReqHost() && host_mappings.find(dr->ReqHost()) == host_mappings.end() )
// Don't timeout when this is the first result in an expected pair
// (one result each for A and AAAA queries).
do_host_timeout = false;
@ -1427,7 +1409,7 @@ int DNS_Mgr::AnswerAvailable(int timeout)
t.tv_sec = timeout;
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 )
{
@ -1463,4 +1445,4 @@ void DNS_Mgr::Terminate()
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
@ -7,13 +7,14 @@
#include <queue>
#include <utility>
#include "zeek/List.h"
#include "zeek/EventHandler.h"
#include "zeek/iosource/IOSource.h"
#include "zeek/IPAddr.h"
#include "zeek/List.h"
#include "zeek/iosource/IOSource.h"
#include "zeek/util.h"
namespace zeek {
namespace zeek
{
class EventHandler;
class RecordType;
@ -26,30 +27,33 @@ using ValPtr = IntrusivePtr<Val>;
using ListValPtr = IntrusivePtr<ListVal>;
using TableValPtr = IntrusivePtr<TableVal>;
} // namespace zeek
} // namespace zeek
// Defined in nb_dns.h
struct nb_dns_info;
struct nb_dns_result;
namespace zeek::detail {
namespace zeek::detail
{
class DNS_Mgr_Request;
using DNS_mgr_request_list = PList<DNS_Mgr_Request>;
class DNS_Mapping;
enum DNS_MgrMode {
DNS_PRIME, // used to prime the cache
DNS_FORCE, // internal error if cache miss
DNS_DEFAULT, // lookup names as they're requested
DNS_FAKE, // don't look up names, just return dummy results
};
enum DNS_MgrMode
{
DNS_PRIME, // used to prime the cache
DNS_FORCE, // internal error if cache miss
DNS_DEFAULT, // lookup names as they're requested
DNS_FAKE, // don't look up names, just return dummy results
};
// Number of seconds we'll wait for a reply.
#define DNS_TIMEOUT 5
class DNS_Mgr final : public iosource::IOSource {
class DNS_Mgr final : public iosource::IOSource
{
public:
explicit DNS_Mgr(DNS_MgrMode mode);
~DNS_Mgr() override;
@ -64,7 +68,7 @@ public:
ValPtr LookupAddr(const IPAddr& addr);
// Define the directory where to store the data.
void SetDir(const char* arg_dir) { dir = util::copy_string(arg_dir); }
void SetDir(const char* arg_dir) { dir = util::copy_string(arg_dir); }
void Verify();
void Resolve();
@ -75,29 +79,31 @@ public:
const char* LookupTextInCache(const std::string& name);
// Support for async lookups.
class LookupCallback {
class LookupCallback
{
public:
LookupCallback() { }
virtual ~LookupCallback() { }
LookupCallback() { }
virtual ~LookupCallback() { }
virtual void Resolved(const char* name) { };
virtual void Resolved(TableVal* addrs) { };
virtual void Resolved(const char* name){};
virtual void Resolved(TableVal* addrs){};
virtual void Timeout() = 0;
};
};
void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback);
void AsyncLookupName(const std::string& name, LookupCallback* callback);
void AsyncLookupNameText(const std::string& name, LookupCallback* callback);
struct Stats {
unsigned long requests; // These count only async requests.
struct Stats
{
unsigned long requests; // These count only async requests.
unsigned long successful;
unsigned long failed;
unsigned long pending;
unsigned long cached_hosts;
unsigned long cached_addresses;
unsigned long cached_texts;
};
};
void GetStats(Stats* stats);
@ -108,8 +114,7 @@ protected:
friend class DNS_Mgr_Request;
void Event(EventHandlerPtr e, DNS_Mapping* dm);
void Event(EventHandlerPtr e, DNS_Mapping* dm,
ListValPtr l1, ListValPtr l2);
void Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2);
void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm);
ValPtr BuildMappingVal(DNS_Mapping* dm);
@ -119,7 +124,7 @@ protected:
ListValPtr AddrListDelta(ListVal* al1, ListVal* al2);
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<std::string, DNS_Mapping*> TextMap;
void LoadCache(FILE* f);
@ -143,7 +148,7 @@ protected:
// IOSource interface.
void Process() override;
void InitSource() override;
const char* Tag() override { return "DNS_Mgr"; }
const char* Tag() override { return "DNS_Mgr"; }
double GetNextTimeout() override;
DNS_MgrMode mode;
@ -156,7 +161,7 @@ protected:
nb_dns_info* nb_dns;
char* cache_name;
char* dir; // directory in which cache_name resides
char* dir; // directory in which cache_name resides
bool did_init;
int asyncs_pending;
@ -165,7 +170,8 @@ protected:
typedef std::list<LookupCallback*> CallbackList;
struct AsyncRequest {
struct AsyncRequest
{
double time;
IPAddr host;
std::string name;
@ -175,12 +181,11 @@ protected:
AsyncRequest() : time(0.0), is_txt(false), processed(false) { }
bool IsAddrReq() const { return name.empty(); }
bool IsAddrReq() const { return name.empty(); }
void Resolved(const char* name)
{
for ( CallbackList::iterator i = callbacks.begin();
i != callbacks.end(); ++i )
for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i )
{
(*i)->Resolved(name);
delete *i;
@ -191,8 +196,7 @@ protected:
void Resolved(TableVal* addrs)
{
for ( CallbackList::iterator i = callbacks.begin();
i != callbacks.end(); ++i )
for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i )
{
(*i)->Resolved(addrs);
delete *i;
@ -203,8 +207,7 @@ protected:
void Timeout()
{
for ( CallbackList::iterator i = callbacks.begin();
i != callbacks.end(); ++i )
for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i )
{
(*i)->Timeout();
delete *i;
@ -212,8 +215,7 @@ protected:
callbacks.clear();
processed = true;
}
};
};
typedef std::map<IPAddr, AsyncRequest*> AsyncRequestAddrMap;
AsyncRequestAddrMap asyncs_addrs;
@ -227,21 +229,20 @@ protected:
typedef std::list<AsyncRequest*> QueuedList;
QueuedList asyncs_queued;
struct AsyncRequestCompare {
bool operator()(const AsyncRequest* a, const AsyncRequest* b)
{
return a->time > b->time;
}
};
struct AsyncRequestCompare
{
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;
unsigned long num_requests;
unsigned long successful;
unsigned long failed;
};
};
extern DNS_Mgr* dns_mgr;
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -1,37 +1,39 @@
// Implementation of breakpoints.
#include "zeek/zeek-config.h"
#include "zeek/DbgBreakpoint.h"
#include <assert.h>
#include "zeek/Desc.h"
#include "zeek/ID.h"
#include "zeek/Debug.h"
#include "zeek/Scope.h"
#include "zeek/Desc.h"
#include "zeek/Frame.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/Timer.h"
#include "zeek/Reporter.h"
#include "zeek/Val.h"
#include "zeek/module_util.h"
#include "zeek/zeek-config.h"
namespace zeek::detail {
namespace zeek::detail
{
// BreakpointTimer used for time-based breakpoints
class BreakpointTimer final : public Timer {
class BreakpointTimer final : public Timer
{
public:
BreakpointTimer(DbgBreakpoint* arg_bp, double arg_t)
: Timer(arg_t, TIMER_BREAKPOINT)
{ bp = arg_bp; }
BreakpointTimer(DbgBreakpoint* arg_bp, double arg_t) : Timer(arg_t, TIMER_BREAKPOINT)
{
bp = arg_bp;
}
void Dispatch(double t, bool is_expire) override;
protected:
DbgBreakpoint* bp;
};
};
void BreakpointTimer::Dispatch(double t, bool is_expire)
{
@ -41,7 +43,6 @@ void BreakpointTimer::Dispatch(double t, bool is_expire)
bp->ShouldBreak(t);
}
DbgBreakpoint::DbgBreakpoint()
{
kind = BP_STMT;
@ -61,7 +62,7 @@ DbgBreakpoint::DbgBreakpoint()
DbgBreakpoint::~DbgBreakpoint()
{
SetEnable(false); // clean up any active state
SetEnable(false); // clean up any active state
RemoveFromGlobalMap();
}
@ -119,7 +120,6 @@ void DbgBreakpoint::RemoveFromStmt()
at_stmt->DecrBPCount();
}
bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str)
{
if ( plr.type == PLR_UNKNOWN )
@ -141,8 +141,7 @@ bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str)
}
at_stmt = plr.stmt;
snprintf(description, sizeof(description), "%s:%d",
source_filename, source_line);
snprintf(description, sizeof(description), "%s:%d", source_filename, source_line);
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);
kind = BP_FUNC;
function_name = make_full_var_name(current_module.c_str(),
loc_s.c_str());
function_name = make_full_var_name(current_module.c_str(), loc_s.c_str());
at_stmt = plr.stmt;
const Location* loc = at_stmt->GetLocationInfo();
snprintf(description, sizeof(description), "%s at %s:%d",
function_name.c_str(), loc->filename, loc->last_line);
snprintf(description, sizeof(description), "%s at %s:%d", function_name.c_str(),
loc->filename, loc->last_line);
debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
}
@ -178,8 +176,7 @@ bool DbgBreakpoint::SetLocation(Stmt* stmt)
AddToGlobalMap();
const Location* loc = stmt->GetLocationInfo();
snprintf(description, sizeof(description), "%s:%d",
loc->filename, loc->last_line);
snprintf(description, sizeof(description), "%s:%d", loc->filename, loc->last_line);
debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
@ -204,19 +201,20 @@ bool DbgBreakpoint::Reset()
{
ParseLocationRec plr;
switch ( kind ) {
case BP_TIME:
debug_msg("Time-based breakpoints not yet supported.\n");
break;
switch ( kind )
{
case BP_TIME:
debug_msg("Time-based breakpoints not yet supported.\n");
break;
case BP_FUNC:
case BP_STMT:
case BP_LINE:
plr.type = PLR_FUNCTION;
//### How to deal with wildcards?
//### perhaps save user choices?--tough...
break;
}
case BP_FUNC:
case BP_STMT:
case BP_LINE:
plr.type = PLR_FUNCTION;
//### How to deal with wildcards?
//### perhaps save user choices?--tough...
break;
}
reporter->InternalError("DbgBreakpoint::Reset function incomplete.");
@ -252,14 +250,13 @@ BreakCode DbgBreakpoint::HasHit()
if ( ! yes )
{
debug_msg("Breakpoint condition '%s' invalid, removing condition.\n",
condition.c_str());
condition.c_str());
SetCondition("");
PrintHitMsg();
return BC_HIT;
}
if ( ! IsIntegral(yes->GetType()->Tag()) &&
! IsBool(yes->GetType()->Tag()) )
if ( ! IsIntegral(yes->GetType()->Tag()) && ! IsBool(yes->GetType()->Tag()) )
{
PrintHitMsg();
debug_msg("Breakpoint condition should return an integral type");
@ -295,24 +292,25 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
if ( ! IsEnabled() )
return BC_NO_HIT;
switch ( kind ) {
case BP_STMT:
case BP_FUNC:
if ( at_stmt != s )
return BC_NO_HIT;
break;
switch ( kind )
{
case BP_STMT:
case BP_FUNC:
if ( at_stmt != s )
return BC_NO_HIT;
break;
case BP_LINE:
assert(s->GetLocationInfo()->first_line <= source_line &&
s->GetLocationInfo()->last_line >= source_line);
break;
case BP_LINE:
assert(s->GetLocationInfo()->first_line <= source_line &&
s->GetLocationInfo()->last_line >= source_line);
break;
case BP_TIME:
assert(false);
case BP_TIME:
assert(false);
default:
reporter->InternalError("Invalid breakpoint type in DbgBreakpoint::ShouldBreak");
}
default:
reporter->InternalError("Invalid breakpoint type in DbgBreakpoint::ShouldBreak");
}
// If we got here, that means that the breakpoint could hit,
// except potentially if it has a special condition or a repeat count.
@ -324,7 +322,6 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
return code;
}
BreakCode DbgBreakpoint::ShouldBreak(double t)
{
if ( kind != BP_TIME )
@ -345,32 +342,32 @@ BreakCode DbgBreakpoint::ShouldBreak(double t)
void DbgBreakpoint::PrintHitMsg()
{
switch ( kind ) {
case BP_STMT:
case BP_FUNC:
case BP_LINE:
switch ( kind )
{
ODesc d;
Frame* f = g_frame_stack.back();
const ScriptFunc* func = f->GetFunction();
case BP_STMT:
case BP_FUNC:
case BP_LINE:
{
ODesc d;
Frame* f = g_frame_stack.back();
const ScriptFunc* func = f->GetFunction();
if ( func )
func->DescribeDebug (&d, f->GetFuncArgs());
if ( func )
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",
GetID(), d.Description(),
loc->filename, loc->first_line);
debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->filename,
loc->first_line);
}
return;
case BP_TIME:
assert(false);
default:
reporter->InternalError("Missed a case in DbgBreakpoint::PrintHitMsg\n");
}
return;
case BP_TIME:
assert(false);
default:
reporter->InternalError("Missed a case in DbgBreakpoint::PrintHitMsg\n");
}
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -3,34 +3,48 @@
#pragma once
#include <string>
#include "zeek/util.h"
namespace zeek::detail {
namespace zeek::detail
{
class Stmt;
class ParseLocationRec;
enum BreakCode { BC_NO_HIT, BC_HIT, BC_HIT_AND_DELETE };
class DbgBreakpoint {
enum Kind { BP_STMT = 0, BP_FUNC, BP_LINE, BP_TIME };
enum BreakCode
{
BC_NO_HIT,
BC_HIT,
BC_HIT_AND_DELETE
};
class DbgBreakpoint
{
enum Kind
{
BP_STMT = 0,
BP_FUNC,
BP_LINE,
BP_TIME
};
public:
DbgBreakpoint();
~DbgBreakpoint();
int GetID() const { return BPID; }
void SetID(int newID) { BPID = newID; }
int GetID() const { return BPID; }
void SetID(int newID) { BPID = newID; }
// True if breakpoint could be set; false otherwise
bool SetLocation(ParseLocationRec plr, std::string_view loc_str);
bool SetLocation(Stmt* stmt);
bool SetLocation(double time);
bool Reset(); // cancel and re-apply bpt when restarting execution
bool Reset(); // cancel and re-apply bpt when restarting execution
// Temporary = disable (remove?) the breakpoint right after it's hit.
bool IsTemporary() const { return temporary; }
void SetTemporary(bool is_temporary) { temporary = is_temporary; }
bool IsTemporary() const { return temporary; }
void SetTemporary(bool is_temporary) { temporary = is_temporary; }
// Feed it a Stmt* or a time and see if this breakpoint should
// hit. bcHitAndDelete means that it has hit, and should now be
@ -41,17 +55,17 @@ public:
BreakCode ShouldBreak(Stmt* s);
BreakCode ShouldBreak(double t);
const std::string& GetCondition() const { return condition; }
const std::string& GetCondition() const { return condition; }
bool SetCondition(const std::string& new_condition);
int GetRepeatCount() const { return repeat_count; }
int GetRepeatCount() const { return repeat_count; }
bool SetRepeatCount(int count); // implements function of ignore command in gdb
bool IsEnabled() const { return enabled; }
bool IsEnabled() const { return enabled; }
bool SetEnable(bool do_enable);
// e.g. "FooBar() at foo.c:23"
const char * Description() const { return description; }
const char* Description() const { return description; }
protected:
void AddToGlobalMap();
@ -60,27 +74,27 @@ protected:
void AddToStmt();
void RemoveFromStmt();
BreakCode HasHit(); // a breakpoint hit, update state, return proper code.
void PrintHitMsg(); // display reason when the breakpoint hits
BreakCode HasHit(); // a breakpoint hit, update state, return proper code.
void PrintHitMsg(); // display reason when the breakpoint hits
Kind kind;
int32_t BPID;
char description[512];
std::string function_name; // location
std::string function_name; // location
const char* source_filename;
int32_t source_line;
bool enabled; // ### comment this and next
bool enabled; // ### comment this and next
bool temporary;
Stmt* at_stmt;
double at_time; // break when the virtual time is this
double at_time; // break when the virtual time is this
// Support for conditional and N'th time breakpoints.
int32_t repeat_count; // if positive, break after this many hits
int32_t hit_count; // how many times it's been hit (w/o breaking)
int32_t repeat_count; // if positive, break after this many hits
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,16 +2,18 @@
#pragma once
namespace zeek::detail {
namespace zeek::detail
{
class Expr;
// Automatic displays: display these at each stoppage.
class DbgDisplay {
class DbgDisplay
{
public:
DbgDisplay(Expr* expr_to_display);
bool IsEnabled() { return enabled; }
bool IsEnabled() { return enabled; }
bool SetEnable(bool do_enable)
{
bool old_value = enabled;
@ -19,11 +21,11 @@ public:
return old_value;
}
const Expr* Expression() const { return expression; }
const Expr* Expression() const { return expression; }
protected:
bool enabled;
Expr* expression;
};
} // namespace zeek::detail
} // namespace zeek::detail

View file

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

View file

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

View file

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

View file

@ -1,42 +1,41 @@
// Debugging support for Bro policy files.
#include "zeek/zeek-config.h"
#include "zeek/Debug.h"
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
#include "zeek/zeek-config.h"
#ifdef HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#include <readline/readline.h>
#endif
#include "zeek/util.h"
#include "zeek/DebugCmds.h"
#include "zeek/DbgBreakpoint.h"
#include "zeek/ID.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/DebugCmds.h"
#include "zeek/Desc.h"
#include "zeek/Expr.h"
#include "zeek/Stmt.h"
#include "zeek/Frame.h"
#include "zeek/Func.h"
#include "zeek/ID.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/Scope.h"
#include "zeek/PolicyFile.h"
#include "zeek/Desc.h"
#include "zeek/Reporter.h"
#include "zeek/Scope.h"
#include "zeek/Stmt.h"
#include "zeek/Val.h"
#include "zeek/module_util.h"
#include "zeek/input.h"
#include "zeek/module_util.h"
#include "zeek/util.h"
extern "C" {
extern "C"
{
#include "zeek/setsignal.h"
}
}
using namespace std;
@ -63,11 +62,12 @@ struct yy_buffer_state;
typedef struct yy_buffer_state* YY_BUFFER_STATE;
YY_BUFFER_STATE bro_scan_string(const char*);
extern YYLTYPE yylloc; // holds start line and column of token
extern YYLTYPE yylloc; // holds start line and column of token
extern int line_number;
extern const char* filename;
namespace zeek::detail {
namespace zeek::detail
{
DebuggerState::DebuggerState()
{
@ -88,15 +88,13 @@ DebuggerState::~DebuggerState()
bool StmtLocMapping::StartsAfter(const StmtLocMapping* m2)
{
if ( ! m2 )
if ( ! m2 )
reporter->InternalError("Assertion failed: m2 != 0");
return loc.first_line > m2->loc.first_line ||
(loc.first_line == m2->loc.first_line &&
loc.first_column > m2->loc.first_column);
(loc.first_line == m2->loc.first_line && loc.first_column > m2->loc.first_column);
}
// Generic debug message output.
int debug_msg(const char* fmt, ...)
{
@ -110,7 +108,6 @@ int debug_msg(const char* fmt, ...)
return retval;
}
// Trace message output
FILE* TraceState::SetTraceFile(const char* trace_filename)
@ -195,7 +192,6 @@ int TraceState::LogTrace(const char* fmt, ...)
return retval;
}
// Helper functions.
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();
}
static void parse_function_name(vector<ParseLocationRec>& result,
ParseLocationRec& plr, const string& s)
static void parse_function_name(vector<ParseLocationRec>& result, ParseLocationRec& plr,
const string& s)
{ // function name
const auto& id = lookup_ID(s.c_str(), current_module.c_str());
@ -254,7 +250,7 @@ static void parse_function_name(vector<ParseLocationRec>& result,
return;
}
Stmt* body = nullptr; // the particular body we care about; 0 = all
Stmt* body = nullptr; // the particular body we care about; 0 = all
if ( bodies.size() == 1 )
body = bodies[0].stmts.get();
@ -263,13 +259,13 @@ static void parse_function_name(vector<ParseLocationRec>& result,
while ( true )
{
debug_msg("There are multiple definitions of that event handler.\n"
"Please choose one of the following options:\n");
"Please choose one of the following options:\n");
for ( unsigned int i = 0; i < bodies.size(); ++i )
{
Stmt* first;
Location 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");
@ -298,7 +294,7 @@ static void parse_function_name(vector<ParseLocationRec>& result,
}
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();
break;
@ -394,7 +390,7 @@ vector<ParseLocationRec> parse_location_string(const string& s)
auto iter = g_dbgfilemaps.find(loc_filename);
if ( iter == g_dbgfilemaps.end() )
reporter->InternalError("Policy file %s should have been loaded\n",
loc_filename.data());
loc_filename.data());
if ( plr.line > how_many_lines_in(loc_filename.data()) )
{
@ -411,8 +407,7 @@ vector<ParseLocationRec> parse_location_string(const string& s)
if ( entry->Loc().first_line > plr.line )
break;
if ( plr.line >= entry->Loc().first_line &&
plr.line <= entry->Loc().last_line )
if ( plr.line >= entry->Loc().first_line && plr.line <= entry->Loc().last_line )
{
hit = entry;
break;
@ -428,7 +423,6 @@ vector<ParseLocationRec> parse_location_string(const string& s)
return result;
}
// Interactive debugging console.
static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args);
@ -458,7 +452,7 @@ void break_signal(int)
int dbg_init_debugger(const char* cmdfile)
{
if ( ! g_policy_debug )
return 0; // probably shouldn't have been called
return 0; // probably shouldn't have been called
init_global_dbg_constants();
@ -469,7 +463,7 @@ int dbg_init_debugger(const char* cmdfile)
// ### Implement this
debug_msg("Command files not supported. Using interactive mode.\n");
// ### if ( interactive ) (i.e., not reading cmds from a file)
// ### if ( interactive ) (i.e., not reading cmds from a file)
#ifdef HAVE_READLINE
init_readline();
#endif
@ -486,7 +480,6 @@ int dbg_shutdown_debugger()
return 1;
}
// 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
// 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';
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;
int start = i;
@ -512,7 +505,7 @@ void tokenize(const char* cstr, string& operation, vector<string>& arguments)
{
if ( str[i] == '\\' )
{
if ( i < (signed int) str.length() )
if ( i < (signed int)str.length() )
++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.
int dbg_execute_command(const char* cmd)
{
@ -563,8 +555,7 @@ int dbg_execute_command(const char* cmd)
if ( ! entry )
return 0;
const DebugCmdInfo* info =
(const DebugCmdInfo*) entry->data;
const DebugCmdInfo* info = (const DebugCmdInfo*)entry->data;
if ( info && info->Repeatable() )
{
@ -585,7 +576,7 @@ int dbg_execute_command(const char* cmd)
vector<string> arguments;
tokenize(localcmd, opstring, arguments);
delete [] localcmd;
delete[] localcmd;
// Make sure we know this op name.
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 )
if ( matching_cmds[i] )
{
cmd_code = (DebugCmd) i;
cmd_code = (DebugCmd)i;
break;
}
@ -628,9 +619,9 @@ int dbg_execute_command(const char* cmd)
* http://tiswww.case.edu/php/chet/readline/history.html
* 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();
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
@ -643,11 +634,11 @@ int dbg_execute_command(const char* cmd)
return retcode;
const DebugCmdInfo* info = get_debug_cmd_info(cmd_code);
if ( ! info )
if ( ! info )
reporter->InternalError("Assertion failed: info");
if ( ! info )
return -2; // ### yuck, why -2?
return -2; // ### yuck, why -2?
return info->ResumeExecution();
}
@ -655,85 +646,86 @@ int dbg_execute_command(const char* cmd)
// Call the appropriate function for the command.
static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args)
{
switch ( cmd_code ) {
case dcHelp:
dbg_cmd_help(cmd_code, args);
break;
switch ( cmd_code )
{
case dcHelp:
dbg_cmd_help(cmd_code, args);
break;
case dcQuit:
debug_msg("Program Terminating\n");
exit(0);
case dcQuit:
debug_msg("Program Terminating\n");
exit(0);
case dcNext:
g_frame_stack.back()->BreakBeforeNextStmt(true);
step_or_next_pending = true;
last_frame = g_frame_stack.back();
break;
case dcNext:
g_frame_stack.back()->BreakBeforeNextStmt(true);
step_or_next_pending = true;
last_frame = g_frame_stack.back();
break;
case dcStep:
g_debugger_state.BreakBeforeNextStmt(true);
step_or_next_pending = true;
last_frame = g_frame_stack.back();
break;
case dcStep:
g_debugger_state.BreakBeforeNextStmt(true);
step_or_next_pending = true;
last_frame = g_frame_stack.back();
break;
case dcContinue:
g_debugger_state.BreakBeforeNextStmt(false);
debug_msg("Continuing.\n");
break;
case dcContinue:
g_debugger_state.BreakBeforeNextStmt(false);
debug_msg("Continuing.\n");
break;
case dcFinish:
g_frame_stack.back()->BreakOnReturn(true);
g_debugger_state.BreakBeforeNextStmt(false);
break;
case dcFinish:
g_frame_stack.back()->BreakOnReturn(true);
g_debugger_state.BreakBeforeNextStmt(false);
break;
case dcBreak:
dbg_cmd_break(cmd_code, args);
break;
case dcBreak:
dbg_cmd_break(cmd_code, args);
break;
case dcBreakCondition:
dbg_cmd_break_condition(cmd_code, args);
break;
case dcBreakCondition:
dbg_cmd_break_condition(cmd_code, args);
break;
case dcDeleteBreak:
case dcClearBreak:
case dcDisableBreak:
case dcEnableBreak:
case dcIgnoreBreak:
dbg_cmd_break_set_state(cmd_code, args);
break;
case dcDeleteBreak:
case dcClearBreak:
case dcDisableBreak:
case dcEnableBreak:
case dcIgnoreBreak:
dbg_cmd_break_set_state(cmd_code, args);
break;
case dcPrint:
dbg_cmd_print(cmd_code, args);
break;
case dcPrint:
dbg_cmd_print(cmd_code, args);
break;
case dcBacktrace:
return dbg_cmd_backtrace(cmd_code, args);
case dcBacktrace:
return dbg_cmd_backtrace(cmd_code, args);
case dcFrame:
case dcUp:
case dcDown:
return dbg_cmd_frame(cmd_code, args);
case dcFrame:
case dcUp:
case dcDown:
return dbg_cmd_frame(cmd_code, args);
case dcInfo:
return dbg_cmd_info(cmd_code, args);
case dcInfo:
return dbg_cmd_info(cmd_code, args);
case dcList:
return dbg_cmd_list(cmd_code, args);
case dcList:
return dbg_cmd_list(cmd_code, args);
case dcDisplay:
case dcUndisplay:
debug_msg("Command not yet implemented.\n");
break;
case dcDisplay:
case dcUndisplay:
debug_msg("Command not yet implemented.\n");
break;
case dcTrace:
return dbg_cmd_trace(cmd_code, args);
case dcTrace:
return dbg_cmd_trace(cmd_code, args);
default:
debug_msg("INTERNAL ERROR: "
"Got an unknown debugger command in DbgDispatchCmd: %d\n",
cmd_code);
return 0;
}
default:
debug_msg("INTERNAL ERROR: "
"Got an unknown debugger command in DbgDispatchCmd: %d\n",
cmd_code);
return 0;
}
return 0;
}
@ -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;
char* buf = new char[buf_size];
snprintf(buf, buf_size, "In %s at %s:%d",
d.Description(), loc.filename, loc.last_line);
snprintf(buf, buf_size, "In %s at %s:%d", d.Description(), loc.filename, loc.last_line);
string retval(buf);
delete [] buf;
delete[] buf;
return retval;
}
@ -807,29 +798,27 @@ int dbg_handle_debug_input()
if ( ! step_or_next_pending || g_frame_stack.back() != last_frame )
{
string context =
get_context_description(stmt, g_frame_stack.back());
string context = get_context_description(stmt, g_frame_stack.back());
debug_msg("%s\n", context.c_str());
}
step_or_next_pending = false;
PrintLines(loc.filename, loc.first_line,
loc.last_line - loc.first_line + 1, true);
PrintLines(loc.filename, loc.first_line, loc.last_line - loc.first_line + 1, true);
g_debugger_state.last_loc = loc;
do
{
// readline returns a pointer to a buffer it allocates; it's
// freed at the bottom.
// readline returns a pointer to a buffer it allocates; it's
// freed at the bottom.
#ifdef HAVE_READLINE
input_line = readline(get_prompt());
#else
printf ("%s", get_prompt());
printf("%s", get_prompt());
// readline uses malloc, and we want to be consistent
// with it.
input_line = (char*) util::safe_malloc(1024);
input_line = (char*)util::safe_malloc(1024);
input_line[1023] = 0;
// ### Maybe it's not always stdin.
input_line = fgets(input_line, 1023, stdin);
@ -843,13 +832,12 @@ int dbg_handle_debug_input()
if ( input_line )
{
free(input_line); // this was malloc'ed
free(input_line); // this was malloc'ed
input_line = nullptr;
}
else
exit(0);
}
while ( status == 0 );
} while ( status == 0 );
// Clear out some state. ### Is there a better place?
g_debugger_state.curr_frame_idx = 0;
@ -861,12 +849,10 @@ int dbg_handle_debug_input()
return 0;
}
// Return true to continue execution, false to abort.
bool pre_execute_stmt(Stmt* stmt, Frame* f)
{
if ( ! g_policy_debug ||
stmt->Tag() == STMT_LIST || stmt->Tag() == STMT_NULL )
if ( ! g_policy_debug || stmt->Tag() == STMT_LIST || stmt->Tag() == STMT_NULL )
return true;
if ( g_trace_state.DoTrace() )
@ -888,8 +874,7 @@ bool pre_execute_stmt(Stmt* stmt, Frame* f)
bool should_break = false;
if ( g_debugger_state.BreakBeforeNextStmt() ||
f->BreakBeforeNextStmt() )
if ( g_debugger_state.BreakBeforeNextStmt() || f->BreakBeforeNextStmt() )
{
if ( g_debugger_state.BreakBeforeNextStmt() )
g_debugger_state.BreakBeforeNextStmt(false);
@ -912,7 +897,7 @@ bool pre_execute_stmt(Stmt* stmt, Frame* f)
for ( BPMapType::iterator i = p.first; i != p.second; ++i )
{
int break_code = i->second->ShouldBreak(stmt);
if ( break_code == 2 ) // ### 2?
if ( break_code == 2 ) // ### 2?
{
i->second->SetEnable(false);
delete i->second;
@ -960,14 +945,14 @@ ValPtr dbg_eval_expr(const char* expr)
// Push the current frame's associated scope.
// Note: g_debugger_state.curr_frame_idx is the user-visible number,
// while the array index goes in the opposite direction
int frame_idx =
(g_frame_stack.size() - 1) - g_debugger_state.curr_frame_idx;
int frame_idx = (g_frame_stack.size() - 1) - g_debugger_state.curr_frame_idx;
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()");
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()");
Frame* frame = g_frame_stack[frame_idx];
if ( ! (frame) )
if ( ! (frame) )
reporter->InternalError("Assertion failed: frame");
const ScriptFunc* func = frame->GetFunction();
@ -1009,11 +994,11 @@ ValPtr dbg_eval_expr(const char* expr)
delete g_curr_debug_expr;
g_curr_debug_expr = nullptr;
delete [] g_curr_debug_error;
delete[] g_curr_debug_error;
g_curr_debug_error = nullptr;
in_debug = false;
return result;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -2,16 +2,17 @@
#pragma once
#include <vector>
#include <deque>
#include <map>
#include <string>
#include <deque>
#include <vector>
#include "zeek/Obj.h"
#include "zeek/StmtEnums.h"
#include "zeek/util.h"
namespace zeek {
namespace zeek
{
class Val;
template <class T> class IntrusivePtr;
@ -19,7 +20,8 @@ using ValPtr = zeek::IntrusivePtr<Val>;
extern std::string current_module;
namespace detail {
namespace detail
{
class Frame;
class Stmt;
@ -28,14 +30,20 @@ class DbgWatch;
class DbgDisplay;
// This needs to be defined before we do the includes that come after it.
enum ParseLocationRecType { PLR_UNKNOWN, PLR_FILE_AND_LINE, PLR_FUNCTION };
class ParseLocationRec {
enum ParseLocationRecType
{
PLR_UNKNOWN,
PLR_FILE_AND_LINE,
PLR_FUNCTION
};
class ParseLocationRec
{
public:
ParseLocationRecType type;
int32_t line;
Stmt* stmt;
const char* filename;
};
};
class StmtLocMapping;
using Filemap = std::deque<StmtLocMapping*>; // mapping for a single file
@ -43,34 +51,41 @@ using Filemap = std::deque<StmtLocMapping*>; // mapping for a single file
using BPIDMapType = std::map<int, DbgBreakpoint*>;
using BPMapType = std::multimap<const Stmt*, DbgBreakpoint*>;
class TraceState {
class TraceState
{
public:
TraceState() { dbgtrace = false; trace_file = stderr; }
TraceState()
{
dbgtrace = false;
trace_file = stderr;
}
// Returns previous filename.
FILE* SetTraceFile(const char* trace_filename);
bool DoTrace() const { return dbgtrace; }
bool DoTrace() const { return dbgtrace; }
void TraceOn();
void TraceOff();
int LogTrace(const char* fmt, ...) __attribute__((format(printf, 2, 3)));;
int LogTrace(const char* fmt, ...) __attribute__((format(printf, 2, 3)));
;
protected:
bool dbgtrace; // print an execution trace
bool dbgtrace; // print an execution trace
FILE* trace_file;
};
};
extern TraceState g_trace_state;
class DebuggerState {
class DebuggerState
{
public:
DebuggerState();
~DebuggerState();
int NextBPID() { return next_bp_id++; }
int NextWatchID() { return next_watch_id++; }
int NextDisplayID() { return next_display_id++; }
int NextBPID() { return next_bp_id++; }
int NextWatchID() { return next_watch_id++; }
int NextDisplayID() { return next_display_id++; }
bool BreakBeforeNextStmt() { return break_before_next_stmt; }
void BreakBeforeNextStmt(bool dobrk) { break_before_next_stmt = dobrk; }
@ -78,7 +93,6 @@ public:
bool BreakFromSignal() { return break_from_signal; }
void BreakFromSignal(bool dobrk) { break_from_signal = dobrk; }
// Temporary state: vanishes when execution resumes.
//### Umesh, why do these all need to be public? -- Vern
@ -86,42 +100,47 @@ public:
// Which frame we're looking at; 0 = the innermost frame.
int curr_frame_idx;
bool already_did_list; // did we already do a 'list' command?
bool already_did_list; // did we already do a 'list' command?
Location last_loc; // used by 'list'; the last location listed
Location last_loc; // used by 'list'; the last location listed
BPIDMapType breakpoints; // BPID -> Breakpoint
BPIDMapType breakpoints; // BPID -> Breakpoint
std::vector<DbgWatch*> watches;
std::vector<DbgDisplay*> displays;
BPMapType breakpoint_map; // maps Stmt -> Breakpoints on it
BPMapType breakpoint_map; // maps Stmt -> Breakpoints on it
protected:
bool break_before_next_stmt; // trap into debugger (used for "step")
bool break_from_signal; // was break caused by a signal?
bool break_before_next_stmt; // trap into debugger (used for "step")
bool break_from_signal; // was break caused by a signal?
int next_bp_id, next_watch_id, next_display_id;
private:
Frame* dbg_locals; // unused
};
};
// Source line -> statement mapping.
// (obj -> source line mapping available in object itself)
class StmtLocMapping {
class StmtLocMapping
{
public:
StmtLocMapping() { }
StmtLocMapping(const Location* l, Stmt* s) { loc = *l; stmt = s; }
StmtLocMapping() { }
StmtLocMapping(const Location* l, Stmt* s)
{
loc = *l;
stmt = s;
}
bool StartsAfter(const StmtLocMapping* m2);
const Location& Loc() const { return loc; }
Stmt* Statement() const { return stmt; }
const Location& Loc() const { return loc; }
Stmt* Statement() const { return stmt; }
protected:
Location loc;
Stmt* stmt;
};
};
extern bool g_policy_debug; // enable debugging facility
extern bool g_policy_debug; // enable debugging facility
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
// Debugging hooks.
// Return true to continue execution, false to abort.
@ -158,7 +176,7 @@ int dbg_init_debugger(const char* cmdfile = nullptr);
int dbg_shutdown_debugger();
// Returns 1 if successful, 0 otherwise.
int dbg_handle_debug_input(); // read a line and then have it executed
int dbg_handle_debug_input(); // read a line and then have it executed
// Returns > 0 if execution should be resumed, 0 if another debug command
// should be read, or < 0 if there was an error.
@ -170,12 +188,12 @@ ValPtr dbg_eval_expr(const char* expr);
// Get line that looks like "In FnFoo(arg = val) at File:Line".
std::string get_context_description(const Stmt* stmt, const Frame* frame);
extern Frame* g_dbg_locals; // variables created within debugger context
extern Frame* g_dbg_locals; // variables created within debugger context
extern std::map<std::string, Filemap*> g_dbgfilemaps; // filename => filemap
// 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 zeek
} // namespace detail
} // namespace zeek

View file

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

View file

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

View file

@ -11,29 +11,17 @@
zeek::detail::DebugLogger 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.
DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = {
{ "serial", 0, false },
{ "rules", 0, false },
{ "string", 0, false },
{ "notifiers", 0, false },
{ "main-loop", 0, false },
{ "dpd", 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 }
};
{"serial", 0, false}, {"rules", 0, false}, {"string", 0, false},
{"notifiers", 0, false}, {"main-loop", 0, false}, {"dpd", 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()
{
@ -81,10 +69,11 @@ void DebugLogger::ShowStreamsHelp()
fprintf(stderr, "Available streams:\n");
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, " 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, "Pseudo streams\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);
next:
next:
tok = strtok(0, ",");
}
delete [] tmp;
delete[] tmp;
}
void DebugLogger::Log(DebugStream stream, const char* fmt, ...)
@ -160,8 +149,8 @@ void DebugLogger::Log(DebugStream stream, const char* fmt, ...)
if ( ! g->enabled )
return;
fprintf(file, "%17.06f/%17.06f [%s] ",
run_state::network_time, util::current_time(true), g->prefix);
fprintf(file, "%17.06f/%17.06f [%s] ", run_state::network_time, util::current_time(true),
g->prefix);
for ( int i = g->indent; i > 0; --i )
fputs(" ", file);
@ -183,8 +172,8 @@ void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...)
if ( enabled_streams.find(tok) == enabled_streams.end() )
return;
fprintf(file, "%17.06f/%17.06f [plugin %s] ",
run_state::network_time, util::current_time(true), plugin.Name().c_str());
fprintf(file, "%17.06f/%17.06f [plugin %s] ", run_state::network_time, util::current_time(true),
plugin.Name().c_str());
va_list ap;
va_start(ap, fmt);
@ -195,6 +184,6 @@ void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...)
fflush(file);
}
} // namespace zeek::detail
} // namespace zeek::detail
#endif

View file

@ -5,56 +5,64 @@
#ifdef DEBUG
#include <stdio.h>
#include <set>
#include <string>
#include "zeek/zeek-config.h"
#include <stdio.h>
#include <string>
#include <set>
#define DBG_LOG(stream, args...) \
if ( ::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args)
#define DBG_LOG_VERBOSE(stream, args...) \
if ( ::zeek::detail::debug_logger.IsVerbose() && ::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args)
#define DBG_LOG(stream, args...) \
if ( ::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args)
#define DBG_LOG_VERBOSE(stream, args...) \
if ( ::zeek::detail::debug_logger.IsVerbose() && \
::zeek::detail::debug_logger.IsEnabled(stream) ) \
::zeek::detail::debug_logger.Log(stream, args)
#define DBG_PUSH(stream) ::zeek::detail::debug_logger.PushIndent(stream)
#define DBG_POP(stream) ::zeek::detail::debug_logger.PopIndent(stream)
#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
// an entry to DebugLogger::streams in DebugLogger.cc.
enum DebugStream {
DBG_SERIAL, // Serialization
DBG_RULES, // Signature matching
DBG_STRING, // String code
DBG_NOTIFIERS, // Notifiers
DBG_MAINLOOP, // Main IOSource loop
DBG_ANALYZER, // Analyzer framework
DBG_PACKET_ANALYSIS, // Packet analysis
DBG_FILE_ANALYSIS, // File analysis
DBG_TM, // Time-machine packet input via Brocolli
DBG_LOGGING, // Logging streams
DBG_INPUT, // Input streams
DBG_THREADING, // Threading system
DBG_PLUGINS, // Plugin system
DBG_ZEEKYGEN, // Zeekygen
DBG_PKTIO, // Packet sources and dumpers.
DBG_BROKER, // Broker communication
DBG_SCRIPTS, // Script initialization
DBG_SUPERVISOR, // Process supervisor
enum DebugStream
{
DBG_SERIAL, // Serialization
DBG_RULES, // Signature matching
DBG_STRING, // String code
DBG_NOTIFIERS, // Notifiers
DBG_MAINLOOP, // Main IOSource loop
DBG_ANALYZER, // Analyzer framework
DBG_PACKET_ANALYSIS, // Packet analysis
DBG_FILE_ANALYSIS, // File analysis
DBG_TM, // Time-machine packet input via Brocolli
DBG_LOGGING, // Logging streams
DBG_INPUT, // Input streams
DBG_THREADING, // Threading system
DBG_PLUGINS, // Plugin system
DBG_ZEEKYGEN, // Zeekygen
DBG_PKTIO, // Packet sources and dumpers.
DBG_BROKER, // Broker communication
DBG_SCRIPTS, // Script initialization
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:
// Output goes to stderr per default.
DebugLogger();
@ -63,26 +71,22 @@ public:
void OpenDebugLog(const char* filename = 0);
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)
{ ++streams[int(stream)].indent; }
void PopIndent(DebugStream stream)
{ --streams[int(stream)].indent; }
void PushIndent(DebugStream stream) { ++streams[int(stream)].indent; }
void PopIndent(DebugStream stream) { --streams[int(stream)].indent; }
void EnableStream(DebugStream stream)
{ streams[int(stream)].enabled = true; }
void DisableStream(DebugStream stream)
{ streams[int(stream)].enabled = false; }
void EnableStream(DebugStream stream) { streams[int(stream)].enabled = true; }
void DisableStream(DebugStream stream) { streams[int(stream)].enabled = false; }
// Takes comma-seperated list of stream prefixes.
void EnableStreams(const char* streams);
bool IsEnabled(DebugStream stream) const
{ return streams[int(stream)].enabled; }
bool IsEnabled(DebugStream stream) const { return streams[int(stream)].enabled; }
void SetVerbose(bool arg_verbose) { verbose = arg_verbose; }
bool IsVerbose() const { return verbose; }
void SetVerbose(bool arg_verbose) { verbose = arg_verbose; }
bool IsVerbose() const { return verbose; }
void ShowStreamsHelp();
@ -90,21 +94,22 @@ private:
FILE* file;
bool verbose;
struct Stream {
struct Stream
{
const char* prefix;
int indent;
bool enabled;
};
};
std::set<std::string> enabled_streams;
static Stream streams[NUM_DBGS];
};
};
extern DebugLogger debug_logger;
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek
#else
#define DBG_LOG(args...)

View file

@ -1,22 +1,23 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Desc.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "zeek/File.h"
#include "zeek/Reporter.h"
#include "zeek/ConvertUTF.h"
#include "zeek/File.h"
#include "zeek/IPAddr.h"
#include "zeek/Reporter.h"
#include "zeek/zeek-config.h"
#define DEFAULT_SIZE 128
#define SLOP 10
namespace zeek {
namespace zeek
{
ODesc::ODesc(DescType t, File* arg_f)
{
@ -28,7 +29,7 @@ ODesc::ODesc(DescType t, File* arg_f)
{
size = DEFAULT_SIZE;
base = util::safe_malloc(size);
((char*) base)[0] = '\0';
((char*)base)[0] = '\0';
offset = 0;
}
else
@ -64,7 +65,7 @@ void ODesc::EnableEscaping()
escape = true;
}
void ODesc::EnableUTF8 ()
void ODesc::EnableUTF8()
{
utf8 = true;
}
@ -93,12 +94,11 @@ void ODesc::Add(const char* s, int do_indent)
{
unsigned int n = strlen(s);
if ( do_indent && IsReadable() && offset > 0 &&
((const char*) base)[offset - 1] == '\n' )
if ( do_indent && IsReadable() && offset > 0 && ((const char*)base)[offset - 1] == '\n' )
Indent();
if ( IsBinary() )
AddBytes(s, n+1);
AddBytes(s, n + 1);
else
AddBytes(s, n);
}
@ -169,13 +169,12 @@ void ODesc::Add(double d, bool no_exp)
Add(tmp);
auto approx_equal = [](double a, double b, double tolerance = 1e-6) -> bool
{
{
auto v = a - b;
return v < 0 ? -v < tolerance : v < tolerance;
};
};
if ( approx_equal(d, nearbyint(d), 1e-9) &&
isfinite(d) && ! strchr(tmp, 'e') )
if ( approx_equal(d, nearbyint(d), 1e-9) && isfinite(d) && ! strchr(tmp, 'e') )
// disambiguate from integer
Add(".0");
}
@ -210,7 +209,7 @@ void ODesc::AddBytes(const String* s)
{
const char* str = s->Render(String::EXPANDED_STRING);
Add(str);
delete [] str;
delete[] str;
}
}
else
@ -294,17 +293,17 @@ std::pair<const char*, size_t> ODesc::FirstEscapeLoc(const char* bytes, size_t n
void ODesc::AddBytes(const void* bytes, unsigned int n)
{
if ( ! escape )
{
AddBytesRaw(bytes, n);
return;
}
{
AddBytesRaw(bytes, n);
return;
}
const char* s = (const char*) bytes;
const char* e = (const char*) bytes + n;
const char* s = (const char*)bytes;
const char* e = (const char*)bytes + n;
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 )
{
@ -343,7 +342,7 @@ void ODesc::AddBytesRaw(const void* bytes, unsigned int n)
{
static bool write_failed = false;
if ( ! f->Write((const char*) bytes, n) )
if ( ! f->Write((const char*)bytes, n) )
{
if ( ! write_failed )
// 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
// simply using &base[offset] generates complaints about
// using a void* for pointer arithemtic.
memcpy((void*) &((char*) base)[offset], bytes, n);
memcpy((void*)&((char*)base)[offset], bytes, 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);
size = DEFAULT_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;
}
std::string obj_desc(const Obj* o)
{
static ODesc d;
@ -428,4 +426,4 @@ std::string obj_desc(const Obj* o)
return std::string(d.Description());
}
} // namespace zeek
} // namespace zeek

View file

@ -3,95 +3,97 @@
#pragma once
#include <sys/types.h> // for u_char
#include <set>
#include <utility>
#include <string>
#include <utility>
#include "zeek/ZeekString.h" // for byte_vec
#include "zeek/util.h" // for bro_int_t
namespace zeek {
namespace zeek
{
class IPAddr;
class IPPrefix;
class File;
class Type;
enum DescType {
enum DescType
{
DESC_READABLE,
DESC_PORTABLE,
DESC_BINARY,
};
};
enum DescStyle {
enum DescStyle
{
STANDARD_STYLE,
RAW_STYLE,
};
};
class ODesc {
class ODesc
{
public:
explicit ODesc(DescType t=DESC_READABLE, File* f=nullptr);
explicit ODesc(DescType t = DESC_READABLE, File* f = nullptr);
~ODesc();
bool IsReadable() const { return type == DESC_READABLE; }
bool IsPortable() const { return type == DESC_PORTABLE; }
bool IsBinary() const { return type == DESC_BINARY; }
bool IsReadable() const { return type == DESC_READABLE; }
bool IsPortable() const { return type == DESC_PORTABLE; }
bool IsBinary() const { return type == DESC_BINARY; }
bool IsShort() const { return is_short; }
void SetShort() { is_short = true; }
void SetShort(bool s) { is_short = s; }
bool IsShort() const { return is_short; }
void SetShort() { is_short = true; }
void SetShort(bool s) { is_short = s; }
// Whether we want to have quotes around strings.
bool WantQuotes() const { return want_quotes; }
void SetQuotes(bool q) { want_quotes = q; }
bool WantQuotes() const { return want_quotes; }
void SetQuotes(bool q) { want_quotes = q; }
// Whether to ensure deterministic output (for example, when
// describing TableVal's).
bool WantDeterminism() const { return want_determinism; }
void SetDeterminism(bool d) { want_determinism = d; }
bool WantDeterminism() const { return want_determinism; }
void SetDeterminism(bool d) { want_determinism = d; }
// Whether we want to print statistics like access time and execution
// count where available.
bool IncludeStats() const { return include_stats; }
void SetIncludeStats(bool s) { include_stats = s; }
bool IncludeStats() const { return include_stats; }
void SetIncludeStats(bool s) { include_stats = s; }
DescStyle Style() const { return style; }
void SetStyle(DescStyle s) { style = s; }
DescStyle Style() const { return style; }
void SetStyle(DescStyle s) { style = s; }
void SetFlush(bool arg_do_flush) { do_flush = arg_do_flush; }
void SetFlush(bool arg_do_flush) { do_flush = arg_do_flush; }
void EnableEscaping();
void EnableUTF8();
void AddEscapeSequence(const char* s) { escape_sequences.insert(s); }
void AddEscapeSequence(const char* s, size_t n)
{ escape_sequences.insert(std::string(s, n)); }
void AddEscapeSequence(const std::string & s)
{ escape_sequences.insert(s); }
void AddEscapeSequence(const char* s, size_t n) { escape_sequences.insert(std::string(s, n)); }
void AddEscapeSequence(const std::string& s) { escape_sequences.insert(s); }
void RemoveEscapeSequence(const char* s) { escape_sequences.erase(s); }
void RemoveEscapeSequence(const char* s, size_t n)
{ escape_sequences.erase(std::string(s, n)); }
void RemoveEscapeSequence(const std::string & s)
{ escape_sequences.erase(s); }
{
escape_sequences.erase(std::string(s, n));
}
void RemoveEscapeSequence(const std::string& s) { escape_sequences.erase(s); }
void PushIndent();
void PopIndent();
void PopIndentNoNL();
int GetIndentLevel() const { return indent_level; }
int GetIndentLevel() const { return indent_level; }
void ClearIndentLevel() { indent_level = 0; }
int IndentSpaces() const { return indent_with_spaces; }
void SetIndentSpaces(int i) { indent_with_spaces = i; }
int IndentSpaces() const { return indent_with_spaces; }
void SetIndentSpaces(int i) { indent_with_spaces = i; }
void Add(const char* s, int do_indent=1);
void AddN(const char* s, int len) { AddBytes(s, len); }
void Add(const std::string& s) { AddBytes(s.data(), s.size()); }
void Add(const char* s, int do_indent = 1);
void AddN(const char* s, int len) { AddBytes(s, len); }
void Add(const std::string& s) { AddBytes(s.data(), s.size()); }
void Add(int i);
void Add(uint32_t u);
void Add(int64_t i);
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 IPPrefix& prefix);
@ -101,13 +103,22 @@ public:
void AddBytes(const String* s);
void Add(const char* s1, const char* s2)
{ Add(s1); Add(s2); }
{
Add(s1);
Add(s2);
}
void AddSP(const char* s1, const char* s2)
{ Add(s1); AddSP(s2); }
{
Add(s1);
AddSP(s2);
}
void AddSP(const char* s )
{ Add(s); SP(); }
void AddSP(const char* s)
{
Add(s);
SP();
}
void AddCount(bro_int_t n)
{
@ -118,23 +129,25 @@ public:
}
}
void SP() {
if ( ! IsBinary() )
Add(" ", 0);
}
void NL() {
if ( ! IsBinary() && ! is_short )
Add("\n", 0);
}
void SP()
{
if ( ! IsBinary() )
Add(" ", 0);
}
void NL()
{
if ( ! IsBinary() && ! is_short )
Add("\n", 0);
}
// Bypasses the escaping enabled via EnableEscaping().
void AddRaw(const char* s, int len) { AddBytesRaw(s, len); }
void AddRaw(const std::string &s) { AddBytesRaw(s.data(), s.size()); }
void AddRaw(const char* s, int len) { AddBytesRaw(s, len); }
void AddRaw(const std::string& s) { AddBytesRaw(s.data(), s.size()); }
// 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()
{
const void* t = base;
@ -147,7 +160,7 @@ public:
return byte_vec(t);
}
int Len() const { return offset; }
int Len() const { return offset; }
void Clear();
@ -191,12 +204,12 @@ protected:
DescType type;
DescStyle style;
void* base; // beginning of buffer
unsigned int offset; // where we are in the buffer
unsigned int size; // size of buffer in bytes
void* base; // beginning of buffer
unsigned int offset; // where we are in the buffer
unsigned int size; // size of buffer in bytes
bool utf8; // whether valid utf-8 sequences may pass through unescaped
bool escape; // escape unprintable characters in output?
bool escape; // escape unprintable characters in output?
bool is_short;
bool want_quotes;
bool want_determinism;
@ -209,10 +222,10 @@ protected:
using escape_set = std::set<std::string>;
escape_set escape_sequences; // additional sequences of chars to escape
File* f; // or the file we're using.
File* f; // or the file we're using.
std::set<const Type*> encountered_types;
};
};
// Returns a string representation of an object's description. Used for
// debugging and error messages. takes a bare pointer rather than an
@ -221,4 +234,4 @@ protected:
class Obj;
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
#include <cstdint>
#include <vector>
#include <memory>
#include <vector>
#include "zeek/Hash.h"
// Type for function to be called when deleting elements.
typedef void (*dict_delete_func)(void*);
namespace zeek {
namespace zeek
{
class IterCookie;
class Dictionary;
enum DictOrder { ORDERED, UNORDERED };
enum DictOrder
{
ORDERED,
UNORDERED
};
// A dict_delete_func that just calls delete.
extern void generic_delete_func(void*);
namespace detail {
namespace detail
{
class DictEntry;
// Default number of hash buckets in dictionary. The dictionary will increase the size
// 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
// or for debugging purposes.
@ -54,9 +60,9 @@ constexpr uint16_t TOO_FAR_TO_REACH = 0xFFFF;
/**
* An entry stored in the dictionary.
*/
class DictEntry {
class DictEntry
{
public:
#ifdef DEBUG
int bucket = 0;
#endif
@ -72,10 +78,10 @@ public:
uint32_t hash = 0;
void* value = nullptr;
union {
char key_here[8]; //hold key len<=8. when over 8, it's a pointer to real keys.
union {
char key_here[8]; // hold key len<=8. when over 8, it's a pointer to real keys.
char* key;
};
};
DictEntry(void* arg_key, int key_size = 0, hash_t hash = 0, void* value = nullptr,
int16_t d = TOO_FAR_TO_REACH, bool copy_key = false)
@ -88,7 +94,7 @@ public:
{
memcpy(key_here, arg_key, key_size);
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
{
@ -104,7 +110,7 @@ public:
}
}
bool Empty() const { return distance == TOO_FAR_TO_REACH; }
bool Empty() const { return distance == TOO_FAR_TO_REACH; }
void SetEmpty()
{
distance = TOO_FAR_TO_REACH;
@ -115,13 +121,13 @@ public:
value = nullptr;
key_size = 0;
bucket = 0;
#endif//DEBUG
#endif // DEBUG
}
void Clear()
{
if( key_size > 8 )
delete [] key;
if ( key_size > 8 )
delete[] key;
SetEmpty();
}
@ -131,27 +137,21 @@ public:
return std::make_unique<detail::HashKey>(GetKey(), key_size, hash);
}
template <typename T>
T GetValue() const { return static_cast<T>(value); }
template <typename T> T GetValue() const { return static_cast<T>(value); }
bool Equal(const char* arg_key, int arg_key_size, hash_t arg_hash) const
{//only 40-bit hash comparison.
return ( 0 == ((hash ^ arg_hash) & HASH_MASK) )
&& key_size == arg_key_size && 0 == memcmp(GetKey(), arg_key, key_size);
{ // only 40-bit hash comparison.
return (0 == ((hash ^ arg_hash) & HASH_MASK)) && key_size == arg_key_size &&
0 == memcmp(GetKey(), arg_key, key_size);
}
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);
}
};
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); }
};
} // namespace detail
} // namespace detail
class DictIterator {
class DictIterator
{
public:
using value_type = detail::DictEntry;
using reference = detail::DictEntry&;
@ -171,13 +171,17 @@ public:
pointer operator->() { return curr; }
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 !(*this == that); }
bool operator==(const DictIterator& that) const { return curr == that.curr; }
bool operator!=(const DictIterator& that) const { return ! (*this == that); }
private:
friend class Dictionary;
DictIterator(const Dictionary* d, detail::DictEntry* begin, detail::DictEntry* end);
@ -185,9 +189,10 @@ private:
Dictionary* dict = nullptr;
detail::DictEntry* curr = nullptr;
detail::DictEntry* end = nullptr;
};
};
class RobustDictIterator {
class RobustDictIterator
{
public:
using value_type = detail::DictEntry;
using reference = detail::DictEntry&;
@ -195,20 +200,25 @@ public:
using difference_type = std::ptrdiff_t;
using iterator_category = std::forward_iterator_tag;
RobustDictIterator() : curr(nullptr) {}
RobustDictIterator() : curr(nullptr) { }
RobustDictIterator(Dictionary* d);
RobustDictIterator(const RobustDictIterator& other);
RobustDictIterator(RobustDictIterator&& other);
~RobustDictIterator();
~RobustDictIterator();
reference operator*() { return curr; }
pointer operator->() { return &curr; }
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 !(*this == that); }
bool operator==(const RobustDictIterator& that) const { return curr == that.curr; }
bool operator!=(const RobustDictIterator& that) const { return ! (*this == that); }
private:
friend class Dictionary;
@ -225,7 +235,7 @@ private:
detail::DictEntry curr;
Dictionary* dict = nullptr;
int next = -1;
};
};
/**
* 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
* entries is the absolute limit. Only Connections use that many entries, and that is rare.
*/
class Dictionary {
class Dictionary
{
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();
// Member functions for looking up a key, inserting/changing its
// contents, and deleting it. These come in two flavors: one
// which takes a zeek::detail::HashKey, and the other which takes a raw key,
// 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 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 the removal may have invalidated any existing iterators.
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
// that it's a heap pointer that now belongs to the Dictionary to
// manage as needed.
// If iterators_invalidated is supplied, its value is set to true
// 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
// case it needs to be deleted. Returns 0 if no such element exists.
@ -271,23 +286,23 @@ public:
// If iterators_invalidated is supplied, its value is set to true
// if the removal may have invalidated any existing iterators.
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.
int Length() const
{ return num_entries; }
int Length() const { return num_entries; }
// Largest it's ever been.
int MaxLength() const
{ return max_entries; }
int MaxLength() const { return max_entries; }
// Total number of entries ever.
uint64_t NumCumulativeInserts() const
{ return cum_entries; }
uint64_t NumCumulativeInserts() const { return cum_entries; }
// True if the dictionary is ordered, false otherwise.
int IsOrdered() const { return order != nullptr; }
int IsOrdered() const { return order != nullptr; }
// If the dictionary is ordered then returns the n'th entry's value;
// the second method also returns the key. The first entry inserted
@ -316,14 +331,17 @@ public:
//
// If return_hash is true, a HashKey for the entry is returned in h,
// which should be delete'd when no longer needed.
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]]
IterCookie* InitForIteration() const;
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]]
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 iteration.")]]
void StopIteration(IterCookie* cookie) const;
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
"iteration.")]] IterCookie*
InitForIteration() const;
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
"iteration.")]] 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 "
"iteration.")]] void
StopIteration(IterCookie* cookie) const;
void SetDeleteFunc(dict_delete_func f) { delete_func = f; }
void SetDeleteFunc(dict_delete_func f) { delete_func = f; }
// With a robust cookie, it is safe to change the dictionary while
// iterating. This means that (i) we will eventually visit all
@ -331,23 +349,25 @@ public:
// 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
// necessary.)
[[deprecated("Remove in v5.1. Use begin_robust() and the standard-library-compatible version of iteration.")]]
void MakeRobustCookie(IterCookie* cookie);
[[deprecated("Remove in v5.1. Use begin_robust() and the standard-library-compatible version "
"of iteration.")]] void
MakeRobustCookie(IterCookie* cookie);
// Remove all entries.
void Clear();
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
size_t MemoryAllocation() const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] size_t
MemoryAllocation() const;
/// The capacity of the table, Buckets + Overflow Size.
int Capacity(bool expected = false) const;
//Debugging
// Debugging
#ifdef DEBUG
void AssertValid() const;
#endif//DEBUG
void Dump(int level=0) const;
#endif // DEBUG
void Dump(int level = 0) const;
void DistanceStats(int& max_distance, int* distances = 0, int num_distances = 0) const;
void DumpKeys() const;
@ -362,12 +382,12 @@ public:
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
iterator begin() { return { this, table, table + Capacity() }; }
iterator end() { return { this, table + Capacity(), table + Capacity() }; }
const_iterator begin() const { return { this, table, table + Capacity() }; }
const_iterator end() const { return { this, table + Capacity(), table + Capacity() }; }
const_iterator cbegin() { return { this, table, table + Capacity() }; }
const_iterator cend() { return { this, table + Capacity(), table + Capacity() }; }
iterator begin() { return {this, table, table + Capacity()}; }
iterator end() { return {this, table + Capacity(), table + Capacity()}; }
const_iterator begin() const { return {this, table, table + Capacity()}; }
const_iterator end() const { return {this, table + Capacity(), table + Capacity()}; }
const_iterator cbegin() { return {this, table, table + Capacity()}; }
const_iterator cend() { return {this, table + Capacity(), table + Capacity()}; }
RobustDictIterator begin_robust() { return MakeRobustIterator(); }
RobustDictIterator end_robust() { return RobustDictIterator(); }
@ -380,7 +400,7 @@ private:
/// Buckets of the table, not including overflow size.
int Buckets(bool expected = false) const;
//bucket math
// bucket math
int Log2(int num) const;
int ThresholdEntries() const;
@ -419,47 +439,55 @@ private:
void Init();
// Iteration
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]]
IterCookie* InitForIterationNonConst();
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of iteration.")]]
void* 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);
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
"iteration.")]] IterCookie*
InitForIterationNonConst();
[[deprecated("Remove in v5.1. Use begin() and the standard-library-compatible version of "
"iteration.")]] void*
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 LookupIndex(const void* key, int key_size, detail::hash_t hash, int* insert_position = nullptr,
int* insert_distance = nullptr);
int LookupIndex(const void* key, int key_size, detail::hash_t hash,
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* insert_position = nullptr, int* insert_distance = nullptr);
int* insert_position = nullptr, int* insert_distance = nullptr);
/// Insert entry, Adjust cookies when necessary.
void InsertRelocateAndAdjust(detail::DictEntry& entry, int insert_position);
/// 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.
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration and the version that takes a RobustDictIterator.")]]
void AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, int insert_position, int last_affected_position);
void AdjustOnInsert(RobustDictIterator* c, const detail::DictEntry& entry,
int insert_position, int last_affected_position);
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration and the "
"version that takes a RobustDictIterator.")]] void
AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, int insert_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);
///Remove & Relocate
/// Remove & Relocate
detail::DictEntry RemoveAndRelocate(int position, int* last_affected_position = nullptr);
///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.")]]
void AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, int position, int last_affected_position);
void AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& entry,
int position, int last_affected_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.")]] void
AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, int 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();
// Remap an item in position to a new position. Returns true if the relocation was
@ -471,16 +499,18 @@ private:
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();
detail::DictEntry GetNextRobustIteration(RobustDictIterator* iter);
void IncrIters() { ++num_iterators; }
void DecrIters() { --num_iterators; }
void IncrIters() { ++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
// 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.
std::vector<detail::DictEntry>* order = nullptr;
};
};
/*
* Template specialization of Dictionary that stores pointers for values.
*/
template<typename T>
class PDict : public Dictionary {
template <typename T> class PDict : public Dictionary
{
public:
explicit PDict(DictOrder ordering = UNORDERED, int initial_size = 0) :
Dictionary(ordering, initial_size) {}
explicit PDict(DictOrder ordering = UNORDERED, int initial_size = 0)
: Dictionary(ordering, initial_size)
{
}
T* Lookup(const char* key) const
{
detail::HashKey h(key);
return (T*) Dictionary::Lookup(&h);
return (T*)Dictionary::Lookup(&h);
}
T* Lookup(const detail::HashKey* key) const
{ return (T*) Dictionary::Lookup(key); }
T* Lookup(const detail::HashKey* key) const { return (T*)Dictionary::Lookup(key); }
T* Insert(const char* key, T* val, bool* iterators_invalidated = nullptr)
{
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)
{ return (T*) Dictionary::Insert(key, (void*) val, iterators_invalidated); }
T* NthEntry(int n) const
{ return (T*) Dictionary::NthEntry(n); }
{
return (T*)Dictionary::Insert(key, (void*)val, iterators_invalidated);
}
T* NthEntry(int n) const { return (T*)Dictionary::NthEntry(n); }
T* NthEntry(int n, const char*& key) const
{
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.")]]
T* NextEntry(IterCookie*& cookie) const
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] T*
NextEntry(IterCookie*& cookie) const
{
detail::HashKey* h;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return (T*) Dictionary::NextEntry(h, cookie, false);
return (T*)Dictionary::NextEntry(h, cookie, false);
#pragma GCC diagnostic pop
}
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]]
T* NextEntry(detail::HashKey*& h, IterCookie*& cookie) const
[[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] T*
NextEntry(detail::HashKey*& h, IterCookie*& cookie) const
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return (T*) Dictionary::NextEntry(h, cookie, true);
return (T*)Dictionary::NextEntry(h, cookie, true);
#pragma GCC diagnostic pop
}
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)
{ 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.
#include "zeek/zeek-config.h"
#include "zeek/Discard.h"
#include <algorithm>
#include "zeek/ZeekString.h"
#include "zeek/RunState.h"
#include "zeek/Func.h"
#include "zeek/Var.h"
#include "zeek/Val.h"
#include "zeek/IP.h"
#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()
{
@ -26,9 +26,7 @@ Discarder::Discarder()
discarder_maxlen = static_cast<int>(id::find_val("discarder_maxlen")->AsCount());
}
Discarder::~Discarder()
{
}
Discarder::~Discarder() { }
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();
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP &&
proto != IPPROTO_ICMP )
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && proto != IPPROTO_ICMP )
// This is not a protocol we understand.
return false;
@ -69,14 +66,13 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
return false;
int ip_hdr_len = ip->HdrLen();
len -= ip_hdr_len; // remove IP header
len -= ip_hdr_len; // remove IP header
caplen -= ip_hdr_len;
bool is_tcp = (proto == IPPROTO_TCP);
bool is_udp = (proto == IPPROTO_UDP);
int min_hdr_len = is_tcp ?
sizeof(struct tcphdr) :
(is_udp ? sizeof(struct udphdr) : sizeof(struct icmp));
int min_hdr_len =
is_tcp ? sizeof(struct tcphdr) : (is_udp ? sizeof(struct udphdr) : sizeof(struct icmp));
if ( len < min_hdr_len || caplen < min_hdr_len )
// 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 )
{
const struct tcphdr* tp = (const struct tcphdr*) data;
const struct tcphdr* tp = (const struct tcphdr*)data;
int th_len = tp->th_off * 4;
zeek::Args args{
@ -114,8 +110,8 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
{
if ( check_udp )
{
const struct udphdr* up = (const struct udphdr*) data;
int uh_len = sizeof (struct udphdr);
const struct udphdr* up = (const struct udphdr*)data;
int uh_len = sizeof(struct udphdr);
zeek::Args args{
ip->ToPktHdrVal(),
@ -138,7 +134,7 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
{
if ( check_icmp )
{
const struct icmp* ih = (const struct icmp*) data;
const struct icmp* ih = (const struct icmp*)data;
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));
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

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

View file

@ -1,12 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/EquivClass.h"
#include "zeek/CCL.h"
#include "zeek/util.h"
#include "zeek/zeek-config.h"
namespace zeek::detail {
namespace zeek::detail
{
EquivClass::EquivClass(int arg_size)
{
@ -38,11 +39,11 @@ EquivClass::EquivClass(int arg_size)
EquivClass::~EquivClass()
{
delete [] fwd;
delete [] bck;
delete [] equiv_class;
delete [] rep;
delete [] ccl_flags;
delete[] fwd;
delete[] bck;
delete[] equiv_class;
delete[] rep;
delete[] ccl_flags;
}
void EquivClass::ConvertCCL(CCL* ccl)
@ -163,7 +164,6 @@ void EquivClass::CCL_Use(CCL* ccl)
}
}
void EquivClass::UniqueChar(int sym)
{
// If until now the character has been a proper subset of
@ -183,7 +183,7 @@ void EquivClass::Dump(FILE* f)
{
fprintf(f, "%d symbols in EC yielded %d ecs\n", size, num_ecs);
for ( int i = 0; i < size; ++i )
if ( SymEquivClass(i) != 0 ) // skip usually huge default ec
if ( SymEquivClass(i) != 0 ) // skip usually huge default ec
fprintf(f, "map %d ('%c') -> %d\n", i, i, SymEquivClass(i));
}
@ -192,4 +192,4 @@ int EquivClass::Size() const
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>
namespace zeek::detail {
namespace zeek::detail
{
class CCL;
class EquivClass {
class EquivClass
{
public:
explicit EquivClass(int size);
~EquivClass();
@ -22,26 +24,26 @@ public:
void ConvertCCL(CCL* ccl);
bool IsRep(int sym) const { return rep[sym] == sym; }
int EquivRep(int sym) const { return rep[sym]; }
int SymEquivClass(int sym) const { return equiv_class[sym]; }
int* EquivClasses() const { return equiv_class; }
bool IsRep(int sym) const { return rep[sym] == sym; }
int EquivRep(int sym) const { return rep[sym]; }
int SymEquivClass(int sym) const { return equiv_class[sym]; }
int* EquivClasses() const { return equiv_class; }
int NumSyms() const { return size; }
int NumClasses() const { return num_ecs; }
int NumSyms() const { return size; }
int NumClasses() const { return num_ecs; }
void Dump(FILE* f);
int Size() const;
protected:
int size; // size of character set
int num_ecs; // size of equivalence classes
int* fwd; // forward list of different classes
int* bck; // backward list
int* equiv_class; // symbol's equivalence class
int* rep; // representative for symbol's equivalence class
int size; // size of character set
int num_ecs; // size of equivalence classes
int* fwd; // forward list of different classes
int* bck; // backward list
int* equiv_class; // symbol's equivalence class
int* rep; // representative for symbol's equivalence class
int* ccl_flags;
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.
#include "zeek/zeek-config.h"
#include "zeek/Event.h"
#include "zeek/Desc.h"
#include "zeek/Func.h"
#include "zeek/NetVar.h"
#include "zeek/RunState.h"
#include "zeek/Trigger.h"
#include "zeek/Val.h"
#include "zeek/plugin/Manager.h"
#include "zeek/iosource/Manager.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& mgr = zeek::event_mgr;
namespace zeek {
namespace zeek
{
Event::Event(EventHandlerPtr arg_handler, zeek::Args arg_args,
util::detail::SourceID arg_src, analyzer::ID arg_aid,
Obj* arg_obj)
: handler(arg_handler),
args(std::move(arg_args)),
src(arg_src),
aid(arg_aid),
obj(arg_obj),
Event::Event(EventHandlerPtr arg_handler, zeek::Args arg_args, util::detail::SourceID arg_src,
analyzer::ID 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)
{
if ( obj )
@ -94,8 +90,7 @@ EventMgr::~EventMgr()
Unref(src_val);
}
void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl,
util::detail::SourceID src,
void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl, util::detail::SourceID src,
analyzer::ID aid, Obj* 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");
}
} // namespace zeek
} // namespace zeek

View file

@ -5,30 +5,32 @@
#include <tuple>
#include <type_traits>
#include "zeek/Flare.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/ZeekArgs.h"
#include "zeek/ZeekList.h"
#include "zeek/analyzer/Analyzer.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 Event final : public Obj {
class Event final : public Obj
{
public:
Event(EventHandlerPtr handler, zeek::Args args,
util::detail::SourceID src = util::detail::SOURCE_LOCAL, analyzer::ID aid = 0,
Obj* obj = nullptr);
void SetNext(Event* n) { next_event = n; }
Event* NextEvent() const { return next_event; }
void SetNext(Event* n) { next_event = n; }
Event* NextEvent() const { return next_event; }
util::detail::SourceID Source() const { return src; }
analyzer::ID Analyzer() const { return aid; }
EventHandlerPtr Handler() const { return handler; }
const zeek::Args& Args() const { return args; }
util::detail::SourceID Source() const { return src; }
analyzer::ID Analyzer() const { return aid; }
EventHandlerPtr Handler() const { return handler; }
const zeek::Args& Args() const { return args; }
void Describe(ODesc* d) const override;
@ -45,9 +47,10 @@ protected:
analyzer::ID aid;
Obj* obj;
Event* next_event;
};
};
class EventMgr final : public Obj, public iosource::IOSource {
class EventMgr final : public Obj, public iosource::IOSource
{
public:
EventMgr();
~EventMgr() override;
@ -72,28 +75,27 @@ public:
* A version of Enqueue() taking a variable number of arguments.
*/
template <class... Args>
std::enable_if_t<
std::is_convertible_v<
std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>>
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>>
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 Drain();
bool IsDraining() const { return draining; }
bool IsDraining() const { return draining; }
bool HasEvents() const { return head != nullptr; }
bool HasEvents() const { return head != nullptr; }
// Returns the source ID of last raised event.
util::detail::SourceID CurrentSource() const { return current_src; }
util::detail::SourceID CurrentSource() const { return current_src; }
// Returns the ID of the analyzer which raised the last event, or 0 if
// non-analyzer event.
analyzer::ID CurrentAnalyzer() const { return current_aid; }
analyzer::ID CurrentAnalyzer() const { return current_aid; }
int Size() const
{ return num_events_queued - num_events_dispatched; }
int Size() const { return num_events_queued - num_events_dispatched; }
void Describe(ODesc* d) const override;
@ -115,8 +117,8 @@ protected:
RecordVal* src_val;
bool draining;
detail::Flare queue_flare;
};
};
extern EventMgr event_mgr;
} // namespace zeek
} // namespace zeek

View file

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

View file

@ -2,97 +2,98 @@
#pragma once
#include <unordered_set>
#include <string>
#include <unordered_set>
#include "zeek/ZeekList.h"
#include "zeek/ZeekArgs.h"
#include "zeek/Type.h"
#include "zeek/ZeekArgs.h"
#include "zeek/ZeekList.h"
namespace zeek {
namespace zeek
{
class Func;
using FuncPtr = IntrusivePtr<Func>;
class EventHandler {
class EventHandler
{
public:
explicit EventHandler(std::string name);
const char* Name() { return name.data(); }
const char* Name() { return name.data(); }
const FuncPtr& GetFunc()
{ return local; }
const FuncPtr& GetFunc() { return local; }
const FuncTypePtr& GetType(bool check_export = true);
void SetFunc(FuncPtr f);
void AutoPublish(std::string topic)
{
auto_publish.insert(std::move(topic));
}
void AutoPublish(std::string topic) { auto_publish.insert(std::move(topic)); }
void AutoUnpublish(const std::string& topic)
{
auto_publish.erase(topic);
}
void AutoUnpublish(const std::string& topic) { auto_publish.erase(topic); }
void Call(zeek::Args* vl, bool no_remote = false);
// Returns true if there is at least one local or remote handler.
explicit operator bool() const;
explicit operator bool() const;
void SetUsed() { used = true; }
bool Used() { return used; }
void SetUsed() { used = true; }
bool Used() { return used; }
// Handlers marked as error handlers will not be called recursively to
// avoid infinite loops if they trigger a similar error themselves.
void SetErrorHandler() { error_handler = true; }
bool ErrorHandler() { return error_handler; }
void SetErrorHandler() { error_handler = true; }
bool ErrorHandler() { return error_handler; }
void SetEnable(bool arg_enable) { enabled = arg_enable; }
void SetEnable(bool arg_enable) { enabled = arg_enable; }
// Flags the event as interesting even if there is no body defined. In
// particular, this will then still pass the event on to plugins.
void SetGenerateAlways() { generate_always = true; }
bool GenerateAlways() { return generate_always; }
void SetGenerateAlways() { generate_always = true; }
bool GenerateAlways() { return generate_always; }
private:
void NewEvent(zeek::Args* vl); // Raise new_event() meta event.
void NewEvent(zeek::Args* vl); // Raise new_event() meta event.
std::string name;
FuncPtr local;
FuncTypePtr type;
bool used; // this handler is indeed used somewhere
bool used; // this handler is indeed used somewhere
bool enabled;
bool error_handler; // this handler reports error messages.
bool error_handler; // this handler reports error messages.
bool generate_always;
std::unordered_set<std::string> auto_publish;
};
};
// Encapsulates a ptr to an event handler to overload the boolean operator.
class EventHandlerPtr {
class EventHandlerPtr
{
public:
EventHandlerPtr(EventHandler* p = nullptr) { handler = p; }
EventHandlerPtr(const EventHandlerPtr& h) { handler = h.handler; }
EventHandlerPtr(EventHandler* p = nullptr) { handler = p; }
EventHandlerPtr(const EventHandlerPtr& h) { handler = h.handler; }
const EventHandlerPtr& operator=(EventHandler* p)
{ handler = p; return *this; }
{
handler = p;
return *this;
}
const EventHandlerPtr& operator=(const EventHandlerPtr& h)
{ handler = h.handler; return *this; }
{
handler = h.handler;
return *this;
}
bool operator==(const EventHandlerPtr& h) const
{ return handler == h.handler; }
bool operator==(const EventHandlerPtr& h) const { return handler == h.handler; }
EventHandler* Ptr() { return handler; }
EventHandler* Ptr() { return handler; }
explicit operator bool() const { return handler && *handler; }
EventHandler* operator->() { return handler; }
const EventHandler* operator->() const { return handler; }
explicit operator bool() const { return handler && *handler; }
EventHandler* operator->() { return handler; }
const EventHandler* operator->() const { return handler; }
private:
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/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"

View file

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

View file

@ -2,22 +2,24 @@
#pragma once
#include "zeek/zeek-config.h"
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <vector>
namespace zeek {
#include "zeek/zeek-config.h"
namespace zeek
{
class EventHandler;
class EventHandlerPtr;
class RE_Matcher;
// The registry keeps track of all events that we provide or handle.
class EventRegistry {
class EventRegistry
{
public:
EventRegistry();
~EventRegistry() noexcept;
@ -53,8 +55,8 @@ public:
private:
std::map<std::string, std::unique_ptr<EventHandler>, std::less<>> handlers;
};
};
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.
#include "zeek/zeek-config.h"
#include "zeek/File.h"
#include <sys/types.h>
#include "zeek/zeek-config.h"
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#include <sys/time.h>
#include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
#include <errno.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <algorithm>
#include "zeek/Attr.h"
#include "zeek/Type.h"
#include "zeek/Desc.h"
#include "zeek/Event.h"
#include "zeek/Expr.h"
#include "zeek/NetVar.h"
#include "zeek/RunState.h"
#include "zeek/Event.h"
#include "zeek/Reporter.h"
#include "zeek/Desc.h"
#include "zeek/RunState.h"
#include "zeek/Type.h"
#include "zeek/Var.h"
namespace zeek {
namespace zeek
{
std::list<std::pair<std::string, File*>> File::open_files;
@ -159,8 +160,8 @@ File::~File()
Close();
Unref(attrs);
delete [] name;
delete [] access;
delete[] name;
delete[] access;
#ifdef USE_PERFTOOLS_DEBUG
heap_checker->UnIgnoreObject(this);
@ -231,7 +232,7 @@ bool File::Close()
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 )
{
@ -294,7 +295,7 @@ RecordVal* File::Rotate()
Unlink();
fclose(f);
fclose(f);
f = nullptr;
Open(newf);
@ -350,11 +351,11 @@ double File::Size()
FilePtr File::Get(const char* name)
{
for ( const auto &el : open_files )
for ( const auto& el : open_files )
if ( el.first == name )
return {NewRef{}, el.second};
return make_intrusive<File>(name, "w");
}
} // namespace zeek
} // namespace zeek

View file

@ -3,7 +3,6 @@
#pragma once
#include <fcntl.h>
#include <list>
#include <string>
#include <utility>
@ -15,16 +14,18 @@
#include "zeek/Val.h"
#include "zeek/util.h"
namespace zeek {
namespace zeek
{
namespace detail {
namespace detail
{
class PrintStmt;
class Attributes;
extern void do_print_stmt(const std::vector<ValPtr>& vals);
} // namespace detail;
} // namespace detail;
class RecordVal;
class Type;
@ -33,7 +34,8 @@ using TypePtr = IntrusivePtr<Type>;
class File;
using FilePtr = IntrusivePtr<File>;
class File final : public Obj {
class File final : public Obj
{
public:
explicit File(FILE* arg_f);
File(FILE* arg_f, const char* filename, const char* access);
@ -45,19 +47,18 @@ public:
// Returns false if an error occured.
bool Write(const char* data, int len = 0);
void Flush() { fflush(f); }
void Flush() { fflush(f); }
FILE* Seek(long position); // seek to absolute position
FILE* Seek(long position); // seek to absolute position
void SetBuf(bool buffered); // false=line buffered, true=fully buffered
void SetBuf(bool buffered); // false=line buffered, true=fully buffered
const TypePtr& GetType() const
{ return t; }
const TypePtr& GetType() const { return t; }
// Whether the file is open in a general sense; it might
// not be open as a Unix file due to our management of
// a finite number of FDs.
bool IsOpen() const { return is_open; }
bool IsOpen() const { return is_open; }
// Returns true if the close made sense, false if it was already
// closed, not active, or whatever.
@ -80,14 +81,13 @@ public:
// Get the file with the given name, opening it if it doesn't yet exist.
static FilePtr Get(const char* name);
void EnableRawOutput() { raw_output = true; }
bool IsRawOutput() const { return raw_output; }
void EnableRawOutput() { raw_output = true; }
bool IsRawOutput() const { return raw_output; }
protected:
friend void detail::do_print_stmt(const std::vector<ValPtr>& vals);
File() { Init(); }
File() { Init(); }
void Init();
/**
@ -114,7 +114,7 @@ protected:
char* access;
detail::Attributes* attrs;
double open_time;
bool is_open; // whether the file is open in a general sense
bool is_open; // whether the file is open in a general sense
bool buffered;
bool raw_output;
@ -122,6 +122,6 @@ protected:
private:
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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include "zeek/Reporter.h"
namespace zeek::detail {
Flare::Flare()
: pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK)
namespace zeek::detail
{
}
Flare::Flare() : pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK) { }
[[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;
for ( ; ; )
for ( ;; )
{
int n = write(pipe.WriteFD(), &tmp, 1);
@ -66,7 +64,7 @@ int Flare::Extinguish(bool signal_safe)
int rval = 0;
char tmp[256];
for ( ; ; )
for ( ;; )
{
int n = read(pipe.ReadFD(), &tmp, sizeof(tmp));
@ -91,4 +89,4 @@ int Flare::Extinguish(bool signal_safe)
return rval;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -4,11 +4,12 @@
#include "zeek/Pipe.h"
namespace zeek::detail {
namespace zeek::detail
{
class Flare {
class Flare
{
public:
/**
* 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.
@ -21,7 +22,7 @@ public:
* @return a file descriptor that will become ready if the flare has been
* Fire()'d and not yet Extinguished()'d.
*/
int FD() const { return pipe.ReadFD(); }
int FD() const { return pipe.ReadFD(); }
/**
* Put the object in the "ready" state.
@ -41,6 +42,6 @@ public:
private:
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.
#include "zeek/zeek-config.h"
#include "zeek/Frag.h"
#include "zeek/Hash.h"
#include "zeek/IP.h"
#include "zeek/NetVar.h"
#include "zeek/session/Manager.h"
#include "zeek/Reporter.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 MAX_ACCEPTABLE_FRAG_SIZE = 64000;
namespace zeek::detail {
namespace zeek::detail
{
FragTimer::~FragTimer()
{
@ -29,9 +30,8 @@ void FragTimer::Dispatch(double t, bool /* is_expire */)
reporter->InternalWarning("fragment timer dispatched w/o reassembler");
}
FragReassembler::FragReassembler(session::Manager* arg_s,
const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt,
const FragReassemblerKey& k, double t)
FragReassembler::FragReassembler(session::Manager* arg_s, const std::unique_ptr<IP_Hdr>& ip,
const u_char* pkt, const FragReassemblerKey& k, double t)
: Reassembler(0, REASSEM_FRAG)
{
s = arg_s;
@ -41,9 +41,9 @@ FragReassembler::FragReassembler(session::Manager* arg_s,
if ( ip4 )
{
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.
memcpy((void*) proto_hdr, (const void*) ip4, proto_hdr_len);
memcpy((void*)proto_hdr, (const void*)ip4, proto_hdr_len);
}
else
{
@ -53,7 +53,7 @@ FragReassembler::FragReassembler(session::Manager* arg_s,
}
reassembled_pkt = nullptr;
frag_size = 0; // flag meaning "not known"
frag_size = 0; // flag meaning "not known"
next_proto = ip->NextProto();
if ( frag_timeout != 0.0 )
@ -70,11 +70,10 @@ FragReassembler::FragReassembler(session::Manager* arg_s,
FragReassembler::~FragReassembler()
{
DeleteTimer();
delete [] proto_hdr;
delete[] proto_hdr;
}
void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
const u_char* pkt)
void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt)
{
const struct ip* ip4 = ip->IP4_Hdr();
@ -82,16 +81,15 @@ void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
{
if ( ip4->ip_p != ((const struct ip*)proto_hdr)->ip_p ||
ip4->ip_hl != ((const struct ip*)proto_hdr)->ip_hl )
// || ip4->ip_tos != proto_hdr->ip_tos
// don't check TOS, there's at least one stack that actually
// uses different values, and it's hard to see an associated
// attack.
s->Weird("fragment_protocol_inconsistency", ip.get());
// || ip4->ip_tos != proto_hdr->ip_tos
// don't check TOS, there's at least one stack that actually
// uses different values, and it's hard to see an associated
// attack.
s->Weird("fragment_protocol_inconsistency", ip.get());
}
else
{
if ( ip->NextProto() != next_proto ||
ip->HdrLen() - 8 != proto_hdr_len )
if ( ip->NextProto() != next_proto || ip->HdrLen() - 8 != proto_hdr_len )
s->Weird("fragment_protocol_inconsistency", ip.get());
// 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)
{
if ( memcmp((const void*) b1, (const void*) b2, n) )
if ( memcmp((const void*)b1, (const void*)b2, n) )
Weird("fragment_inconsistency");
else
Weird("fragment_overlap");
@ -254,7 +252,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
// for a more recent one.
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;
@ -280,7 +278,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
reporter->InternalWarning("bad fragment reassembly");
DeleteTimer();
Expire(run_state::network_time);
delete [] pkt_start;
delete[] pkt_start;
return;
}
@ -293,7 +291,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
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);
reassembled_pkt = std::make_unique<IP_Hdr>(reassem4, true, true);
DeleteTimer();
@ -301,7 +299,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
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);
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);
@ -310,9 +308,8 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
else
{
reporter->InternalWarning("bad IP version in fragment reassembly: %d",
version);
delete [] pkt_start;
reporter->InternalWarning("bad IP version in fragment reassembly: %d", version);
delete[] pkt_start;
}
}
@ -320,7 +317,7 @@ void FragReassembler::Expire(double t)
{
block_list.Clear();
expire_timer->ClearReassembler();
expire_timer = nullptr; // timer manager will delete it
expire_timer = nullptr; // timer manager will delete it
fragment_mgr->Remove(this);
}
@ -331,7 +328,7 @@ void FragReassembler::DeleteTimer()
{
expire_timer->ClearReassembler();
timer_mgr->Cancel(expire_timer);
expire_timer = nullptr; // timer manager will delete it
expire_timer = nullptr; // timer manager will delete it
}
}
@ -388,4 +385,4 @@ uint32_t FragmentManager::MemoryAllocation() const
return fragments.size() * (sizeof(FragmentMap::key_type) + sizeof(FragmentMap::value_type));
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -5,38 +5,44 @@
#include <sys/types.h> // for u_char
#include <tuple>
#include "zeek/util.h" // for bro_uint_t
#include "zeek/IPAddr.h"
#include "zeek/Reassem.h"
#include "zeek/Timer.h"
#include "zeek/util.h" // for bro_uint_t
namespace zeek {
namespace zeek
{
class IP_Hdr;
namespace session { class Manager; }
namespace session
{
class Manager;
}
namespace detail {
namespace detail
{
class FragReassembler;
class FragTimer;
using FragReassemblerKey = std::tuple<IPAddr, IPAddr, bro_uint_t>;
class FragReassembler : public Reassembler {
class FragReassembler : public Reassembler
{
public:
FragReassembler(session::Manager* s, const std::unique_ptr<IP_Hdr>& ip,
const u_char* pkt, const FragReassemblerKey& k, double t);
FragReassembler(session::Manager* s, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt,
const FragReassemblerKey& k, double t);
~FragReassembler() override;
void AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt);
void Expire(double t);
void DeleteTimer();
void ClearTimer() { expire_timer = nullptr; }
void ClearTimer() { expire_timer = nullptr; }
std::unique_ptr<IP_Hdr> ReassembledPkt() { return std::move(reassembled_pkt); }
const FragReassemblerKey& Key() const { return key; }
std::unique_ptr<IP_Hdr> ReassembledPkt() { return std::move(reassembled_pkt); }
const FragReassemblerKey& Key() const { return key; }
protected:
void BlockInserted(DataBlockMap::const_iterator it) override;
@ -46,67 +52,63 @@ protected:
u_char* proto_hdr;
std::unique_ptr<IP_Hdr> reassembled_pkt;
session::Manager* s;
uint64_t frag_size; // size of fully reassembled fragment
uint64_t frag_size; // size of fully reassembled fragment
FragReassemblerKey key;
uint16_t next_proto; // first IPv6 fragment header's next proto field
uint16_t proto_hdr_len;
FragTimer* expire_timer;
};
};
class FragTimer final : public Timer {
class FragTimer final : public Timer
{
public:
FragTimer(FragReassembler* arg_f, double arg_t)
: Timer(arg_t, TIMER_FRAG)
{ f = arg_f; }
FragTimer(FragReassembler* arg_f, double arg_t) : Timer(arg_t, TIMER_FRAG) { f = arg_f; }
~FragTimer() override;
void Dispatch(double t, bool is_expire) override;
// Break the association between this timer and its creator.
void ClearReassembler() { f = nullptr; }
void ClearReassembler() { f = nullptr; }
protected:
FragReassembler* f;
};
};
class FragmentManager {
class FragmentManager
{
public:
FragmentManager() = default;
~FragmentManager();
FragReassembler* NextFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
const u_char* pkt);
FragReassembler* NextFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt);
void Clear();
void Remove(detail::FragReassembler* f);
size_t Size() const { return fragments.size(); }
size_t MaxFragments() const { return max_fragments; }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
uint32_t MemoryAllocation() const;
size_t Size() const { return fragments.size(); }
size_t MaxFragments() const { return max_fragments; }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] uint32_t
MemoryAllocation() const;
private:
using FragmentMap = std::map<detail::FragReassemblerKey, detail::FragReassembler*>;
FragmentMap fragments;
size_t max_fragments = 0;
};
};
extern FragmentManager* fragment_mgr;
class FragReassemblerTracker {
class FragReassemblerTracker
{
public:
FragReassemblerTracker(FragReassembler* f)
: frag_reassembler(f)
{ }
FragReassemblerTracker(FragReassembler* f) : frag_reassembler(f) { }
~FragReassemblerTracker()
{ fragment_mgr->Remove(frag_reassembler); }
~FragReassemblerTracker() { fragment_mgr->Remove(frag_reassembler); }
private:
FragReassembler* frag_reassembler;
};
};
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

@ -4,16 +4,17 @@
#include <broker/error.hh>
#include "zeek/broker/Data.h"
#include "zeek/Func.h"
#include "zeek/Desc.h"
#include "zeek/Func.h"
#include "zeek/ID.h"
#include "zeek/Trigger.h"
#include "zeek/Val.h"
#include "zeek/ID.h"
#include "zeek/broker/Data.h"
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)
{
@ -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
// after this frame does.
captures = function ? function->GetCapturesFrame() : nullptr;
captures_offset_map =
function ? function->GetCapturesOffsetMap() : nullptr;
captures_offset_map = function ? function->GetCapturesOffsetMap() : nullptr;
current_offset = 0;
}
@ -178,10 +178,10 @@ void Frame::Describe(ODesc* d) const
d->Add(size);
for ( int i = 0; i < size; ++i )
{
d->Add(frame[i].val != nullptr);
d->SP();
}
{
d->Add(frame[i].val != nullptr);
d->SP();
}
}
for ( int i = 0; i < size; ++i )
@ -270,7 +270,8 @@ Frame* Frame::SelectiveClone(const IDPList& selection, ScriptFunc* func) const
}
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);
}
@ -334,7 +335,8 @@ broker::expected<broker::data> Frame::SerializeClosureFrame(const IDPList& selec
if ( them.length() )
{
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"));
@ -380,7 +382,7 @@ broker::expected<broker::data> Frame::SerializeClosureFrame(const IDPList& selec
if ( ! expected )
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;
}
@ -404,8 +406,7 @@ broker::expected<broker::data> Frame::SerializeCopyFrame()
return broker::ec::invalid_data;
TypeTag tag = val->GetType()->Tag();
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.emplace_back(std::move(val_tuple));
}
@ -415,7 +416,7 @@ broker::expected<broker::data> Frame::SerializeCopyFrame()
}
std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
const std::optional<FuncType::CaptureList>& captures)
const std::optional<FuncType::CaptureList>& captures)
{
if ( data.size() == 0 )
return std::make_pair(true, nullptr);
@ -458,7 +459,7 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
return std::make_pair(false, nullptr);
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);
if ( ! val )
@ -470,7 +471,6 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
return std::make_pair(true, std::move(rf));
}
// Code to support deprecated semantics:
IDPList outer_ids;
@ -572,7 +572,7 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
return std::make_pair(false, nullptr);
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);
if ( ! val )
@ -590,10 +590,10 @@ void Frame::AddKnownOffsets(const IDPList& ids)
offset_map = std::make_unique<OffsetMap>();
std::transform(ids.begin(), ids.end(), std::inserter(*offset_map, offset_map->end()),
[] (const ID* id) -> std::pair<std::string, int>
{
return std::make_pair(std::string(id->Name()), id->Offset());
});
[](const ID* id) -> std::pair<std::string, int>
{
return std::make_pair(std::string(id->Name()), id->Offset());
});
}
void Frame::CaptureClosure(Frame* c, IDPList arg_outer_ids)
@ -643,7 +643,10 @@ void Frame::ClearElement(int n)
bool Frame::IsOuterID(const ID* in) const
{
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)
@ -661,20 +664,21 @@ broker::expected<broker::data> Frame::SerializeIDList(const IDPList& in)
return {std::move(rval)};
}
broker::expected<broker::data>
Frame::SerializeOffsetMap(const OffsetMap& in)
broker::expected<broker::data> Frame::SerializeOffsetMap(const OffsetMap& in)
{
broker::vector rval;
std::for_each(in.begin(), in.end(),
[&rval] (const std::pair<std::string, int>& e)
{ rval.emplace_back(e.first); rval.emplace_back(e.second);});
[&rval](const std::pair<std::string, int>& e)
{
rval.emplace_back(e.first);
rval.emplace_back(e.second);
});
return {std::move(rval)};
}
std::pair<bool, IDPList>
Frame::UnserializeIDList(const broker::vector& data)
std::pair<bool, IDPList> Frame::UnserializeIDList(const broker::vector& data)
{
IDPList rval;
if ( data.size() % 2 != 0 )
@ -725,14 +729,14 @@ Frame::UnserializeOffsetMap(const broker::vector& data)
if ( ! key )
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 )
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));
}
}
}

View file

@ -2,43 +2,46 @@
#pragma once
#include <unordered_map>
#include <string>
#include <utility>
#include <vector>
#include <memory>
#include <optional>
#include <broker/data.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/Type.h"
#include "zeek/IntrusivePtr.h"
#include "zeek/ZeekArgs.h"
#include "zeek/ZeekList.h" // for typedef val_list
namespace zeek {
namespace zeek
{
using ValPtr = IntrusivePtr<Val>;
namespace detail {
namespace detail
{
class CallExpr;
class ScriptFunc;
using IDPtr = IntrusivePtr<ID>;
namespace trigger {
namespace trigger
{
class Trigger;
using TriggerPtr = IntrusivePtr<Trigger>;
}
}
class Frame;
using FramePtr = IntrusivePtr<Frame>;
class Frame : public Obj {
class Frame : public Obj
{
public:
/**
* Constructs a new frame belonging to *func* with *fn_args*
@ -83,8 +86,7 @@ public:
* @param v the value to associate it with
*/
void SetElement(const ID* id, ValPtr v);
void SetElement(const IDPtr& id, ValPtr v)
{ SetElement(id.get(), std::move(v)); }
void SetElement(const IDPtr& id, ValPtr v) { SetElement(id.get(), std::move(v)); }
/**
* Gets the value associated with *id* and returns it. Returns
@ -93,8 +95,7 @@ public:
* @param id the id who's value to retreive
* @return the value associated with *id*
*/
const ValPtr& GetElementByID(const IDPtr& id) const
{ return GetElementByID(id.get()); }
const ValPtr& GetElementByID(const IDPtr& id) const { return GetElementByID(id.get()); }
/**
* Adjusts the current offset being used for frame accesses.
@ -103,7 +104,7 @@ public:
* @param incr Amount by which to increase the frame offset.
* Use a negative value to shrink the offset.
*/
void AdjustOffset(int incr) { current_offset += incr; }
void AdjustOffset(int incr) { current_offset += incr; }
/**
* Resets all of the indexes from [*startIdx, frame_size) in
@ -120,43 +121,40 @@ public:
/**
* @return the function that the frame is associated with.
*/
const ScriptFunc* GetFunction() const { return function; }
const ScriptFunc* GetFunction() const { return function; }
/**
* @return the arguments passed to the function that this frame
* is associated with.
*/
const Args* GetFuncArgs() const { return func_args; }
const Args* GetFuncArgs() const { return func_args; }
/**
* Change the function that the frame is associated with.
*
* @param func the function for the frame to be associated with.
*/
void SetFunction(ScriptFunc* func) { function = func; }
void SetFunction(ScriptFunc* func) { function = func; }
/**
* Sets the next statement to be executed in the context of the frame.
*
* @param stmt the statement to set it to.
*/
void SetNextStmt(Stmt* stmt) { next_stmt = stmt; }
void SetNextStmt(Stmt* stmt) { next_stmt = stmt; }
/**
* @return the next statement to be executed in the context of the frame.
*/
Stmt* GetNextStmt() const { return next_stmt; }
Stmt* GetNextStmt() const { return next_stmt; }
/** Used to implement "next" command in debugger. */
void BreakBeforeNextStmt(bool should_break)
{ break_before_next_stmt = should_break; }
bool BreakBeforeNextStmt() const
{ return break_before_next_stmt; }
void BreakBeforeNextStmt(bool should_break) { break_before_next_stmt = should_break; }
bool BreakBeforeNextStmt() const { return break_before_next_stmt; }
/** Used to implement "finish" command in debugger. */
void BreakOnReturn(bool should_break)
{ break_on_return = should_break; }
bool BreakOnReturn() const { return break_on_return; }
void BreakOnReturn(bool should_break) { break_on_return = should_break; }
bool BreakOnReturn() const { return break_on_return; }
/**
* Performs a deep copy of all the values in the current frame. If
@ -233,8 +231,8 @@ public:
* reflects captures with copy-semantics rather than deprecated
* reference semantics.
*/
static std::pair<bool, FramePtr> Unserialize(const broker::vector& data,
const std::optional<FuncType::CaptureList>& captures);
static std::pair<bool, FramePtr>
Unserialize(const broker::vector& data, const std::optional<FuncType::CaptureList>& captures);
/**
* Sets the IDs that the frame knows offsets for. These offsets will
@ -257,17 +255,17 @@ public:
// the trigger needs to be registered.
void SetTrigger(trigger::TriggerPtr arg_trigger);
void ClearTrigger();
trigger::Trigger* GetTrigger() const { return trigger.get(); }
trigger::Trigger* GetTrigger() const { return trigger.get(); }
void SetCall(const CallExpr* arg_call) { call = arg_call; }
void ClearCall() { call = nullptr; }
const CallExpr* GetCall() const { return call; }
void SetCall(const CallExpr* arg_call) { call = arg_call; }
void ClearCall() { call = nullptr; }
const CallExpr* GetCall() const { return call; }
void SetCallLoc(const Location* loc) { call_loc = loc; }
void SetCallLoc(const Location* loc) { call_loc = loc; }
const detail::Location* GetCallLocation() const;
void SetDelayed() { delayed = true; }
bool HasDelayed() const { return delayed; }
void SetDelayed() { delayed = true; }
bool HasDelayed() const { return delayed; }
/**
* Track a new function that refers to this frame for use as a closure.
@ -279,15 +277,15 @@ public:
void AddFunctionWithClosureRef(ScriptFunc* func);
private:
using OffsetMap = std::unordered_map<std::string, int>;
struct Element {
struct Element
{
ValPtr val;
// Weak reference is used to prevent circular reference memory leaks
// in lambdas/closures.
bool weak_ref;
};
};
const ValPtr& GetElementByID(const ID* id) const;
@ -321,20 +319,17 @@ private:
bool IsCaptureID(const ID* in) const;
/** Serializes an offset_map */
static broker::expected<broker::data>
SerializeOffsetMap(const OffsetMap& in);
static broker::expected<broker::data> SerializeOffsetMap(const OffsetMap& in);
/** Serializes an IDPList */
static broker::expected<broker::data>
SerializeIDList(const IDPList& in);
static broker::expected<broker::data> SerializeIDList(const IDPList& in);
/** Unserializes an offset map. */
static std::pair<bool, std::unordered_map<std::string, int>>
UnserializeOffsetMap(const broker::vector& data);
/** Unserializes an IDPList. */
static std::pair<bool, IDPList>
UnserializeIDList(const broker::vector& data);
static std::pair<bool, IDPList> UnserializeIDList(const broker::vector& data);
/** The number of vals that can be stored in this frame. */
int size;
@ -392,13 +387,13 @@ private:
trigger::TriggerPtr trigger;
const CallExpr* call = nullptr;
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;
};
};
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek
/**
* 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.
#include "zeek/zeek-config.h"
#include "zeek/Func.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "zeek/zeek-config.h"
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#include <sys/time.h>
#include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#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 <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/Debug.h"
#include "zeek/Desc.h"
#include "zeek/Event.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/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/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/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
// break what symbols are available when, which keeps the build from breaking.
@ -77,16 +73,18 @@
#include "CPP-load.bif.func_def"
// clang-format on
extern RETSIGTYPE sig_handler(int signo);
extern RETSIGTYPE sig_handler(int signo);
namespace zeek::detail {
namespace zeek::detail
{
std::vector<CallInfo> call_stack;
bool did_builtin_init = false;
std::vector<void (*)()> bif_initializers;
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()
{
@ -149,8 +147,8 @@ Func::Func(Kind arg_kind) : kind(arg_kind)
Func::~Func() = default;
void Func::AddBody(detail::StmtPtr /* new_body */,
const std::vector<detail::IDPtr>& /* new_inits */,
size_t /* new_frame_size */, int /* priority */)
const std::vector<detail::IDPtr>& /* new_inits */, size_t /* new_frame_size */,
int /* priority */)
{
Internal("Func::AddBody called");
}
@ -242,8 +240,7 @@ void Func::CopyStateInto(Func* other) const
other->unique_id = unique_id;
}
void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
FunctionFlavor flavor) const
void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const
{
// Helper function factoring out this code from ScriptFunc:Call() for
// better readability.
@ -251,54 +248,57 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
if ( ! handled )
{
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
// into ::Call method).
return;
}
switch ( flavor ) {
case FUNC_FLAVOR_EVENT:
if ( hook_result )
reporter->InternalError("plugin returned non-void result for event %s",
this->Name());
break;
case FUNC_FLAVOR_HOOK:
if ( hook_result->GetType()->Tag() != TYPE_BOOL )
reporter->InternalError("plugin returned non-bool for hook %s",
this->Name());
break;
case FUNC_FLAVOR_FUNCTION:
switch ( flavor )
{
const auto& yt = GetType()->Yield();
if ( (! yt) || yt->Tag() == TYPE_VOID )
{
case FUNC_FLAVOR_EVENT:
if ( hook_result )
reporter->InternalError("plugin returned non-void result for void method %s",
this->Name());
}
reporter->InternalError("plugin returned non-void result for event %s",
this->Name());
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",
hook_result->GetType()->Tag(), yt->Tag(), this->Name());
}
break;
break;
case FUNC_FLAVOR_HOOK:
if ( hook_result->GetType()->Tag() != TYPE_BOOL )
reporter->InternalError("plugin returned non-bool for hook %s", this->Name());
break;
case FUNC_FLAVOR_FUNCTION:
{
const auto& yt = GetType()->Yield();
if ( (! yt) || yt->Tag() == TYPE_VOID )
{
if ( hook_result )
reporter->InternalError(
"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 )
{
reporter->InternalError(
"plugin returned wrong type (got %d, expecting %d) for %s",
hook_result->GetType()->Tag(), yt->Tag(), this->Name());
}
break;
}
}
}
}
namespace detail {
namespace detail
{
ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body,
const std::vector<IDPtr>& aggr_inits,
ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body, const std::vector<IDPtr>& aggr_inits,
size_t arg_frame_size, int priority)
: Func(SCRIPT_FUNC)
{
@ -316,8 +316,8 @@ ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body,
}
}
ScriptFunc::ScriptFunc(std::string _name, FuncTypePtr ft,
std::vector<StmtPtr> bs, std::vector<int> priorities)
ScriptFunc::ScriptFunc(std::string _name, FuncTypePtr ft, std::vector<StmtPtr> bs,
std::vector<int> priorities)
{
name = std::move(_name);
frame_size = ft->ParamList()->GetTypes().size();
@ -355,7 +355,10 @@ ScriptFunc::~ScriptFunc()
bool ScriptFunc::IsPure() const
{
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
@ -368,9 +371,8 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
if ( sample_logger )
sample_logger->FunctionSeen(this);
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION,
HookCallFunction(this, parent, args),
empty_hook_result);
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(
HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
CheckPluginResult(handled, hook_result, Flavor());
@ -396,7 +398,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
f->SetCall(parent->GetCall());
}
g_frame_stack.push_back(f.get()); // used for backtracing
g_frame_stack.push_back(f.get()); // used for backtracing
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
call_stack.emplace_back(CallInfo{call_expr, this, *args});
@ -405,8 +407,8 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
ODesc d;
DescribeDebug(&d, args);
g_trace_state.LogTrace("%s called: %s\n",
GetType()->FlavorString().c_str(), d.Description());
g_trace_state.LogTrace("%s called: %s\n", GetType()->FlavorString().c_str(),
d.Description());
}
StmtFlowType flow = FLOW_NEXT;
@ -483,11 +485,10 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
// Warn if the function returns something, but we returned from
// the function without an explicit return, or without a value.
else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID &&
(flow != FLOW_RETURN /* we fell off the end */ ||
! result /* explicit return with no result */) &&
! f->HasDelayed() )
reporter->Warning("non-void function returning without a value: %s",
Name());
(flow != FLOW_RETURN /* we fell off the end */ ||
! result /* explicit return with no result */) &&
! f->HasDelayed() )
reporter->Warning("non-void function returning without a value: %s", Name());
if ( result && g_trace_state.DoTrace() )
{
@ -552,8 +553,7 @@ void ScriptFunc::SetCaptures(Frame* f)
}
}
void ScriptFunc::AddBody(StmtPtr new_body,
const std::vector<IDPtr>& new_inits,
void ScriptFunc::AddBody(StmtPtr new_body, const std::vector<IDPtr>& new_inits,
size_t new_frame_size, int priority)
{
if ( new_frame_size > frame_size )
@ -634,8 +634,7 @@ bool ScriptFunc::HasCopySemantics() const
void ScriptFunc::SetClosureFrame(Frame* f)
{
if ( closure )
reporter->InternalError("Tried to override closure for ScriptFunc %s.",
Name());
reporter->InternalError("Tried to override closure for ScriptFunc %s.", Name());
// Have to use weak references initially because otherwise Ref'ing the
// 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());
ASSERT(result.first);
ASSERT(result.first);
SetCaptures(result.second.release());
return true;
}
FuncPtr ScriptFunc::DoClone()
{
// 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 body,
const std::vector<IDPtr>& inits)
StmtPtr ScriptFunc::AddInits(StmtPtr body, const std::vector<IDPtr>& inits)
{
if ( inits.empty() )
return body;
@ -740,9 +736,8 @@ StmtPtr ScriptFunc::AddInits(
return stmt_series;
}
BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
bool arg_is_pure)
: Func(BUILTIN_FUNC)
BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, bool arg_is_pure)
: Func(BUILTIN_FUNC)
{
func = arg_func;
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();
}
BuiltinFunc::~BuiltinFunc()
{
}
BuiltinFunc::~BuiltinFunc() { }
bool BuiltinFunc::IsPure() const
{
@ -778,9 +771,8 @@ ValPtr BuiltinFunc::Invoke(Args* args, Frame* parent) const
if ( sample_logger )
sample_logger->FunctionSeen(this);
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION,
HookCallFunction(this, parent, args),
empty_hook_result);
auto [handled, hook_result] = PLUGIN_HOOK_WITH_RESULT(
HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
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)
{
if ( f->TheFunc() != BifFunc::fmt_bif)
if ( f->TheFunc() != BifFunc::fmt_bif )
return true;
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 )
{
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;
}
}
@ -924,7 +917,7 @@ function_ingredients::function_ingredients(ScopePtr scope, StmtPtr body)
static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
{
auto emit = [=](const CallExpr* ce)
{
{
if ( ce )
{
if ( unwind )
@ -933,8 +926,7 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
{
ODesc d;
arg->Describe(&d);
reporter->ExprRuntimeError(ce, "%s (%s), during call:", msg,
d.Description());
reporter->ExprRuntimeError(ce, "%s (%s), during call:", msg, d.Description());
}
else
reporter->ExprRuntimeError(ce, "%s", msg);
@ -959,8 +951,7 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
reporter->Error("%s", msg);
}
}
};
};
if ( call_stack.empty() )
{
@ -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
{ return name.size() > 2 && name[0] == '_' && name[1] == '_'; };
{
return name.size() > 2 && name[0] == '_' && name[1] == '_';
};
std::string last_func = last_call.func->Name();
auto pos = last_func.find_first_of("::");
@ -1055,21 +1048,20 @@ void init_primary_bifs()
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 "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();
did_builtin_init = true;
}
} // namespace detail
} // namespace detail
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);
}
} // namespace zeek
} // namespace zeek

View file

@ -2,38 +2,42 @@
#pragma once
#include <utility>
#include <memory>
#include <string>
#include <vector>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
#include "zeek/ZeekList.h"
#include "zeek/Stmt.h"
#include "zeek/BifReturnVal.h"
#include "zeek/Obj.h"
#include "zeek/Scope.h"
#include "zeek/Type.h" /* for function_flavor */
#include "zeek/Stmt.h"
#include "zeek/TraverseTypes.h"
#include "zeek/Type.h" /* for function_flavor */
#include "zeek/ZeekArgs.h"
#include "zeek/BifReturnVal.h"
#include "zeek/ZeekList.h"
namespace caf {
namespace caf
{
template <class> class expected;
}
}
namespace broker {
namespace broker
{
class data;
using vector = std::vector<data>;
using caf::expected;
}
}
namespace zeek {
namespace zeek
{
class Val;
class FuncType;
namespace detail {
namespace detail
{
class Scope;
class Stmt;
@ -46,34 +50,41 @@ using StmtPtr = IntrusivePtr<Stmt>;
class ScriptFunc;
} // namespace detail
} // namespace detail
class Func;
using FuncPtr = IntrusivePtr<Func>;
class Func : public Obj {
class Func : public Obj
{
public:
static inline const FuncPtr nil;
enum Kind { SCRIPT_FUNC, BUILTIN_FUNC };
enum Kind
{
SCRIPT_FUNC,
BUILTIN_FUNC
};
explicit Func(Kind arg_kind);
~Func() override;
virtual bool IsPure() const = 0;
FunctionFlavor Flavor() const { return GetType()->Flavor(); }
FunctionFlavor Flavor() const { return GetType()->Flavor(); }
struct Body {
struct Body
{
detail::StmtPtr stmts;
int priority;
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; }
bool HasBodies() const { return bodies.size(); }
const std::vector<Body>& GetBodies() const { return bodies; }
bool HasBodies() const { return bodies.size(); }
/**
* Calls a Zeek function.
@ -81,16 +92,14 @@ public:
* @param parent the frame from which the function is being called.
* @return the return value of the function call.
*/
virtual ValPtr Invoke(
zeek::Args* args, detail::Frame* parent = nullptr) const = 0;
virtual ValPtr Invoke(zeek::Args* args, detail::Frame* parent = nullptr) const = 0;
/**
* A version of Invoke() taking a variable number of individual arguments.
*/
template <class... Args>
std::enable_if_t<
std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>,
ValPtr>
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>,
ValPtr>
Invoke(Args&&... args) const
{
auto zargs = zeek::Args{std::forward<Args>(args)...};
@ -98,20 +107,18 @@ public:
}
// Add a new event handler to an existing function (event).
virtual void AddBody(detail::StmtPtr new_body,
const std::vector<detail::IDPtr>& new_inits,
virtual void AddBody(detail::StmtPtr new_body, const std::vector<detail::IDPtr>& new_inits,
size_t new_frame_size, int priority = 0);
virtual void SetScope(detail::ScopePtr newscope);
virtual detail::ScopePtr GetScope() const { return scope; }
virtual detail::ScopePtr GetScope() const { return scope; }
const FuncTypePtr& GetType() const
{ return type; }
const FuncTypePtr& GetType() const { return type; }
Kind GetKind() const { return kind; }
Kind GetKind() const { return kind; }
const char* Name() const { return name.c_str(); }
void SetName(const char* arg_name) { name = arg_name; }
void SetName(const char* arg_name) { name = arg_name; }
void Describe(ODesc* d) const override = 0;
virtual void DescribeDebug(ODesc* d, const zeek::Args* args) const;
@ -122,7 +129,9 @@ public:
uint32_t GetUniqueFuncID() const { return unique_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:
Func();
@ -131,8 +140,7 @@ protected:
void CopyStateInto(Func* other) const;
// Helper function for checking result of plugin hook.
void CheckPluginResult(bool handled, const ValPtr& hook_result,
FunctionFlavor flavor) const;
void CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const;
std::vector<Body> bodies;
detail::ScopePtr scope;
@ -141,19 +149,20 @@ protected:
FuncTypePtr type;
std::string name;
static inline std::vector<FuncPtr> unique_ids;
};
};
namespace detail {
namespace detail
{
class ScriptFunc : public Func {
class ScriptFunc : public Func
{
public:
ScriptFunc(const IDPtr& id, StmtPtr body,
const std::vector<IDPtr>& inits,
size_t frame_size, int priority);
ScriptFunc(const IDPtr& id, StmtPtr body, const std::vector<IDPtr>& inits, size_t frame_size,
int priority);
// For compiled scripts.
ScriptFunc(std::string name, FuncTypePtr ft,
std::vector<StmtPtr> bodies, std::vector<int> priorities);
ScriptFunc(std::string name, FuncTypePtr ft, std::vector<StmtPtr> bodies,
std::vector<int> priorities);
~ScriptFunc() override;
@ -176,7 +185,7 @@ public:
*
* @return internal frame kept by the function for persisting captures
*/
Frame* GetCapturesFrame() const { return captures_frame; }
Frame* GetCapturesFrame() const { return captures_frame; }
// Same definition as in Frame.h.
using OffsetMap = std::unordered_map<std::string, int>;
@ -186,8 +195,7 @@ public:
*
* @return pointer to mapping of captures to slots
*/
const OffsetMap* GetCapturesOffsetMap() const
{ return captures_offset_mapping; }
const OffsetMap* GetCapturesOffsetMap() const { return captures_offset_mapping; }
// The following "Closure" methods implement the deprecated
// capture-by-reference functionality.
@ -233,9 +241,8 @@ public:
*/
bool DeserializeCaptures(const broker::vector& data);
void AddBody(StmtPtr new_body,
const std::vector<IDPtr>& new_inits,
size_t new_frame_size, int priority) override;
void AddBody(StmtPtr new_body, const std::vector<IDPtr>& new_inits, size_t new_frame_size,
int priority) override;
/**
* Replaces the given current instance of a function body with
@ -245,17 +252,16 @@ public:
* @param old_body Body to replace.
* @param new_body New body to use; can be nil.
*/
void ReplaceBody(const detail::StmtPtr& old_body,
detail::StmtPtr new_body);
void ReplaceBody(const detail::StmtPtr& old_body, detail::StmtPtr new_body);
StmtPtr CurrentBody() const { return current_body; }
int CurrentPriority() const { return current_priority; }
StmtPtr CurrentBody() const { return current_body; }
int CurrentPriority() const { return current_priority; }
/**
* Returns the function's frame size.
* @return The number of ValPtr slots in the function's frame.
*/
int FrameSize() const { return frame_size; }
int FrameSize() const { return frame_size; }
/**
* Changes the function's frame size to a new size - used for
@ -263,20 +269,17 @@ public:
*
* @param new_size The frame size the function should use.
*/
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. */
void SetOuterIDs(IDPList ids)
{ outer_ids = std::move(ids); }
void SetOuterIDs(IDPList ids) { outer_ids = std::move(ids); }
void Describe(ODesc* d) const override;
protected:
ScriptFunc() : Func(SCRIPT_FUNC) {}
ScriptFunc() : Func(SCRIPT_FUNC) { }
StmtPtr AddInits(
StmtPtr body,
const std::vector<IDPtr>& inits);
StmtPtr AddInits(StmtPtr body, const std::vector<IDPtr>& inits);
/**
* Clones this function along with its closures.
@ -323,39 +326,46 @@ private:
// ... and its priority.
int current_priority = 0;
};
};
using built_in_func = BifReturnVal (*)(Frame* frame, const Args* args);
class BuiltinFunc final : public Func {
class BuiltinFunc final : public Func
{
public:
BuiltinFunc(built_in_func func, const char* name, bool is_pure);
~BuiltinFunc() override;
bool IsPure() const override;
ValPtr Invoke(zeek::Args* args, Frame* parent) const override;
built_in_func TheFunc() const { return func; }
built_in_func TheFunc() const { return func; }
void Describe(ODesc* d) const override;
protected:
BuiltinFunc() { func = nullptr; is_pure = 0; }
BuiltinFunc()
{
func = nullptr;
is_pure = 0;
}
built_in_func func;
bool is_pure;
};
};
extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
struct CallInfo {
struct CallInfo
{
const CallExpr* call;
const Func* func;
const zeek::Args& args;
};
};
// Struct that collects all the specifics defining a Func. Used for ScriptFuncs
// with closures.
struct function_ingredients {
struct function_ingredients
{
// Gathers all of the information from a scope and a function body needed
// to build a function.
@ -367,7 +377,7 @@ struct function_ingredients {
int frame_size;
int priority;
ScopePtr scope;
};
};
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, Obj* arg);
} // namespace detail
} // namespace detail
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, Obj* arg);
} // namespace zeek
} // namespace zeek

View file

@ -1,45 +1,56 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/Hash.h"
#include <highwayhash/sip_hash.h>
#include <highwayhash/highwayhash_target.h>
#include <highwayhash/instruction_sets.h>
#include <highwayhash/sip_hash.h>
#include "zeek/digest.h"
#include "zeek/Reporter.h"
#include "zeek/ZeekString.h"
#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"
namespace zeek::detail {
namespace zeek::detail
{
alignas(32) uint64_t KeyedHash::shared_highwayhash_key[4];
alignas(32) uint64_t KeyedHash::cluster_highwayhash_key[4];
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.
static_assert(std::is_same<hash64_t, highwayhash::HHResult64>::value, "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");
// 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.
static_assert(std::is_same<hash64_t, highwayhash::HHResult64>::value,
"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)
{
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_highwayhash_key), highwayhash::HHKey>::value, "Highwayhash HHKey is not uint64_t[4]");
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_highwayhash_key), highwayhash::HHKey>::value,
"Highwayhash HHKey is not uint64_t[4]");
if ( seeds_initialized )
return;
// 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.
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
// yes, we use the same buffer twice to initialize two different keys. This should not really be 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.
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
// yes, we use the same buffer twice to initialize two different keys. This should not really be
// 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);
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);
seeds_initialized = true;
@ -47,39 +58,45 @@ void KeyedHash::InitializeSeeds(const std::array<uint32_t, SEED_INIT_SIZE>& seed
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)
{
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)
{
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)
{
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 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;
}
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)
{
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()
@ -92,7 +109,7 @@ void init_hash_function()
HashKey::HashKey(bro_int_t i)
{
key_u.i = i;
key = (void*) &key_u;
key = (void*)&key_u;
size = sizeof(i);
hash = HashBytes(key, size);
}
@ -100,7 +117,7 @@ HashKey::HashKey(bro_int_t i)
HashKey::HashKey(bro_uint_t u)
{
key_u.i = bro_int_t(u);
key = (void*) &key_u;
key = (void*)&key_u;
size = sizeof(u);
hash = HashBytes(key, size);
}
@ -108,7 +125,7 @@ HashKey::HashKey(bro_uint_t u)
HashKey::HashKey(uint32_t u)
{
key_u.u32 = u;
key = (void*) &key_u;
key = (void*)&key_u;
size = sizeof(u);
hash = HashBytes(key, size);
}
@ -116,19 +133,19 @@ HashKey::HashKey(uint32_t u)
HashKey::HashKey(const uint32_t u[], int n)
{
size = n * sizeof(u[0]);
key = (void*) u;
key = (void*)u;
hash = HashBytes(key, size);
}
HashKey::HashKey(double d)
{
union {
union {
double d;
int i[2];
} u;
} u;
key_u.d = u.d = d;
key = (void*) &key_u;
key = (void*)&key_u;
size = sizeof(d);
hash = HashBytes(key, size);
}
@ -136,22 +153,22 @@ HashKey::HashKey(double d)
HashKey::HashKey(const void* p)
{
key_u.p = p;
key = (void*) &key_u;
key = (void*)&key_u;
size = sizeof(p);
hash = HashBytes(key, size);
}
HashKey::HashKey(const char* s)
{
size = strlen(s); // note - skip final \0
key = (void*) s;
size = strlen(s); // note - skip final \0
key = (void*)s;
hash = HashBytes(key, size);
}
HashKey::HashKey(const String* s)
{
size = s->Len();
key = (void*) s->Bytes();
key = (void*)s->Bytes();
hash = HashBytes(key, size);
}
@ -162,7 +179,7 @@ HashKey::HashKey(int copy_key, void* arg_key, int arg_size)
if ( copy_key )
{
key = (void*) new char[size];
key = (void*)new char[size];
memcpy(key, arg_key, size);
}
else
@ -179,8 +196,7 @@ HashKey::HashKey(const void* arg_key, int arg_size, hash_t arg_hash)
is_our_dynamic = true;
}
HashKey::HashKey(const void* arg_key, int arg_size, hash_t arg_hash,
bool /* dont_copy */)
HashKey::HashKey(const void* arg_key, int arg_size, hash_t arg_hash, bool /* dont_copy */)
{
size = arg_size;
hash = arg_hash;
@ -208,7 +224,7 @@ void* HashKey::TakeKey()
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);
return k_copy;
}
@ -218,4 +234,4 @@ hash_t HashKey::HashBytes(const void* bytes, int 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.
* 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,
* e.g. for lookups in hash-tables; the Hashes are also used for connection ID generation.
* The HashKey class is the actual class that is used to generate Hash keys that are used
* 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
* a seed file is used. There are a few functions that create hashes that are static over runs
* and use an installation-wide seed value; these are specifically called out.
* This means that the hashes created by most functions in this file will be different each run,
* unless a seed file is used. There are a few functions that create hashes that are static over
* runs and use an installation-wide seed value; these are specifically called out.
*/
#pragma once
@ -26,26 +27,33 @@
// to allow bro_md5_hmac access to the hmac seed
#include "zeek/ZeekArgs.h"
namespace zeek { class String; }
namespace zeek::detail {
namespace zeek
{
class String;
}
namespace zeek::detail
{
class Frame;
class BifReturnVal;
}
}
namespace zeek::BifFunc {
extern zeek::detail::BifReturnVal md5_hmac_bif(zeek::detail::Frame* frame, const zeek::Args*);
}
namespace zeek::BifFunc
{
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 hash64_t;
typedef uint64_t hash128_t[2];
typedef uint64_t hash256_t[4];
class KeyedHash {
class KeyedHash
{
public:
/**
* Generate a 64 bit digest hash.
@ -193,19 +201,23 @@ public:
private:
// actually HHKey. This key changes each start (unless a seed is specified)
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];
// 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];
// This key changes each start (unless a seed is specified)
inline static uint8_t shared_hmac_md5_key[16];
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*);
};
};
typedef enum {
typedef enum
{
HASH_KEY_INT,
HASH_KEY_DOUBLE,
HASH_KEY_STRING
@ -213,7 +225,8 @@ typedef enum {
constexpr int NUM_HASH_KEYS = HASH_KEY_STRING + 1;
class HashKey {
class HashKey
{
public:
explicit HashKey(bro_int_t i);
explicit HashKey(bro_uint_t u);
@ -226,7 +239,7 @@ public:
~HashKey()
{
if ( is_our_dynamic )
delete [] (char *) key;
delete[](char*) key;
}
// Create a HashKey given all of its components. "key" is assumed
@ -257,30 +270,35 @@ public:
// we give them a copy of it.
void* TakeKey();
const void* Key() const { return key; }
int Size() const { return size; }
hash_t Hash() const { return hash; }
const void* Key() const { return key; }
int Size() const { return size; }
hash_t Hash() const { return hash; }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const { return padded_sizeof(*this) + util::pad_size(size); }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this) + util::pad_size(size);
}
static hash_t HashBytes(const void* bytes, int size);
protected:
void* CopyKey(const void* key, int size) const;
union {
union {
bro_int_t i;
uint32_t u32;
double d;
const void* p;
} key_u;
} key_u;
void* key;
hash_t hash;
int size;
bool is_our_dynamic = false;
};
};
extern void init_hash_function();
} // namespace zeek::detail
} // namespace zeek::detail

142
src/ID.cc
View file

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

119
src/ID.h
View file

@ -7,12 +7,13 @@
#include <string_view>
#include <vector>
#include "zeek/Obj.h"
#include "zeek/Attr.h"
#include "zeek/Notifier.h"
#include "zeek/Obj.h"
#include "zeek/TraverseTypes.h"
namespace zeek {
namespace zeek
{
class Func;
class Val;
@ -29,23 +30,36 @@ using EnumTypePtr = IntrusivePtr<EnumType>;
using ValPtr = IntrusivePtr<Val>;
using FuncPtr = IntrusivePtr<Func>;
}
}
namespace zeek::detail {
namespace zeek::detail
{
class Attributes;
class Expr;
using ExprPtr = IntrusivePtr<Expr>;
enum InitClass { INIT_NONE, INIT_FULL, INIT_EXTRA, INIT_REMOVE, };
enum IDScope { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL };
enum InitClass
{
INIT_NONE,
INIT_FULL,
INIT_EXTRA,
INIT_REMOVE,
};
enum IDScope
{
SCOPE_FUNCTION,
SCOPE_MODULE,
SCOPE_GLOBAL
};
class ID;
using IDPtr = IntrusivePtr<ID>;
class IDOptInfo;
class ID final : public Obj, public notifier::detail::Modifiable {
class ID final : public Obj, public notifier::detail::Modifiable
{
public:
static inline const IDPtr nil;
@ -53,53 +67,48 @@ public:
~ID() override;
const char* Name() const { return name; }
const char* Name() const { return name; }
int Scope() const { return scope; }
bool IsGlobal() const { return scope != SCOPE_FUNCTION; }
int Scope() const { return scope; }
bool IsGlobal() const { return scope != SCOPE_FUNCTION; }
bool IsExport() const { return is_export; }
void SetExport() { is_export = true; }
bool IsExport() const { return is_export; }
void SetExport() { is_export = true; }
std::string ModuleName() const;
void SetType(TypePtr t);
const TypePtr& GetType() const
{ return type; }
const TypePtr& GetType() const { return type; }
template <class T>
IntrusivePtr<T> GetType() const
{ return cast_intrusive<T>(type); }
template <class T> IntrusivePtr<T> GetType() const { return cast_intrusive<T>(type); }
bool IsType() const
{ return is_type; }
bool IsType() const { return is_type; }
void MakeType() { is_type = true; }
void MakeType() { is_type = true; }
void SetVal(ValPtr v);
void SetVal(ValPtr v, InitClass c);
void SetVal(ExprPtr ev, InitClass c);
bool HasVal() const { return val != nullptr; }
bool HasVal() const { return val != nullptr; }
const ValPtr& GetVal() const
{ return val; }
const ValPtr& GetVal() const { return val; }
void ClearVal();
void SetConst() { is_const = true; }
bool IsConst() const { return is_const; }
void SetConst() { is_const = true; }
bool IsConst() const { return is_const; }
void SetOption();
bool IsOption() const { return is_option; }
bool IsOption() const { return is_option; }
void SetEnumConst() { is_enum_const = true; }
bool IsEnumConst() const { return is_enum_const; }
void SetEnumConst() { is_enum_const = true; }
bool IsEnumConst() const { return is_enum_const; }
void SetOffset(int arg_offset) { offset = arg_offset; }
int Offset() const { return offset; }
void SetOffset(int arg_offset) { offset = arg_offset; }
int Offset() const { return offset; }
bool IsRedefinable() const;
@ -108,8 +117,7 @@ public:
void RemoveAttr(AttrTag a);
void UpdateValAttrs();
const AttributesPtr& GetAttrs() const
{ return attrs; }
const AttributesPtr& GetAttrs() const { return attrs; }
const AttrPtr& GetAttr(AttrTag t) const;
@ -128,20 +136,17 @@ public:
void DescribeReST(ODesc* d, bool roles_only = false) const;
void DescribeReSTShort(ODesc* d) const;
bool DoInferReturnType() const
{ return infer_return_type; }
void SetInferReturnType(bool infer)
{ infer_return_type = infer; }
bool DoInferReturnType() const { return infer_return_type; }
void SetInferReturnType(bool infer) { infer_return_type = infer; }
virtual TraversalCode Traverse(TraversalCallback* cb) const;
bool HasOptionHandlers() const
{ return !option_handlers.empty(); }
bool HasOptionHandlers() const { return ! option_handlers.empty(); }
void AddOptionHandler(FuncPtr callback, int priority);
std::vector<Func*> GetOptionHandlers() const;
IDOptInfo* GetOptInfo() const { return opt_info; }
IDOptInfo* GetOptInfo() const { return opt_info; }
protected:
void EvalFunc(ExprPtr ef, ExprPtr ev);
@ -168,12 +173,12 @@ protected:
// via the associated pointer, to allow it to be modified in
// contexts where the ID is itself "const".
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;
@ -197,9 +202,10 @@ const TypePtr& find_type(std::string_view name);
* @param name The identifier name to lookup
* @return The type of the identifier.
*/
template<class T>
IntrusivePtr<T> find_type(std::string_view name)
{ return cast_intrusive<T>(find_type(name)); }
template <class T> IntrusivePtr<T> find_type(std::string_view name)
{
return cast_intrusive<T>(find_type(name));
}
/**
* 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
* @return The current value of the identifier.
*/
template<class T>
IntrusivePtr<T> find_val(std::string_view name)
{ return cast_intrusive<T>(find_val(name)); }
template <class T> IntrusivePtr<T> find_val(std::string_view name)
{
return cast_intrusive<T>(find_val(name));
}
/**
* 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
* @return The current value of the identifier.
*/
template<class T>
IntrusivePtr<T> find_const(std::string_view name)
{ return cast_intrusive<T>(find_const(name)); }
template <class T> IntrusivePtr<T> find_const(std::string_view name)
{
return cast_intrusive<T>(find_const(name));
}
/**
* 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 index_vec;
namespace detail {
namespace detail
{
void init_types();
} // namespace detail
} // namespace zeek::id
} // namespace detail
} // namespace zeek::id

824
src/IP.cc
View file

@ -2,18 +2,19 @@
#include "zeek/IP.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <netinet/in.h>
#include <sys/types.h>
#include "zeek/IPAddr.h"
#include "zeek/Reporter.h"
#include "zeek/Type.h"
#include "zeek/Val.h"
#include "zeek/Var.h"
#include "zeek/ZeekString.h"
#include "zeek/Reporter.h"
namespace zeek {
namespace zeek
{
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 )
{
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);
rv->Assign(0, opt->ip6o_type);
@ -54,251 +55,265 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
{
RecordValPtr rv;
switch ( type ) {
case IPPROTO_IPV6:
switch ( type )
{
static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr");
rv = make_intrusive<RecordVal>(ip6_hdr_type);
const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data;
rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000)>>20);
rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff);
rv->Assign(2, ntohs(ip6->ip6_plen));
rv->Assign(3, ip6->ip6_nxt);
rv->Assign(4, ip6->ip6_hlim);
rv->Assign(5, make_intrusive<AddrVal>(IPAddr(ip6->ip6_src)));
rv->Assign(6, make_intrusive<AddrVal>(IPAddr(ip6->ip6_dst)));
if ( ! chain )
chain = make_intrusive<VectorVal>(
id::find_type<VectorType>("ip6_ext_hdr_chain"));
rv->Assign(7, std::move(chain));
}
break;
case IPPROTO_HOPOPTS:
{
static auto ip6_hopopts_type = id::find_type<RecordType>("ip6_hopopts");
rv = make_intrusive<RecordVal>(ip6_hopopts_type);
const struct ip6_hbh* hbh = (const struct ip6_hbh*)data;
rv->Assign(0, hbh->ip6h_nxt);
rv->Assign(1, hbh->ip6h_len);
uint16_t off = 2 * sizeof(uint8_t);
rv->Assign(2, BuildOptionsVal(data + off, Length() - off));
}
break;
case IPPROTO_DSTOPTS:
{
static auto ip6_dstopts_type = id::find_type<RecordType>("ip6_dstopts");
rv = make_intrusive<RecordVal>(ip6_dstopts_type);
const struct ip6_dest* dst = (const struct ip6_dest*)data;
rv->Assign(0, dst->ip6d_nxt);
rv->Assign(1, dst->ip6d_len);
uint16_t off = 2 * sizeof(uint8_t);
rv->Assign(2, BuildOptionsVal(data + off, Length() - off));
}
break;
case IPPROTO_ROUTING:
{
static auto ip6_routing_type = id::find_type<RecordType>("ip6_routing");
rv = make_intrusive<RecordVal>(ip6_routing_type);
const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data;
rv->Assign(0, rt->ip6r_nxt);
rv->Assign(1, rt->ip6r_len);
rv->Assign(2, rt->ip6r_type);
rv->Assign(3, rt->ip6r_segleft);
uint16_t off = 4 * sizeof(uint8_t);
rv->Assign(4, new String(data + off, Length() - off, true));
}
break;
case IPPROTO_FRAGMENT:
{
static auto ip6_fragment_type = id::find_type<RecordType>("ip6_fragment");
rv = make_intrusive<RecordVal>(ip6_fragment_type);
const struct ip6_frag* frag = (const struct ip6_frag*)data;
rv->Assign(0, frag->ip6f_nxt);
rv->Assign(1, frag->ip6f_reserved);
rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8)>>3);
rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006)>>1);
rv->Assign(4, static_cast<bool>(ntohs(frag->ip6f_offlg) & 0x0001));
rv->Assign(5, ntohl(frag->ip6f_ident));
}
break;
case IPPROTO_AH:
{
static auto ip6_ah_type = id::find_type<RecordType>("ip6_ah");
rv = make_intrusive<RecordVal>(ip6_ah_type);
rv->Assign(0, ((ip6_ext*)data)->ip6e_nxt);
rv->Assign(1, ((ip6_ext*)data)->ip6e_len);
rv->Assign(2, ntohs(((uint16_t*)data)[1]));
rv->Assign(3, ntohl(((uint32_t*)data)[1]));
if ( Length() >= 12 )
{
// Sequence Number and ICV fields can only be extracted if
// Payload Len was non-zero for this header.
rv->Assign(4, ntohl(((uint32_t*)data)[2]));
uint16_t off = 3 * sizeof(uint32_t);
rv->Assign(5, new String(data + off, Length() - off, true));
}
}
break;
case IPPROTO_ESP:
{
static auto ip6_esp_type = id::find_type<RecordType>("ip6_esp");
rv = make_intrusive<RecordVal>(ip6_esp_type);
const uint32_t* esp = (const uint32_t*)data;
rv->Assign(0, ntohl(esp[0]));
rv->Assign(1, ntohl(esp[1]));
}
break;
case IPPROTO_MOBILITY:
{
static auto ip6_mob_type = id::find_type<RecordType>("ip6_mobility_hdr");
rv = make_intrusive<RecordVal>(ip6_mob_type);
const struct ip6_mobility* mob = (const struct ip6_mobility*) data;
rv->Assign(0, mob->ip6mob_payload);
rv->Assign(1, mob->ip6mob_len);
rv->Assign(2, mob->ip6mob_type);
rv->Assign(3, mob->ip6mob_rsv);
rv->Assign(4, ntohs(mob->ip6mob_chksum));
static auto ip6_mob_msg_type = id::find_type<RecordType>("ip6_mobility_msg");
auto msg = make_intrusive<RecordVal>(ip6_mob_msg_type);
msg->Assign(0, mob->ip6mob_type);
uint16_t off = sizeof(ip6_mobility);
const u_char* msg_data = data + off;
static auto ip6_mob_brr_type = id::find_type<RecordType>("ip6_mobility_brr");
static auto ip6_mob_hoti_type = id::find_type<RecordType>("ip6_mobility_hoti");
static auto ip6_mob_coti_type = id::find_type<RecordType>("ip6_mobility_coti");
static auto ip6_mob_hot_type = id::find_type<RecordType>("ip6_mobility_hot");
static auto ip6_mob_cot_type = id::find_type<RecordType>("ip6_mobility_cot");
static auto ip6_mob_bu_type = id::find_type<RecordType>("ip6_mobility_bu");
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");
switch ( mob->ip6mob_type ) {
case 0:
{
auto m = make_intrusive<RecordVal>(ip6_mob_brr_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
off += sizeof(uint16_t);
m->Assign(1, BuildOptionsVal(data + off, Length() - off));
msg->Assign(1, std::move(m));
}
case IPPROTO_IPV6:
{
static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr");
rv = make_intrusive<RecordVal>(ip6_hdr_type);
const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data;
rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000) >> 20);
rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff);
rv->Assign(2, ntohs(ip6->ip6_plen));
rv->Assign(3, ip6->ip6_nxt);
rv->Assign(4, ip6->ip6_hlim);
rv->Assign(5, make_intrusive<AddrVal>(IPAddr(ip6->ip6_src)));
rv->Assign(6, make_intrusive<AddrVal>(IPAddr(ip6->ip6_dst)));
if ( ! chain )
chain =
make_intrusive<VectorVal>(id::find_type<VectorType>("ip6_ext_hdr_chain"));
rv->Assign(7, std::move(chain));
}
break;
case 1:
{
auto m = make_intrusive<RecordVal>(ip6_mob_hoti_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t)))));
off += sizeof(uint16_t) + sizeof(uint64_t);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(2, std::move(m));
case IPPROTO_HOPOPTS:
{
static auto ip6_hopopts_type = id::find_type<RecordType>("ip6_hopopts");
rv = make_intrusive<RecordVal>(ip6_hopopts_type);
const struct ip6_hbh* hbh = (const struct ip6_hbh*)data;
rv->Assign(0, hbh->ip6h_nxt);
rv->Assign(1, hbh->ip6h_len);
uint16_t off = 2 * sizeof(uint8_t);
rv->Assign(2, BuildOptionsVal(data + off, Length() - off));
}
break;
}
case 2:
{
auto m = make_intrusive<RecordVal>(ip6_mob_coti_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t)))));
off += sizeof(uint16_t) + sizeof(uint64_t);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(3, std::move(m));
case IPPROTO_DSTOPTS:
{
static auto ip6_dstopts_type = id::find_type<RecordType>("ip6_dstopts");
rv = make_intrusive<RecordVal>(ip6_dstopts_type);
const struct ip6_dest* dst = (const struct ip6_dest*)data;
rv->Assign(0, dst->ip6d_nxt);
rv->Assign(1, dst->ip6d_len);
uint16_t off = 2 * sizeof(uint8_t);
rv->Assign(2, BuildOptionsVal(data + off, Length() - off));
}
break;
}
case 3:
{
auto m = make_intrusive<RecordVal>(ip6_mob_hot_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
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)))));
off += sizeof(uint16_t) + 2 * sizeof(uint64_t);
m->Assign(3, BuildOptionsVal(data + off, Length() - off));
msg->Assign(4, std::move(m));
case IPPROTO_ROUTING:
{
static auto ip6_routing_type = id::find_type<RecordType>("ip6_routing");
rv = make_intrusive<RecordVal>(ip6_routing_type);
const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data;
rv->Assign(0, rt->ip6r_nxt);
rv->Assign(1, rt->ip6r_len);
rv->Assign(2, rt->ip6r_type);
rv->Assign(3, rt->ip6r_segleft);
uint16_t off = 4 * sizeof(uint8_t);
rv->Assign(4, new String(data + off, Length() - off, true));
}
break;
}
case 4:
{
auto m = make_intrusive<RecordVal>(ip6_mob_cot_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
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)))));
off += sizeof(uint16_t) + 2 * sizeof(uint64_t);
m->Assign(3, BuildOptionsVal(data + off, Length() - off));
msg->Assign(5, std::move(m));
case IPPROTO_FRAGMENT:
{
static auto ip6_fragment_type = id::find_type<RecordType>("ip6_fragment");
rv = make_intrusive<RecordVal>(ip6_fragment_type);
const struct ip6_frag* frag = (const struct ip6_frag*)data;
rv->Assign(0, frag->ip6f_nxt);
rv->Assign(1, frag->ip6f_reserved);
rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8) >> 3);
rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006) >> 1);
rv->Assign(4, static_cast<bool>(ntohs(frag->ip6f_offlg) & 0x0001));
rv->Assign(5, ntohl(frag->ip6f_ident));
}
break;
}
case 5:
{
auto m = make_intrusive<RecordVal>(ip6_mob_bu_type);
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(2, static_cast<bool>(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);
m->Assign(6, BuildOptionsVal(data + off, Length() - off));
msg->Assign(6, std::move(m));
break;
}
case IPPROTO_AH:
{
static auto ip6_ah_type = id::find_type<RecordType>("ip6_ah");
rv = make_intrusive<RecordVal>(ip6_ah_type);
rv->Assign(0, ((ip6_ext*)data)->ip6e_nxt);
rv->Assign(1, ((ip6_ext*)data)->ip6e_len);
rv->Assign(2, ntohs(((uint16_t*)data)[1]));
rv->Assign(3, ntohl(((uint32_t*)data)[1]));
case 6:
{
auto m = make_intrusive<RecordVal>(ip6_mob_back_type);
m->Assign(0, *((uint8_t*)msg_data));
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(3, ntohs(*((uint16_t*)(msg_data + 2*sizeof(uint16_t)))));
off += 3 * sizeof(uint16_t);
m->Assign(4, BuildOptionsVal(data + off, Length() - off));
msg->Assign(7, std::move(m));
if ( Length() >= 12 )
{
// Sequence Number and ICV fields can only be extracted if
// Payload Len was non-zero for this header.
rv->Assign(4, ntohl(((uint32_t*)data)[2]));
uint16_t off = 3 * sizeof(uint32_t);
rv->Assign(5, new String(data + off, Length() - off, true));
}
}
break;
}
case 7:
{
auto m = make_intrusive<RecordVal>(ip6_mob_be_type);
m->Assign(0, *((uint8_t*)msg_data));
const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16_t));
m->Assign(1, make_intrusive<AddrVal>(IPAddr(*hoa)));
off += sizeof(uint16_t) + sizeof(in6_addr);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(8, std::move(m));
case IPPROTO_ESP:
{
static auto ip6_esp_type = id::find_type<RecordType>("ip6_esp");
rv = make_intrusive<RecordVal>(ip6_esp_type);
const uint32_t* esp = (const uint32_t*)data;
rv->Assign(0, ntohl(esp[0]));
rv->Assign(1, ntohl(esp[1]));
}
break;
case IPPROTO_MOBILITY:
{
static auto ip6_mob_type = id::find_type<RecordType>("ip6_mobility_hdr");
rv = make_intrusive<RecordVal>(ip6_mob_type);
const struct ip6_mobility* mob = (const struct ip6_mobility*)data;
rv->Assign(0, mob->ip6mob_payload);
rv->Assign(1, mob->ip6mob_len);
rv->Assign(2, mob->ip6mob_type);
rv->Assign(3, mob->ip6mob_rsv);
rv->Assign(4, ntohs(mob->ip6mob_chksum));
static auto ip6_mob_msg_type = id::find_type<RecordType>("ip6_mobility_msg");
auto msg = make_intrusive<RecordVal>(ip6_mob_msg_type);
msg->Assign(0, mob->ip6mob_type);
uint16_t off = sizeof(ip6_mobility);
const u_char* msg_data = data + off;
static auto ip6_mob_brr_type = id::find_type<RecordType>("ip6_mobility_brr");
static auto ip6_mob_hoti_type = id::find_type<RecordType>("ip6_mobility_hoti");
static auto ip6_mob_coti_type = id::find_type<RecordType>("ip6_mobility_coti");
static auto ip6_mob_hot_type = id::find_type<RecordType>("ip6_mobility_hot");
static auto ip6_mob_cot_type = id::find_type<RecordType>("ip6_mobility_cot");
static auto ip6_mob_bu_type = id::find_type<RecordType>("ip6_mobility_bu");
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");
switch ( mob->ip6mob_type )
{
case 0:
{
auto m = make_intrusive<RecordVal>(ip6_mob_brr_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
off += sizeof(uint16_t);
m->Assign(1, BuildOptionsVal(data + off, Length() - off));
msg->Assign(1, std::move(m));
}
break;
case 1:
{
auto m = make_intrusive<RecordVal>(ip6_mob_hoti_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t)))));
off += sizeof(uint16_t) + sizeof(uint64_t);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(2, std::move(m));
break;
}
case 2:
{
auto m = make_intrusive<RecordVal>(ip6_mob_coti_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t)))));
off += sizeof(uint16_t) + sizeof(uint64_t);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(3, std::move(m));
break;
}
case 3:
{
auto m = make_intrusive<RecordVal>(ip6_mob_hot_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
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)))));
off += sizeof(uint16_t) + 2 * sizeof(uint64_t);
m->Assign(3, BuildOptionsVal(data + off, Length() - off));
msg->Assign(4, std::move(m));
break;
}
case 4:
{
auto m = make_intrusive<RecordVal>(ip6_mob_cot_type);
m->Assign(0, ntohs(*((uint16_t*)msg_data)));
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)))));
off += sizeof(uint16_t) + 2 * sizeof(uint64_t);
m->Assign(3, BuildOptionsVal(data + off, Length() - off));
msg->Assign(5, std::move(m));
break;
}
case 5:
{
auto m = make_intrusive<RecordVal>(ip6_mob_bu_type);
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(2, static_cast<bool>(
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);
m->Assign(6, BuildOptionsVal(data + off, Length() - off));
msg->Assign(6, std::move(m));
break;
}
case 6:
{
auto m = make_intrusive<RecordVal>(ip6_mob_back_type);
m->Assign(0, *((uint8_t*)msg_data));
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(3, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t)))));
off += 3 * sizeof(uint16_t);
m->Assign(4, BuildOptionsVal(data + off, Length() - off));
msg->Assign(7, std::move(m));
break;
}
case 7:
{
auto m = make_intrusive<RecordVal>(ip6_mob_be_type);
m->Assign(0, *((uint8_t*)msg_data));
const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16_t));
m->Assign(1, make_intrusive<AddrVal>(IPAddr(*hoa)));
off += sizeof(uint16_t) + sizeof(in6_addr);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(8, std::move(m));
break;
}
default:
reporter->Weird("unknown_mobility_type", util::fmt("%d", mob->ip6mob_type));
break;
}
rv->Assign(5, std::move(msg));
}
break;
}
default:
reporter->Weird("unknown_mobility_type", util::fmt("%d", mob->ip6mob_type));
break;
}
rv->Assign(5, std::move(msg));
}
break;
default:
break;
}
return rv;
}
RecordValPtr IPv6_Hdr::ToVal() const
{ return ToVal(nullptr); }
{
return ToVal(nullptr);
}
IPAddr IP_Hdr::IPHeaderSrcAddr() const
{
@ -366,104 +381,106 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
const u_char* data = Payload();
int proto = NextProto();
switch ( proto ) {
case IPPROTO_TCP:
switch ( proto )
{
const struct tcphdr* tp = (const struct tcphdr*) data;
auto tcp_hdr = make_intrusive<RecordVal>(tcp_hdr_type);
case IPPROTO_TCP:
{
const struct tcphdr* tp = (const struct tcphdr*)data;
auto tcp_hdr = make_intrusive<RecordVal>(tcp_hdr_type);
int tcp_hdr_len = tp->th_off * 4;
int data_len = PayloadLen() - tcp_hdr_len;
int tcp_hdr_len = tp->th_off * 4;
int data_len = PayloadLen() - tcp_hdr_len;
tcp_hdr->Assign(0, val_mgr->Port(ntohs(tp->th_sport), TRANSPORT_TCP));
tcp_hdr->Assign(1, val_mgr->Port(ntohs(tp->th_dport), TRANSPORT_TCP));
tcp_hdr->Assign(2, ntohl(tp->th_seq));
tcp_hdr->Assign(3, ntohl(tp->th_ack));
tcp_hdr->Assign(4, tcp_hdr_len);
tcp_hdr->Assign(5, data_len);
tcp_hdr->Assign(6, tp->th_x2);
tcp_hdr->Assign(7, tp->th_flags);
tcp_hdr->Assign(8, ntohs(tp->th_win));
tcp_hdr->Assign(0, val_mgr->Port(ntohs(tp->th_sport), TRANSPORT_TCP));
tcp_hdr->Assign(1, val_mgr->Port(ntohs(tp->th_dport), TRANSPORT_TCP));
tcp_hdr->Assign(2, ntohl(tp->th_seq));
tcp_hdr->Assign(3, ntohl(tp->th_ack));
tcp_hdr->Assign(4, tcp_hdr_len);
tcp_hdr->Assign(5, data_len);
tcp_hdr->Assign(6, tp->th_x2);
tcp_hdr->Assign(7, tp->th_flags);
tcp_hdr->Assign(8, ntohs(tp->th_win));
pkt_hdr->Assign(sindex + 2, std::move(tcp_hdr));
break;
pkt_hdr->Assign(sindex + 2, std::move(tcp_hdr));
break;
}
case IPPROTO_UDP:
{
const struct udphdr* up = (const struct udphdr*)data;
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(1, val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP));
udp_hdr->Assign(2, ntohs(up->uh_ulen));
pkt_hdr->Assign(sindex + 3, std::move(udp_hdr));
break;
}
case IPPROTO_ICMP:
{
const struct icmp* icmpp = (const struct icmp*)data;
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, icmpp->icmp_type);
pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr));
break;
}
case IPPROTO_ICMPV6:
{
const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*)data;
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, icmpp->icmp6_type);
pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr));
break;
}
default:
{
// This is not a protocol we understand.
break;
}
}
case IPPROTO_UDP:
{
const struct udphdr* up = (const struct udphdr*) data;
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(1, val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP));
udp_hdr->Assign(2, ntohs(up->uh_ulen));
pkt_hdr->Assign(sindex + 3, std::move(udp_hdr));
break;
}
case IPPROTO_ICMP:
{
const struct icmp* icmpp = (const struct icmp *) data;
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, icmpp->icmp_type);
pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr));
break;
}
case IPPROTO_ICMPV6:
{
const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*) data;
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, icmpp->icmp6_type);
pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr));
break;
}
default:
{
// This is not a protocol we understand.
break;
}
}
return pkt_hdr;
}
static inline bool isIPv6ExtHeader(uint8_t type)
{
switch (type) {
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
case IPPROTO_FRAGMENT:
case IPPROTO_AH:
case IPPROTO_ESP:
case IPPROTO_MOBILITY:
return true;
default:
return false;
}
switch ( type )
{
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
case IPPROTO_FRAGMENT:
case IPPROTO_AH:
case IPPROTO_ESP:
case IPPROTO_MOBILITY:
return true;
default:
return false;
}
}
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 finalDst;
}
void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len,
bool set_next, uint16_t next)
void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len, bool set_next, uint16_t next)
{
length = 0;
uint8_t current_type, next_type;
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) )
{
@ -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.
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.
if ( current_type == IPPROTO_DSTOPTS )
ProcessDstOpts((const struct ip6_dest*) hdrs, cur_len);
ProcessDstOpts((const struct ip6_dest*)hdrs, cur_len);
hdrs += cur_len;
length += cur_len;
total_len -= cur_len;
} while ( current_type != IPPROTO_FRAGMENT &&
current_type != IPPROTO_ESP &&
current_type != IPPROTO_MOBILITY &&
isIPv6ExtHeader(next_type) );
} while ( current_type != IPPROTO_FRAGMENT && current_type != IPPROTO_ESP &&
current_type != IPPROTO_MOBILITY && isIPv6ExtHeader(next_type) );
}
bool IPv6_Hdr_Chain::IsFragment() const
@ -525,7 +540,7 @@ bool IPv6_Hdr_Chain::IsFragment() const
return false;
}
return chain[chain.size()-1]->Type() == IPPROTO_FRAGMENT;
return chain[chain.size() - 1]->Type() == IPPROTO_FRAGMENT;
}
IPAddr IPv6_Hdr_Chain::SrcAddr() const
@ -567,39 +582,40 @@ 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.
const in6_addr* addr = (const in6_addr*)(((const u_char*)r) + len - 16);
switch ( r->ip6r_type ) {
case 0: // Defined by RFC 2460, deprecated by RFC 5095
switch ( r->ip6r_type )
{
if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 )
{
if ( r->ip6r_len % 2 == 0 )
finalDst = new IPAddr(*addr);
else
reporter->Weird(SrcAddr(), DstAddr(), "odd_routing0_len");
}
case 0: // Defined by RFC 2460, deprecated by RFC 5095
{
if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 )
{
if ( r->ip6r_len % 2 == 0 )
finalDst = new IPAddr(*addr);
else
reporter->Weird(SrcAddr(), DstAddr(), "odd_routing0_len");
}
// Always raise a weird since this type is deprecated.
reporter->Weird(SrcAddr(), DstAddr(), "routing0_hdr");
// Always raise a weird since this type is deprecated.
reporter->Weird(SrcAddr(), DstAddr(), "routing0_hdr");
}
break;
case 2: // Defined by Mobile IPv6 RFC 6275.
{
if ( r->ip6r_segleft > 0 )
{
if ( r->ip6r_len == 2 )
finalDst = new IPAddr(*addr);
else
reporter->Weird(SrcAddr(), DstAddr(), "bad_routing2_len");
}
}
break;
default:
reporter->Weird(SrcAddr(), DstAddr(), "unknown_routing_type",
util::fmt("%d", r->ip6r_type));
break;
}
break;
case 2: // Defined by Mobile IPv6 RFC 6275.
{
if ( r->ip6r_segleft > 0 )
{
if ( r->ip6r_len == 2 )
finalDst = new IPAddr(*addr);
else
reporter->Weird(SrcAddr(), DstAddr(), "bad_routing2_len");
}
}
break;
default:
reporter->Weird(SrcAddr(), DstAddr(), "unknown_routing_type",
util::fmt("%d", r->ip6r_type));
break;
}
}
void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
@ -610,53 +626,56 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
// https://datatracker.ietf.org/doc/html/rfc8200#section-4.6
assert(len >= 2);
const u_char* data = (const u_char*) d;
const u_char* data = (const u_char*)d;
len -= 2 * sizeof(uint8_t);
data += 2* sizeof(uint8_t);
data += 2 * sizeof(uint8_t);
while ( len > 0 )
{
const struct ip6_opt* opt = (const struct ip6_opt*) data;
switch ( opt->ip6o_type ) {
case 0:
// If option type is zero, it's a Pad0 and can be just a single
// byte in width. Skip over it.
data += sizeof(uint8_t);
len -= sizeof(uint8_t);
break;
default:
const struct ip6_opt* opt = (const struct ip6_opt*)data;
switch ( opt->ip6o_type )
{
// Double-check that the len can hold the whole option structure.
// Otherwise we get a buffer-overflow when we check the option_len.
// Also check that it holds everything for the option itself.
if ( len < sizeof(struct ip6_opt) ||
len < sizeof(struct ip6_opt) + opt->ip6o_len )
{
reporter->Weird(SrcAddr(), DstAddr(), "bad_ipv6_dest_opt_len");
len = 0;
case 0:
// If option type is zero, it's a Pad0 and can be just a single
// byte in width. Skip over it.
data += sizeof(uint8_t);
len -= sizeof(uint8_t);
break;
}
if ( opt->ip6o_type == 201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
{
if ( opt->ip6o_len == sizeof(struct in6_addr) )
default:
{
if ( homeAddr )
reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts");
else
homeAddr = new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt))));
}
else
reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len");
}
// Double-check that the len can hold the whole option structure.
// Otherwise we get a buffer-overflow when we check the option_len.
// Also check that it holds everything for the option itself.
if ( len < sizeof(struct ip6_opt) ||
len < sizeof(struct ip6_opt) + opt->ip6o_len )
{
reporter->Weird(SrcAddr(), DstAddr(), "bad_ipv6_dest_opt_len");
len = 0;
break;
}
data += sizeof(struct ip6_opt) + opt->ip6o_len;
len -= sizeof(struct ip6_opt) + opt->ip6o_len;
if ( opt->ip6o_type ==
201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
{
if ( opt->ip6o_len == sizeof(struct in6_addr) )
{
if ( homeAddr )
reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts");
else
homeAddr =
new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt))));
}
else
reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len");
}
data += sizeof(struct ip6_opt) + opt->ip6o_len;
len -= sizeof(struct ip6_opt) + opt->ip6o_len;
}
break;
}
break;
}
}
}
VectorValPtr IPv6_Hdr_Chain::ToVal() const
{
@ -677,32 +696,33 @@ VectorValPtr IPv6_Hdr_Chain::ToVal() const
uint8_t type = chain[i]->Type();
ext_hdr->Assign(0, type);
switch (type) {
case IPPROTO_HOPOPTS:
ext_hdr->Assign(1, std::move(v));
break;
case IPPROTO_DSTOPTS:
ext_hdr->Assign(2, std::move(v));
break;
case IPPROTO_ROUTING:
ext_hdr->Assign(3, std::move(v));
break;
case IPPROTO_FRAGMENT:
ext_hdr->Assign(4, std::move(v));
break;
case IPPROTO_AH:
ext_hdr->Assign(5, std::move(v));
break;
case IPPROTO_ESP:
ext_hdr->Assign(6, std::move(v));
break;
case IPPROTO_MOBILITY:
ext_hdr->Assign(7, std::move(v));
break;
default:
reporter->InternalWarning("IPv6_Hdr_Chain bad header %d", type);
continue;
}
switch ( type )
{
case IPPROTO_HOPOPTS:
ext_hdr->Assign(1, std::move(v));
break;
case IPPROTO_DSTOPTS:
ext_hdr->Assign(2, std::move(v));
break;
case IPPROTO_ROUTING:
ext_hdr->Assign(3, std::move(v));
break;
case IPPROTO_FRAGMENT:
ext_hdr->Assign(4, std::move(v));
break;
case IPPROTO_AH:
ext_hdr->Assign(5, std::move(v));
break;
case IPPROTO_ESP:
ext_hdr->Assign(6, std::move(v));
break;
case IPPROTO_MOBILITY:
ext_hdr->Assign(7, std::move(v));
break;
default:
reporter->InternalWarning("IPv6_Hdr_Chain bad header %d", type);
continue;
}
rval->Assign(rval->Size(), std::move(ext_hdr));
}
@ -717,7 +737,7 @@ IP_Hdr* IP_Hdr::Copy() const
if ( ip4 )
{
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());
@ -756,4 +776,4 @@ IPv6_Hdr_Chain* IPv6_Hdr_Chain::Copy(const ip6_hdr* new_hdr) const
return rval;
}
} // namespace zeek
} // namespace zeek

225
src/IP.h
View file

@ -2,11 +2,11 @@
#pragma once
#include "zeek/zeek-config.h"
#include <sys/types.h> // for u_char
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h> // for u_char
#include "zeek/zeek-config.h"
#ifdef HAVE_NETINET_IP6_H
#include <netinet/ip6.h>
@ -16,7 +16,8 @@
#include "zeek/IntrusivePtr.h"
namespace zeek {
namespace zeek
{
class IPAddr;
class RecordVal;
@ -24,54 +25,60 @@ class VectorVal;
using RecordValPtr = IntrusivePtr<RecordVal>;
using VectorValPtr = IntrusivePtr<VectorVal>;
namespace detail { class FragReassembler; }
namespace detail
{
class FragReassembler;
}
#ifndef IPPROTO_MOBILITY
#define IPPROTO_MOBILITY 135
#endif
struct ip6_mobility {
struct ip6_mobility
{
uint8_t ip6mob_payload;
uint8_t ip6mob_len;
uint8_t ip6mob_type;
uint8_t ip6mob_rsv;
uint16_t ip6mob_chksum;
};
};
/**
* Base class for IPv6 header/extensions.
*/
class IPv6_Hdr {
class IPv6_Hdr
{
public:
/**
* 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.
*/
void ChangeNext(uint8_t next_type)
{
switch ( type ) {
case IPPROTO_IPV6:
((ip6_hdr*)data)->ip6_nxt = next_type;
break;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_FRAGMENT:
case IPPROTO_AH:
case IPPROTO_MOBILITY:
((ip6_ext*)data)->ip6e_nxt = next_type;
break;
case IPPROTO_ESP:
default:
break;
}
switch ( type )
{
case IPPROTO_IPV6:
((ip6_hdr*)data)->ip6_nxt = next_type;
break;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_FRAGMENT:
case IPPROTO_AH:
case IPPROTO_MOBILITY:
((ip6_ext*)data)->ip6e_nxt = next_type;
break;
case IPPROTO_ESP:
default:
break;
}
}
~IPv6_Hdr() {}
~IPv6_Hdr() { }
/**
* Returns the assigned IPv6 extension header type number of the header
@ -79,20 +86,21 @@ public:
*/
uint8_t NextHdr() const
{
switch ( type ) {
case IPPROTO_IPV6:
return ((ip6_hdr*)data)->ip6_nxt;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_FRAGMENT:
case IPPROTO_AH:
case IPPROTO_MOBILITY:
return ((ip6_ext*)data)->ip6e_nxt;
case IPPROTO_ESP:
default:
return IPPROTO_NONE;
}
switch ( type )
{
case IPPROTO_IPV6:
return ((ip6_hdr*)data)->ip6_nxt;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_FRAGMENT:
case IPPROTO_AH:
case IPPROTO_MOBILITY:
return ((ip6_ext*)data)->ip6e_nxt;
case IPPROTO_ESP:
default:
return IPPROTO_NONE;
}
}
/**
@ -100,23 +108,24 @@ public:
*/
uint16_t Length() const
{
switch ( type ) {
case IPPROTO_IPV6:
return 40;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_MOBILITY:
return 8 + 8 * ((ip6_ext*)data)->ip6e_len;
case IPPROTO_FRAGMENT:
return 8;
case IPPROTO_AH:
return 8 + 4 * ((ip6_ext*)data)->ip6e_len;
case IPPROTO_ESP:
return 8; //encrypted payload begins after 8 bytes
default:
return 0;
}
switch ( type )
{
case IPPROTO_IPV6:
return 40;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_MOBILITY:
return 8 + 8 * ((ip6_ext*)data)->ip6e_len;
case IPPROTO_FRAGMENT:
return 8;
case IPPROTO_AH:
return 8 + 4 * ((ip6_ext*)data)->ip6e_len;
case IPPROTO_ESP:
return 8; // encrypted payload begins after 8 bytes
default:
return 0;
}
}
/**
@ -138,15 +147,15 @@ public:
protected:
uint8_t type;
const u_char* data;
};
};
class IPv6_Hdr_Chain {
class IPv6_Hdr_Chain
{
public:
/**
* Initializes the header chain from an IPv6 header structure.
*/
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, int len)
{ Init(ip6, len, false); }
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, int len) { Init(ip6, len, false); }
~IPv6_Hdr_Chain();
@ -180,29 +189,28 @@ public:
* Returns pointer to fragment header structure if the chain contains one.
*/
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
* relative to the start of the Fragmentable Part of the original packet.
*/
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.
*/
uint32_t ID() const
{ return IsFragment() ? ntohl(GetFragHdr()->ip6f_ident) : 0; }
uint32_t ID() const { return IsFragment() ? ntohl(GetFragHdr()->ip6f_ident) : 0; }
/**
* If the header chain is a fragment, returns the M (more fragments) flag.
*/
int MF() const
{ return IsFragment() ?
(ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; }
int MF() const { return IsFragment() ? (ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; }
/**
* 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.
*/
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
* length, possibly setting the first next protocol pointer field that
* points to a fragment header.
*/
void Init(const struct ip6_hdr* ip6, int total_len, bool set_next,
uint16_t next = 0);
void Init(const struct ip6_hdr* ip6, int total_len, bool set_next, uint16_t next = 0);
/**
* Process a routing header and allocate/remember the final destination
@ -275,13 +284,14 @@ protected:
* non-zero segments left.
*/
IPAddr* finalDst = nullptr;
};
};
/**
* A class that wraps either an IPv4 or IPv6 packet and abstracts methods
* for inquiring about common features between the two.
*/
class IP_Hdr {
class IP_Hdr
{
public:
/**
* 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 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)
{
}
@ -307,10 +317,10 @@ public:
* @param c an already-constructed header chain to take ownership of.
* @param reassembled whether this header is for a reassembled packet.
*/
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, int len,
const IPv6_Hdr_Chain* c = nullptr, bool reassembled=false)
: ip6(arg_ip6), ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6, len)),
del(arg_del), reassembled(reassembled)
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, int len, const IPv6_Hdr_Chain* c = nullptr,
bool reassembled = false)
: ip6(arg_ip6), ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6, len)), del(arg_del),
reassembled(reassembled)
{
}
@ -330,20 +340,20 @@ public:
if ( del )
{
delete [] (struct ip*) ip4;
delete [] (struct ip6_hdr*) ip6;
delete[](struct ip*) ip4;
delete[](struct ip6_hdr*) ip6;
}
}
/**
* If an IPv4 packet is wrapped, return a pointer to it, else null.
*/
const struct ip* IP4_Hdr() const { return ip4; }
const struct ip* IP4_Hdr() const { return ip4; }
/**
* If an IPv6 packet is wrapped, return a pointer to it, else null.
*/
const struct ip6_hdr* IP6_Hdr() const { return ip6; }
const struct ip6_hdr* IP6_Hdr() const { return ip6; }
/**
* Returns the source address held in the IP header.
@ -377,9 +387,9 @@ public:
const u_char* Payload() const
{
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 )
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;
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).
*/
uint16_t HdrLen() const
{ return ip4 ? ip4->ip_hl * 4 : ip6_hdrs->TotalLength(); }
uint16_t HdrLen() const { return ip4 ? ip4->ip_hl * 4 : ip6_hdrs->TotalLength(); }
/**
* 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();
if ( i > 0 )
return (*ip6_hdrs)[i-1]->Type();
return (*ip6_hdrs)[i - 1]->Type();
return IPPROTO_NONE;
}
@ -452,7 +461,7 @@ public:
size_t i = ip6_hdrs->Size();
if ( i > 0 )
return (*ip6_hdrs)[i-1]->NextHdr();
return (*ip6_hdrs)[i - 1]->NextHdr();
return IPPROTO_NONE;
}
@ -460,54 +469,50 @@ public:
/**
* Returns the IPv4 Time to Live or IPv6 Hop Limit field.
*/
unsigned char TTL() const
{ return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
unsigned char TTL() const { return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
/**
* Returns whether the IP header indicates this packet is a fragment.
*/
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
* packet in bytes.
*/
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.
*/
uint32_t ID() const
{ return ip4 ? ntohs(ip4->ip_id) : ip6_hdrs->ID(); }
uint32_t ID() const { return ip4 ? ntohs(ip4->ip_id) : ip6_hdrs->ID(); }
/**
* Returns whether a fragment packet's "More Fragments" field is set.
*/
int MF() const
{ return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : ip6_hdrs->MF(); }
int MF() const { return ip4 ? (ntohs(ip4->ip_off) & 0x2000) != 0 : ip6_hdrs->MF(); }
/**
* Returns whether a fragment packet's "Don't Fragment" field is set.
* Note that IPv6 has no such field.
*/
int DF() const
{ return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; }
int DF() const { 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.
*/
uint32_t FlowLabel() const
{ return ip4 ? 0 : (ntohl(ip6->ip6_flow) & 0x000fffff); }
uint32_t FlowLabel() const { return ip4 ? 0 : (ntohl(ip6->ip6_flow) & 0x000fffff); }
/**
* Returns number of IP headers in packet (includes IPv6 extension headers).
*/
size_t NumHeaders() const
{ return ip4 ? 1 : ip6_hdrs->Size(); }
size_t NumHeaders() const { return ip4 ? 1 : ip6_hdrs->Size(); }
/**
* Returns an ip_hdr or ip6_hdr_chain RecordVal.
@ -534,6 +539,6 @@ private:
const IPv6_Hdr_Chain* ip6_hdrs = nullptr;
bool del = 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.
#include "zeek/IPAddr.h"
#include <cstdlib>
#include <string>
#include <vector>
#include "zeek/IPAddr.h"
#include "zeek/Reporter.h"
#include "zeek/ZeekString.h"
#include "zeek/Conn.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/bro_inet_ntop.h"
namespace zeek {
namespace zeek
{
const IPAddr IPAddr::v4_unspecified = IPAddr(in4_addr{});
const IPAddr IPAddr::v6_unspecified = IPAddr();
namespace detail {
namespace detail
{
ConnKey::ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port,
uint16_t dst_port, TransportProto t, bool one_way)
ConnKey::ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, uint16_t dst_port,
TransportProto t, bool one_way)
: 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>
// followed by the other.
if ( one_way ||
addr_port_canon_lt(src, src_port, dst, dst_port)
)
if ( one_way || addr_port_canon_lt(src, src_port, dst, dst_port) )
{
ip1 = src.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(id.src_addr, id.dst_addr, id.src_port, id.dst_port,
id.proto, id.is_one_way)
: ConnKey(id.src_addr, id.dst_addr, id.src_port, id.dst_port, id.proto, id.is_one_way)
{
}
@ -64,7 +64,7 @@ ConnKey& ConnKey::operator=(const ConnKey& rhs)
return *this;
}
} // namespace detail
} // namespace detail
IPAddr::IPAddr(const String& s)
{
@ -81,7 +81,7 @@ static inline uint32_t bit_mask32(int bottom_bits)
if ( bottom_bits >= 32 )
return 0xffffffff;
return (((uint32_t) 1) << bottom_bits) - 1;
return (((uint32_t)1) << bottom_bits) - 1;
}
void IPAddr::Mask(int top_bits_to_keep)
@ -92,12 +92,11 @@ void IPAddr::Mask(int top_bits_to_keep)
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);
if ( res.quot < 4 )
mask_bits[res.quot] =
htonl(mask_bits[res.quot] & ~bit_mask32(32 - res.rem));
mask_bits[res.quot] = htonl(mask_bits[res.quot] & ~bit_mask32(32 - res.rem));
for ( unsigned int i = res.quot + 1; i < 4; ++i )
mask_bits[i] = 0;
@ -116,7 +115,7 @@ void IPAddr::ReverseMask(int top_bits_to_chop)
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);
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.
int a[4];
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 )
return false;
@ -200,15 +199,14 @@ std::string IPAddr::AsHexString() const
if ( GetFamily() == IPv4 )
{
uint32_t* p = (uint32_t*) &in6.s6_addr[12];
snprintf(buf, sizeof(buf), "%08x", (uint32_t) ntohl(*p));
uint32_t* p = (uint32_t*)&in6.s6_addr[12];
snprintf(buf, sizeof(buf), "%08x", (uint32_t)ntohl(*p));
}
else
{
uint32_t* p = (uint32_t*) in6.s6_addr;
snprintf(buf, sizeof(buf), "%08x%08x%08x%08x",
(uint32_t) ntohl(p[0]), (uint32_t) ntohl(p[1]),
(uint32_t) ntohl(p[2]), (uint32_t) ntohl(p[3]));
uint32_t* p = (uint32_t*)in6.s6_addr;
snprintf(buf, sizeof(buf), "%08x%08x%08x%08x", (uint32_t)ntohl(p[0]), (uint32_t)ntohl(p[1]),
(uint32_t)ntohl(p[2]), (uint32_t)ntohl(p[3]));
}
return buf;
@ -219,7 +217,7 @@ std::string IPAddr::PtrName() const
if ( GetFamily() == IPv4 )
{
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 a3 = (a >> 24) & 0xff;
uint32_t a2 = (a >> 16) & 0xff;
@ -232,15 +230,15 @@ std::string IPAddr::PtrName() const
{
static const char hex_digit[] = "0123456789abcdef";
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 )
{
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, 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)
: prefix(in4), length(96 + length)
IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length) : prefix(in4), length(96 + length)
{
if ( length > 32 )
{
@ -260,8 +257,7 @@ IPPrefix::IPPrefix(const in4_addr& in4, uint8_t length)
prefix.Mask(this->length);
}
IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length)
: prefix(in6), length(length)
IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) : prefix(in6), length(length)
{
if ( length > 128 )
{
@ -289,8 +285,7 @@ bool IPAddr::CheckPrefixLength(uint8_t length, bool len_is_v6_relative) const
return true;
}
IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length, bool len_is_v6_relative)
: prefix(addr)
IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length, bool len_is_v6_relative) : prefix(addr)
{
if ( prefix.CheckPrefixLength(length, len_is_v6_relative) )
{
@ -318,15 +313,16 @@ std::string IPPrefix::AsString() const
else
modp_uitoa10(length, l);
return prefix.AsString() +"/" + l;
return prefix.AsString() + "/" + l;
}
std::unique_ptr<detail::HashKey> IPPrefix::MakeHashKey() const
{
struct {
struct
{
in6_addr ip;
uint32_t len;
} key;
} key;
key.ip = prefix.in6;
key.len = Length();
@ -359,4 +355,4 @@ bool IPPrefix::ConvertString(const char* text, IPPrefix* result)
return true;
}
} // namespace zeek
} // namespace zeek

View file

@ -2,36 +2,39 @@
#pragma once
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include <string>
#include <memory>
#include <string>
#include "zeek/threading/SerialTypes.h"
using in4_addr = in_addr;
namespace zeek {
namespace zeek
{
class String;
struct ConnTuple;
namespace detail {
namespace detail
{
class HashKey;
struct ConnKey {
struct ConnKey
{
in6_addr ip1;
in6_addr ip2;
uint16_t port1;
uint16_t port2;
TransportProto transport;
ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port,
uint16_t dst_port, TransportProto t, bool one_way);
ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, uint16_t dst_port,
TransportProto t, bool one_way);
ConnKey(const ConnTuple& conn);
ConnKey(const ConnKey& rhs) { *this = rhs; }
ConnKey(const ConnKey& rhs) { *this = rhs; }
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; }
@ -41,16 +44,17 @@ struct ConnKey {
bool operator>(const ConnKey& rhs) const { return memcmp(this, &rhs, sizeof(ConnKey)) > 0; }
ConnKey& operator=(const ConnKey& rhs);
};
};
using ConnIDKey [[deprecated("Remove in v5.1. Use zeek::detail::ConnKey.")]] = ConnKey;
} // namespace detail
} // namespace detail
/**
* Class storing both IPv4 and IPv6 addresses.
*/
class IPAddr {
class IPAddr
{
public:
/**
* Address family.
@ -60,15 +64,16 @@ public:
/**
* Byte order.
*/
enum ByteOrder { Host, Network };
enum ByteOrder
{
Host,
Network
};
/**
* Constructs the unspecified IPv6 address (all 128 bits zeroed).
*/
IPAddr()
{
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
}
IPAddr() { memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); }
/**
* 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
* address or a hex IPv6 address.
*/
IPAddr(const std::string& s)
{
Init(s.data());
}
IPAddr(const std::string& s) { Init(s.data()); }
/**
* Constructs an address instance from a string representation.
@ -105,10 +107,7 @@ public:
* @param s ASCIIZ string containing an IP address as either a
* dotted IPv4 address or a hex IPv6 address.
*/
IPAddr(const char* s)
{
Init(s);
}
IPAddr(const char* s) { Init(s); }
/**
* Constructs an address instance from a string representation.
@ -135,7 +134,7 @@ public:
/**
* Copy constructor.
*/
IPAddr(const IPAddr& other) : in6(other.in6) { };
IPAddr(const IPAddr& other) : in6(other.in6){};
/**
* Destructor.
@ -175,8 +174,8 @@ public:
bool IsBroadcast() const
{
if ( GetFamily() == IPv4 )
return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff)
&& (in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff));
return ((in6.s6_addr[12] == 0xff) && (in6.s6_addr[13] == 0xff) &&
(in6.s6_addr[14] == 0xff) && (in6.s6_addr[15] == 0xff));
return false;
}
@ -197,12 +196,12 @@ public:
{
if ( GetFamily() == IPv4 )
{
*bytes = (uint32_t*) &in6.s6_addr[12];
*bytes = (uint32_t*)&in6.s6_addr[12];
return 1;
}
else
{
*bytes = (uint32_t*) in6.s6_addr;
*bytes = (uint32_t*)in6.s6_addr;
return 4;
}
}
@ -348,10 +347,7 @@ public:
return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) == 0;
}
friend bool operator!=(const IPAddr& addr1, const IPAddr& addr2)
{
return ! (addr1 == addr2);
}
friend bool operator!=(const IPAddr& addr1, const IPAddr& addr2) { return ! (addr1 == addr2); }
/**
* Comparison operator IP addresses. This defines a well-defined order for
@ -368,15 +364,9 @@ public:
return addr1 < addr2 || addr1 == addr2;
}
friend bool operator>=(const IPAddr& addr1, const IPAddr& addr2)
{
return ! ( addr1 < addr2 );
}
friend bool operator>=(const IPAddr& addr1, const IPAddr& addr2) { return ! (addr1 < addr2); }
friend bool operator>(const IPAddr& addr1, const IPAddr& addr2)
{
return ! ( addr1 <= addr2 );
}
friend bool operator>(const IPAddr& addr1, const IPAddr& addr2) { return ! (addr1 <= addr2); }
/**
* Converts the address into the type used internally by the
@ -384,8 +374,12 @@ public:
*/
void ConvertToThreadingValue(threading::Value::addr_t* v) const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this);
}
/**
* 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
// Top 96 bits of a v4-mapped-addr.
static constexpr uint8_t v4_mapped_prefix[12] = { 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff, 0xff };
};
static constexpr uint8_t v4_mapped_prefix[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
};
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 )
{
uint32_t* p = (uint32_t*) &in6.s6_addr[12];
uint32_t* p = (uint32_t*)&in6.s6_addr[12];
*p = htonl(*p);
}
}
@ -475,9 +467,9 @@ inline IPAddr::IPAddr(Family family, const uint32_t* bytes, ByteOrder order)
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);
}
}
@ -490,33 +482,32 @@ inline bool IPAddr::IsLoopback() const
return in6.s6_addr[12] == 127;
else
return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0)
&& (in6.s6_addr[2] == 0) && (in6.s6_addr[3] == 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[9] == 0)
&& (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0)
&& (in6.s6_addr[12] == 0) && (in6.s6_addr[13] == 0)
&& (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1));
return ((in6.s6_addr[0] == 0) && (in6.s6_addr[1] == 0) && (in6.s6_addr[2] == 0) &&
(in6.s6_addr[3] == 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[9] == 0) && (in6.s6_addr[10] == 0) && (in6.s6_addr[11] == 0) &&
(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
{
v->family = GetFamily();
switch ( v->family ) {
switch ( v->family )
{
case IPv4:
CopyIPv4(&v->in.in4);
return;
case IPv4:
CopyIPv4(&v->in.in4);
return;
case IPv6:
CopyIPv6(&v->in.in6);
return;
case IPv6:
CopyIPv6(&v->in.in6);
return;
// Can't be reached.
abort();
}
// Can't be reached.
abort();
}
}
/**
@ -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.
*/
class IPPrefix
{
{
public:
/**
* 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,
* meaning that the mask is to apply to the IPv4-mapped-IPv6 representation.
*/
IPPrefix(const IPAddr& addr, uint8_t length,
bool len_is_v6_relative = false);
IPPrefix(const IPAddr& addr, uint8_t length, bool len_is_v6_relative = false);
/**
* Copy constructor.
*/
IPPrefix(const IPPrefix& other)
: prefix(other.prefix), length(other.length) { }
IPPrefix(const IPPrefix& other) : prefix(other.prefix), length(other.length) { }
/**
* Destructor.
@ -589,10 +577,7 @@ public:
* 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.
*/
uint8_t Length() const
{
return prefix.GetFamily() == IPv4 ? length - 96 : length;
}
uint8_t Length() const { return prefix.GetFamily() == IPv4 ? length - 96 : length; }
/**
* Returns the bit length of the prefix always relative to a full
@ -609,7 +594,7 @@ public:
{
IPAddr p(addr);
p.Mask(length);
return p == prefix;
return p == prefix;
}
/**
* Assignment operator.
@ -630,7 +615,7 @@ public:
*/
std::string AsString() const;
operator std::string() const { return AsString(); }
operator std::string() const { return AsString(); }
/**
* Returns a key that can be used to lookup the IP Prefix in a hash table.
@ -647,8 +632,12 @@ public:
prefix.ConvertToThreadingValue(&v->prefix);
}
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const
{
return padded_sizeof(*this);
}
/**
* Comparison operator for IP prefix.
@ -658,10 +647,7 @@ public:
return net1.Prefix() == net2.Prefix() && net1.Length() == net2.Length();
}
friend bool operator!=(const IPPrefix& net1, const IPPrefix& net2)
{
return ! (net1 == net2);
}
friend bool operator!=(const IPPrefix& net1, const IPPrefix& net2) { return ! (net1 == net2); }
/**
* Comparison operator IP prefixes. This defines a well-defined order for
@ -685,15 +671,9 @@ public:
return net1 < net2 || net1 == net2;
}
friend bool operator>=(const IPPrefix& net1, const IPPrefix& net2)
{
return ! (net1 < net2 );
}
friend bool operator>=(const IPPrefix& net1, const IPPrefix& net2) { return ! (net1 < net2); }
friend bool operator>(const IPPrefix& net1, const IPPrefix& net2)
{
return ! ( net1 <= net2 );
}
friend bool operator>(const IPPrefix& net1, const IPPrefix& net2) { return ! (net1 <= net2); }
/**
* Converts an IPv4 or IPv6 prefix string into a network address prefix structure.
@ -718,8 +698,8 @@ public:
}
private:
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.
};
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.
};
} // namespace zeek
} // namespace zeek

View file

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

View file

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

View file

@ -2,23 +2,28 @@
#pragma once
#include <functional>
#include <type_traits>
#include <utility>
#include <functional>
namespace zeek {
namespace zeek
{
/**
* A tag class for the #IntrusivePtr constructor which means: adopt
* the reference from the caller.
*/
struct AdoptRef {};
struct AdoptRef
{
};
/**
* A tag class for the #IntrusivePtr constructor which means: create a
* new reference to the object.
*/
struct NewRef {};
struct NewRef
{
};
/**
* 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
* increase robustness of the code (in particular w.r.t. exceptions).
*/
template <class T>
class IntrusivePtr {
template <class T> class IntrusivePtr
{
public:
// -- member types
@ -74,10 +79,7 @@ public:
*
* @param raw_ptr Pointer to the shared object.
*/
constexpr IntrusivePtr(AdoptRef, pointer raw_ptr) noexcept
: ptr_(raw_ptr)
{
}
constexpr IntrusivePtr(AdoptRef, pointer raw_ptr) noexcept : ptr_(raw_ptr) { }
/**
* 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.
*/
IntrusivePtr(NewRef, pointer raw_ptr) noexcept
: ptr_(raw_ptr)
IntrusivePtr(NewRef, pointer raw_ptr) noexcept : ptr_(raw_ptr)
{
if ( ptr_ )
Ref(ptr_);
@ -99,10 +100,7 @@ public:
// nop
}
IntrusivePtr(const IntrusivePtr& other) noexcept
: IntrusivePtr(NewRef{}, other.get())
{
}
IntrusivePtr(const IntrusivePtr& other) noexcept : IntrusivePtr(NewRef{}, other.get()) { }
template <class U, class = std::enable_if_t<std::is_convertible_v<U*, T*>>>
IntrusivePtr(IntrusivePtr<U> other) noexcept : ptr_(other.release())
@ -116,10 +114,7 @@ public:
Unref(ptr_);
}
void swap(IntrusivePtr& other) noexcept
{
std::swap(ptr_, other.ptr_);
}
void swap(IntrusivePtr& other) noexcept { std::swap(ptr_, other.ptr_); }
friend void swap(IntrusivePtr& a, IntrusivePtr& b) noexcept
{
@ -132,10 +127,7 @@ public:
* intrusive pointer to @c nullptr.
* @returns the raw pointer without modifying the reference count.
*/
pointer release() noexcept
{
return std::exchange(ptr_, nullptr);
}
pointer release() noexcept { return std::exchange(ptr_, nullptr); }
IntrusivePtr& operator=(const IntrusivePtr& other) noexcept
{
@ -160,34 +152,19 @@ public:
return *this;
}
pointer get() const noexcept
{
return ptr_;
}
pointer get() const noexcept { return ptr_; }
pointer operator->() const noexcept
{
return ptr_;
}
pointer operator->() const noexcept { return ptr_; }
reference operator*() const noexcept
{
return *ptr_;
}
reference operator*() const noexcept { return *ptr_; }
bool operator!() const noexcept
{
return !ptr_;
}
bool operator!() const noexcept { return ! ptr_; }
explicit operator bool() const noexcept
{
return ptr_ != nullptr;
}
explicit operator bool() const noexcept { return ptr_ != nullptr; }
private:
pointer ptr_ = nullptr;
};
};
/**
* 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.
* @relates IntrusivePtr
*/
template <class T, class... Ts>
IntrusivePtr<T> make_intrusive(Ts&&... args)
template <class T, class... Ts> IntrusivePtr<T> make_intrusive(Ts&&... args)
{
// Assumes that objects start with a reference count of 1!
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.
* @return The pointer, as cast to type @c T.
*/
template <class T, class U>
IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
template <class T, class U> IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
{
return {AdoptRef{}, static_cast<T*>(p.release())};
}
@ -221,68 +196,68 @@ IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator==(const zeek::IntrusivePtr<T>& x, std::nullptr_t) {
return !x;
}
template <class T> bool operator==(const zeek::IntrusivePtr<T>& x, std::nullptr_t)
{
return ! x;
}
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator==(std::nullptr_t, const zeek::IntrusivePtr<T>& x) {
return !x;
}
template <class T> bool operator==(std::nullptr_t, const zeek::IntrusivePtr<T>& x)
{
return ! x;
}
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator!=(const zeek::IntrusivePtr<T>& x, std::nullptr_t) {
return static_cast<bool>(x);
}
template <class T> bool operator!=(const zeek::IntrusivePtr<T>& x, std::nullptr_t)
{
return static_cast<bool>(x);
}
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator!=(std::nullptr_t, const zeek::IntrusivePtr<T>& x) {
return static_cast<bool>(x);
}
template <class T> bool operator!=(std::nullptr_t, const zeek::IntrusivePtr<T>& x)
{
return static_cast<bool>(x);
}
// -- comparison to raw pointer ------------------------------------------------
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator==(const zeek::IntrusivePtr<T>& x, const T* y) {
return x.get() == y;
}
template <class T> bool operator==(const zeek::IntrusivePtr<T>& x, const T* y)
{
return x.get() == y;
}
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator==(const T* x, const zeek::IntrusivePtr<T>& y) {
return x == y.get();
}
template <class T> bool operator==(const T* x, const zeek::IntrusivePtr<T>& y)
{
return x == y.get();
}
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator!=(const zeek::IntrusivePtr<T>& x, const T* y) {
return x.get() != y;
}
template <class T> bool operator!=(const zeek::IntrusivePtr<T>& x, const T* y)
{
return x.get() != y;
}
/**
* @relates IntrusivePtr
*/
template <class T>
bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y) {
return x != y.get();
}
template <class T> bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y)
{
return x != y.get();
}
// -- comparison to intrusive pointer ------------------------------------------
@ -294,7 +269,7 @@ bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y) {
*/
template <class T, class U>
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();
}
@ -304,19 +279,23 @@ auto operator==(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y)
*/
template <class T, class U>
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();
}
} // namespace zeek
} // namespace zeek
// -- hashing ------------------------------------------------
namespace std {
template <class T> struct hash<zeek::IntrusivePtr<T>> {
namespace std
{
template <class T> struct hash<zeek::IntrusivePtr<T>>
{
// 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
{ return std::hash<T*>{}(v.get()); }
};
}
{
return std::hash<T*>{}(v.get());
}
};
}

View file

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

View file

@ -20,24 +20,29 @@
// sizeof(data) <= sizeof(void*).
#include <stdarg.h>
#include <cassert>
#include <initializer_list>
#include <iterator>
#include <utility>
#include <cassert>
#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>
class List {
template <typename T, ListOrder Order = ListOrder::ORDERED> class List
{
public:
constexpr static int DEFAULT_LIST_SIZE = 10;
constexpr static int LIST_GROWTH_FACTOR = 2;
~List() { free(entries); }
~List() { free(entries); }
explicit List(int size = 0)
{
num_entries = 0;
@ -51,7 +56,7 @@ public:
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)
@ -60,7 +65,7 @@ public:
num_entries = b.num_entries;
if ( max_entries )
entries = (T*) util::safe_malloc(max_entries * sizeof(T));
entries = (T*)util::safe_malloc(max_entries * sizeof(T));
else
entries = nullptr;
@ -81,11 +86,11 @@ public:
List(const T* arr, int 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));
}
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)
{
@ -98,7 +103,7 @@ public:
num_entries = b.num_entries;
if ( max_entries )
entries = (T *) util::safe_malloc(max_entries * sizeof(T));
entries = (T*)util::safe_malloc(max_entries * sizeof(T));
else
entries = nullptr;
@ -124,12 +129,9 @@ public:
}
// Return nth ent of list (do not remove).
T& operator[](int i) const
{
return entries[i];
}
T& operator[](int i) const { return entries[i]; }
void clear() // remove all entries
void clear() // remove all entries
{
free(entries);
entries = nullptr;
@ -139,16 +141,16 @@ public:
bool empty() const noexcept { return num_entries == 0; }
size_t size() const noexcept { return num_entries; }
int length() const { return num_entries; }
int max() const { return max_entries; }
int resize(int new_size = 0) // 0 => size to fit current number of entries
int length() const { return num_entries; }
int max() const { return max_entries; }
int resize(int new_size = 0) // 0 => size to fit current number of entries
{
if ( new_size < num_entries )
new_size = num_entries; // do not lose any entries
new_size = num_entries; // do not lose any 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 )
max_entries = new_size;
else
@ -158,9 +160,12 @@ public:
return max_entries;
}
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
int MemoryAllocation() const
{ return padded_sizeof(*this) + util::pad_size(max_entries * sizeof(T)); }
[[deprecated(
"Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]] int
MemoryAllocation() const
{
return padded_sizeof(*this) + util::pad_size(max_entries * sizeof(T));
}
void push_front(const T& a)
{
@ -168,7 +173,7 @@ public:
resize(max_entries ? max_entries * LIST_GROWTH_FACTOR : DEFAULT_LIST_SIZE);
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;
entries[0] = a;
@ -182,20 +187,20 @@ public:
entries[num_entries++] = a;
}
void pop_front() { remove_nth(0); }
void pop_back() { remove_nth(num_entries-1); }
void pop_front() { remove_nth(0); }
void pop_back() { remove_nth(num_entries - 1); }
T& front() { return entries[0]; }
T& back() { return entries[num_entries-1]; }
T& front() { return entries[0]; }
T& back() { return entries[num_entries - 1]; }
// The append method is maintained for historical/compatibility reasons.
// (It's commonly used in the event generation API)
void append(const T& a) // add to end of list
void append(const T& a) // add to end of list
{
push_back(a);
}
bool remove(const T& a) // delete entry from list
bool remove(const T& a) // delete entry from list
{
int pos = member_pos(a);
if ( pos != -1 )
@ -207,9 +212,9 @@ public:
return false;
}
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];
@ -221,7 +226,7 @@ public:
--num_entries;
for ( ; n < num_entries; ++n )
entries[n] = entries[n+1];
entries[n] = entries[n + 1];
}
else
{
@ -249,7 +254,7 @@ public:
return (i == length()) ? -1 : i;
}
T replace(int ent_index, const T& new_ent) // replace entry #i with a new value
T replace(int ent_index, const T& new_ent) // replace entry #i with a new value
{
if ( ent_index < 0 )
return T{};
@ -298,7 +303,6 @@ public:
const_reverse_iterator crend() const { return rend(); }
protected:
// This could essentially be an std::vector if we wanted. Some
// reasons to maybe not refactor to use std::vector ?
//
@ -328,17 +332,15 @@ protected:
int num_entries;
};
// Specialization of the List class to store pointers of a type.
template<typename T, ListOrder Order = ListOrder::ORDERED>
using PList = List<T*, Order>;
template <typename T, ListOrder Order = ListOrder::ORDERED> using PList = List<T*, Order>;
// Popular type of list: list of strings.
using name_list = PList<char>;
} // namespace zeek
} // namespace zeek
// Macro to visit each list element in turn.
#define loop_over_list(list, iterator) \
int iterator; \
#define loop_over_list(list, iterator) \
int iterator; \
for ( iterator = 0; iterator < (list).length(); ++iterator )

View file

@ -1,6 +1,5 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/NFA.h"
#include <algorithm>
@ -8,8 +7,10 @@
#include "zeek/Desc.h"
#include "zeek/EquivClass.h"
#include "zeek/IntSet.h"
#include "zeek/zeek-config.h"
namespace zeek::detail {
namespace zeek::detail
{
static int nfa_state_id = 0;
@ -159,9 +160,8 @@ unsigned int NFA_State::TotalMemoryAllocation() const
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return padded_sizeof(*this)
+ xtions.MemoryAllocation() - padded_sizeof(xtions)
+ (epsclosure ? epsclosure->MemoryAllocation() : 0);
return padded_sizeof(*this) + xtions.MemoryAllocation() - padded_sizeof(xtions) +
(epsclosure ? epsclosure->MemoryAllocation() : 0);
#pragma GCC diagnostic pop
}
@ -219,7 +219,7 @@ void NFA_Machine::LinkCopies(int n)
for ( i = 0; i < n; ++i )
AppendMachine(copies[i]);
delete [] copies;
delete[] copies;
}
NFA_Machine* NFA_Machine::DuplicateMachine()
@ -243,7 +243,7 @@ void NFA_Machine::AppendMachine(NFA_Machine* m)
final_state->AddXtion(m->FirstState());
final_state = m->FinalState();
Ref(m->FirstState()); // so states stay around after the following
Ref(m->FirstState()); // so states stay around after the following
Unref(m);
}
@ -332,7 +332,6 @@ NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2)
return new NFA_Machine(first, last);
}
NFA_state_list* epsilon_closure(NFA_state_list* states)
{
// 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;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -2,8 +2,8 @@
#pragma once
#include "zeek/Obj.h"
#include "zeek/List.h"
#include "zeek/Obj.h"
#define NO_ACCEPT 0
@ -16,11 +16,13 @@
#define SYM_EPSILON 259
#define SYM_CCL 260
namespace zeek {
namespace zeek
{
class Func;
namespace detail {
namespace detail
{
class CCL;
class EquivClass;
@ -28,33 +30,34 @@ class EquivClass;
class NFA_State;
using NFA_state_list = PList<NFA_State>;
class NFA_State : public Obj {
class NFA_State : public Obj
{
public:
NFA_State(int sym, EquivClass* ec);
explicit NFA_State(CCL* ccl);
~NFA_State() override;
void AddXtion(NFA_State* next_state) { xtions.push_back(next_state); }
NFA_state_list* Transitions() { return &xtions; }
void AddXtion(NFA_State* next_state) { xtions.push_back(next_state); }
NFA_state_list* Transitions() { return &xtions; }
void AddXtionsTo(NFA_state_list* ns);
void SetAccept(int accept_val) { accept = accept_val; }
int Accept() const { return accept; }
void SetAccept(int accept_val) { accept = accept_val; }
int Accept() const { return accept; }
// Returns a deep copy of this NFA state and everything it points
// to. Upon return, each state's marker is set to point to its
// copy.
NFA_State* DeepCopy();
void SetMark(NFA_State* m) { mark = m; }
NFA_State* Mark() const { return mark; }
void SetMark(NFA_State* m) { mark = m; }
NFA_State* Mark() const { return mark; }
void ClearMarks();
void SetFirstTransIsBackRef() { first_trans_is_back_ref = true; }
void SetFirstTransIsBackRef() { first_trans_is_back_ref = true; }
int TransSym() const { return sym; }
CCL* TransCCL() const { return ccl; }
int ID() const { return id; }
int TransSym() const { return sym; }
CCL* TransCCL() const { return ccl; }
int ID() const { return id; }
NFA_state_list* EpsilonClosure();
@ -62,13 +65,14 @@ public:
void Dump(FILE* f);
// Recursivly count all the reachable states.
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int TotalMemoryAllocation() const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
TotalMemoryAllocation() const;
protected:
int sym; // if SYM_CCL, then use ccl
int id; // number that uniquely identifies this state
CCL* ccl; // if nil, then use sym
int sym; // if SYM_CCL, then use ccl
int id; // number that uniquely identifies this state
CCL* ccl; // if nil, then use sym
int accept;
// Whether the first transition points backwards. Used
@ -78,34 +82,40 @@ protected:
NFA_state_list xtions;
NFA_state_list* epsclosure;
NFA_State* mark;
};
};
class EpsilonState : public NFA_State {
class EpsilonState : public NFA_State
{
public:
EpsilonState() : NFA_State(SYM_EPSILON, nullptr) { }
};
EpsilonState() : NFA_State(SYM_EPSILON, nullptr) { }
};
class NFA_Machine : public Obj {
class NFA_Machine : public Obj
{
public:
explicit NFA_Machine(NFA_State* first, NFA_State* final = nullptr);
~NFA_Machine() override;
NFA_State* FirstState() const { return first_state; }
NFA_State* FirstState() const { return first_state; }
void SetFinalState(NFA_State* final) { final_state = final; }
NFA_State* FinalState() const { return final_state; }
void SetFinalState(NFA_State* final) { final_state = final; }
NFA_State* FinalState() const { return final_state; }
void AddAccept(int accept_val);
void MakeClosure() { MakePositiveClosure(); MakeOptional(); }
void MakeClosure()
{
MakePositiveClosure();
MakeOptional();
}
void MakeOptional();
void MakePositiveClosure();
// re{lower,upper}; upper can be NO_UPPER_BOUND = infinity.
void MakeRepl(int lower, int upper);
void MarkBOL() { bol = 1; }
void MarkEOL() { eol = 1; }
void MarkBOL() { bol = 1; }
void MarkEOL() { eol = 1; }
NFA_Machine* DuplicateMachine();
void LinkCopies(int n);
@ -118,8 +128,9 @@ public:
void Describe(ODesc* d) const override;
void Dump(FILE* f);
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@ -131,7 +142,7 @@ protected:
NFA_State* first_state;
NFA_State* final_state;
int bol, eol;
};
};
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)
extern bool NFA_state_cmp_neg(const NFA_State* v1, const NFA_State* v2);
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

@ -1,12 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/NetVar.h"
#include "zeek/Var.h"
#include "zeek/EventHandler.h"
#include "zeek/Val.h"
#include "zeek/ID.h"
#include "zeek/Val.h"
#include "zeek/Var.h"
#include "zeek/zeek-config.h"
zeek::RecordType* conn_id;
zeek::RecordType* endpoint;
@ -105,7 +105,8 @@ zeek::StringVal* cmd_line_bpf_filter;
zeek::StringVal* global_hash_seed;
namespace zeek::detail {
namespace zeek::detail
{
int watchdog_interval;
@ -192,7 +193,8 @@ int record_all_packets;
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,
// 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()
{
#include "const.bif.netvar_init"
#include "packet_analysis.bif.netvar_init"
#include "reporter.bif.netvar_init"
#include "supervisor.bif.netvar_init"
#include "packet_analysis.bif.netvar_init"
}
static void init_bif_types()
@ -216,14 +218,15 @@ static void init_bif_types()
}
#include "const.bif.netvar_def"
#include "types.bif.netvar_def"
#include "event.bif.netvar_def"
#include "packet_analysis.bif.netvar_def"
#include "reporter.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.
namespace zeek::detail {
namespace zeek::detail
{
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_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_excessive_data_without_further_acks = id::find_val("tcp_excessive_data_without_further_acks")->AsCount();
tcp_max_above_hole_without_any_acks =
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();
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_interarrival_thresh = id::find_val("tcp_storm_interarrival_thresh")->AsInterval();
tcp_content_deliver_all_orig =
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_orig = 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());
udp_content_deliver_all_orig =
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_orig = 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_delivery_ports_use_resp =
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();
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -2,11 +2,12 @@
#pragma once
#include "zeek/Val.h"
#include "zeek/EventRegistry.h"
#include "zeek/Stats.h"
#include "zeek/Val.h"
namespace zeek::detail {
namespace zeek::detail
{
extern int watchdog_interval;
@ -101,11 +102,11 @@ extern void init_event_handlers();
extern void init_net_var();
extern void init_builtin_types();
} // namespace zeek::detail
} // namespace zeek::detail
#include "const.bif.netvar_h"
#include "types.bif.netvar_h"
#include "event.bif.netvar_h"
#include "packet_analysis.bif.netvar_h"
#include "reporter.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.
#include "zeek/Notifier.h"
#include <set>
#include "zeek/Notifier.h"
#include "zeek/DebugLogger.h"
zeek::notifier::detail::Registry zeek::notifier::detail::registry;
namespace zeek::notifier::detail {
namespace zeek::notifier::detail
{
Receiver::Receiver()
{
@ -86,4 +88,4 @@ Modifiable::~Modifiable()
registry.Unregister(this);
}
} // namespace zeek::notifier::detail
} // namespace zeek::notifier::detail

View file

@ -7,15 +7,17 @@
#pragma once
#include <unordered_map>
#include <cstdint>
#include <unordered_map>
namespace zeek::notifier::detail {
namespace zeek::notifier::detail
{
class Modifiable;
/** Interface class for receivers of notifications. */
class Receiver {
class Receiver
{
public:
Receiver();
virtual ~Receiver();
@ -32,10 +34,11 @@ public:
* no further modifications can possibly occur.
*/
virtual void Terminate() { }
};
};
/** Singleton class tracking all notification requests globally. */
class Registry {
class Registry
{
public:
~Registry();
@ -86,7 +89,7 @@ private:
typedef std::unordered_multimap<Modifiable*, Receiver*> ModifiableMap;
ModifiableMap registrations;
};
};
/**
* 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
* modified.
*/
class Modifiable {
class Modifiable
{
public:
/**
* Calling this method signals to all registered receivers that the
@ -116,6 +120,6 @@ protected:
// Number of currently registered receivers.
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.
#include "zeek/zeek-config.h"
#include "zeek/Obj.h"
#include <stdlib.h>
#include "zeek/Desc.h"
#include "zeek/Func.h"
#include "zeek/File.h"
#include "zeek/Func.h"
#include "zeek/plugin/Manager.h"
#include "zeek/zeek-config.h"
namespace zeek {
namespace detail {
namespace zeek
{
namespace detail
{
Location start_location("<start 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
{
if ( filename == l.filename ||
(filename && l.filename && util::streq(filename, l.filename)) )
if ( filename == l.filename || (filename && l.filename && util::streq(filename, l.filename)) )
return first_line == l.first_line && last_line == l.last_line;
else
return false;
}
} // namespace detail
} // namespace detail
int Obj::suppress_errors = 0;
@ -63,7 +64,8 @@ Obj::~Obj()
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;
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();
}
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 )
return;
@ -146,8 +149,7 @@ bool Obj::SetLocationInfo(const detail::Location* start, const detail::Location*
delete location;
location = new detail::Location(start->filename,
start->first_line, end->last_line,
location = new detail::Location(start->filename, start->first_line, end->last_line,
start->first_column, end->last_column);
return true;
@ -162,8 +164,8 @@ void Obj::UpdateLocationEndInfo(const detail::Location& end)
location->last_column = end.last_column;
}
void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2,
bool pinpoint_only, const detail::Location* expr_location) const
void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2, bool pinpoint_only,
const detail::Location* expr_location) const
{
d->SetShort();
@ -172,7 +174,7 @@ void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2,
const detail::Location* loc2 = nullptr;
if ( obj2 && obj2->GetLocationInfo() != &detail::no_location &&
*obj2->GetLocationInfo() != *GetLocationInfo() )
*obj2->GetLocationInfo() != *GetLocationInfo() )
loc2 = obj2->GetLocationInfo();
else if ( expr_location )
loc2 = expr_location;
@ -209,7 +211,7 @@ void bad_ref(int type)
void obj_delete_func(void* v)
{
Unref((Obj*) v);
Unref((Obj*)v);
}
} // namespace zeek
} // namespace zeek

View file

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

View file

@ -2,25 +2,25 @@
#include "zeek/OpaqueVal.h"
#include <memory>
#include <broker/data.hh>
#include <broker/error.hh>
#include <memory>
#include "zeek/CompHash.h"
#include "zeek/Desc.h"
#include "zeek/NetVar.h"
#include "zeek/Reporter.h"
#include "zeek/Scope.h"
#include "zeek/Desc.h"
#include "zeek/Var.h"
#include "zeek/probabilistic/BloomFilter.h"
#include "zeek/probabilistic/CardinalityCounter.h"
namespace zeek {
namespace zeek
{
// Helper to retrieve a broker value out of a broker::vector at a specified
// 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)
{
if ( i >= v.size() )
@ -40,12 +40,9 @@ OpaqueMgr* OpaqueMgr::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
{
@ -53,7 +50,7 @@ const std::string& OpaqueMgr::TypeID(const OpaqueVal* v) const
if ( x == _types.end() )
reporter->InternalError("OpaqueMgr::TypeID: opaque type %s not registered",
v->OpaqueName());
v->OpaqueName());
return x->first;
}
@ -211,9 +208,7 @@ HashVal::HashVal(OpaqueTypePtr t) : OpaqueVal(std::move(t))
valid = false;
}
MD5Val::MD5Val() : HashVal(md5_type)
{
}
MD5Val::MD5Val() : HashVal(md5_type) { }
MD5Val::~MD5Val()
{
@ -232,7 +227,7 @@ void HashVal::digest_one(EVP_MD_CTX* h, const Val* v)
{
ODesc d(DESC_BINARY);
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() )
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 = {
true,
static_cast<uint64_t>(md->A),
static_cast<uint64_t>(md->B),
static_cast<uint64_t>(md->C),
static_cast<uint64_t>(md->D),
static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num)
};
broker::vector d = {true,
static_cast<uint64_t>(md->A),
static_cast<uint64_t>(md->B),
static_cast<uint64_t>(md->C),
static_cast<uint64_t>(md->D),
static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num)};
for ( int i = 0; i < MD5_LBLOCK; ++i )
d.emplace_back(static_cast<uint64_t>(md->data[i]));
@ -325,7 +318,7 @@ bool MD5Val::DoUnserialize(const broker::data& data)
}
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) )
return false;
@ -351,9 +344,7 @@ bool MD5Val::DoUnserialize(const broker::data& data)
return true;
}
SHA1Val::SHA1Val() : HashVal(sha1_type)
{
}
SHA1Val::SHA1Val() : HashVal(sha1_type) { }
SHA1Val::~SHA1Val()
{
@ -409,19 +400,17 @@ broker::expected<broker::data> SHA1Val::DoSerialize() const
if ( ! IsValid() )
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 = {
true,
static_cast<uint64_t>(md->h0),
static_cast<uint64_t>(md->h1),
static_cast<uint64_t>(md->h2),
static_cast<uint64_t>(md->h3),
static_cast<uint64_t>(md->h4),
static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num)
};
broker::vector d = {true,
static_cast<uint64_t>(md->h0),
static_cast<uint64_t>(md->h1),
static_cast<uint64_t>(md->h2),
static_cast<uint64_t>(md->h3),
static_cast<uint64_t>(md->h4),
static_cast<uint64_t>(md->Nl),
static_cast<uint64_t>(md->Nh),
static_cast<uint64_t>(md->num)};
for ( int i = 0; i < SHA_LBLOCK; ++i )
d.emplace_back(static_cast<uint64_t>(md->data[i]));
@ -446,7 +435,7 @@ bool SHA1Val::DoUnserialize(const broker::data& data)
}
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) )
return false;
@ -474,9 +463,7 @@ bool SHA1Val::DoUnserialize(const broker::data& data)
return true;
}
SHA256Val::SHA256Val() : HashVal(sha256_type)
{
}
SHA256Val::SHA256Val() : HashVal(sha256_type) { }
SHA256Val::~SHA256Val()
{
@ -501,7 +488,7 @@ ValPtr SHA256Val::DoClone(CloneState* state)
bool SHA256Val::DoInit()
{
assert( ! IsValid() );
assert(! IsValid());
ctx = detail::hash_init(detail::Hash_SHA256);
return true;
}
@ -532,15 +519,10 @@ broker::expected<broker::data> SHA256Val::DoSerialize() const
if ( ! IsValid() )
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 = {
true,
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)
};
broker::vector d = {true, 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 )
d.emplace_back(static_cast<uint64_t>(md->h[i]));
@ -568,7 +550,7 @@ bool SHA256Val::DoUnserialize(const broker::data& data)
}
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) )
return false;
@ -594,9 +576,7 @@ bool SHA256Val::DoUnserialize(const broker::data& data)
return true;
}
EntropyVal::EntropyVal() : OpaqueVal(entropy_type)
{
}
EntropyVal::EntropyVal() : OpaqueVal(entropy_type) { }
bool EntropyVal::Feed(const void* data, size_t size)
{
@ -604,8 +584,8 @@ bool EntropyVal::Feed(const void* data, size_t size)
return true;
}
bool EntropyVal::Get(double *r_ent, double *r_chisq, double *r_mean,
double *r_montepicalc, double *r_scc)
bool EntropyVal::Get(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc,
double* r_scc)
{
state.end(r_ent, r_chisq, r_mean, r_montepicalc, r_scc);
return true;
@ -615,30 +595,22 @@ IMPLEMENT_OPAQUE_VALUE(EntropyVal)
broker::expected<broker::data> EntropyVal::DoSerialize() const
{
broker::vector d =
{
static_cast<uint64_t>(state.totalc),
static_cast<uint64_t>(state.mp),
static_cast<uint64_t>(state.sccfirst),
static_cast<uint64_t>(state.inmont),
static_cast<uint64_t>(state.mcount),
static_cast<uint64_t>(state.cexp),
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),
};
broker::vector d = {
static_cast<uint64_t>(state.totalc), static_cast<uint64_t>(state.mp),
static_cast<uint64_t>(state.sccfirst), static_cast<uint64_t>(state.inmont),
static_cast<uint64_t>(state.mcount), static_cast<uint64_t>(state.cexp),
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);
for ( int i = 0; i < 256; ++i )
d.emplace_back(static_cast<uint64_t>(state.ccount[i]));
for ( int i = 0; i < RT_MONTEN; ++i )
for ( int i = 0; i < RT_MONTEN; ++i )
d.emplace_back(static_cast<uint64_t>(state.monte[i]));
return {std::move(d)};
@ -694,15 +666,13 @@ bool EntropyVal::DoUnserialize(const broker::data& data)
return true;
}
BloomFilterVal::BloomFilterVal()
: OpaqueVal(bloomfilter_type)
BloomFilterVal::BloomFilterVal() : OpaqueVal(bloomfilter_type)
{
hash = nullptr;
bloom_filter = nullptr;
}
BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf)
: OpaqueVal(bloomfilter_type)
BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf) : OpaqueVal(bloomfilter_type)
{
hash = nullptr;
bloom_filter = bf;
@ -762,12 +732,10 @@ std::string BloomFilterVal::InternalState() const
return bloom_filter->InternalState();
}
BloomFilterValPtr BloomFilterVal::Merge(const BloomFilterVal* x,
const BloomFilterVal* y)
BloomFilterValPtr BloomFilterVal::Merge(const BloomFilterVal* x, const BloomFilterVal* y)
{
if ( x->Type() && // any one 0 is ok here
y->Type() &&
! same_type(x->Type(), y->Type()) )
y->Type() && ! same_type(x->Type(), y->Type()) )
{
reporter->Error("cannot merge Bloom filters with different types");
return nullptr;
@ -875,8 +843,8 @@ CardinalityVal::~CardinalityVal()
ValPtr CardinalityVal::DoClone(CloneState* state)
{
return state->NewClone(this,
make_intrusive<CardinalityVal>(new probabilistic::detail::CardinalityCounter(*c)));
return state->NewClone(
this, make_intrusive<CardinalityVal>(new probabilistic::detail::CardinalityCounter(*c)));
}
bool CardinalityVal::Typify(TypePtr arg_type)
@ -948,16 +916,15 @@ bool CardinalityVal::DoUnserialize(const broker::data& data)
return true;
}
ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p)
: OpaqueVal(paraglob_type)
ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p) : OpaqueVal(paraglob_type)
{
this->internal_paraglob = std::move(p);
}
VectorValPtr ParaglobVal::Get(StringVal* &pattern)
VectorValPtr ParaglobVal::Get(StringVal*& pattern)
{
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);
for ( size_t i = 0; i < matches.size(); i++ )
@ -977,7 +944,7 @@ broker::expected<broker::data> ParaglobVal::DoSerialize() const
{
broker::vector d;
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));
return {std::move(d)};
}
@ -988,10 +955,10 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
if ( ! d )
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());
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) )
return false;
@ -1001,12 +968,12 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
{
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());
return false;
}
catch (const paraglob::overflow_error& e)
catch ( const paraglob::overflow_error& e )
{
reporter->Error("Paraglob overflow error -> %s", e.what());
return false;
@ -1017,16 +984,17 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
ValPtr ParaglobVal::DoClone(CloneState* state)
{
try {
return make_intrusive<ParaglobVal>
(std::make_unique<paraglob::Paraglob>(this->internal_paraglob->serialize()));
try
{
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());
return nullptr;
}
catch (const paraglob::overflow_error& e)
catch ( const paraglob::overflow_error& e )
{
reporter->Error("Paraglob overflow error while cloning -> %s", e.what());
return nullptr;
@ -1035,8 +1003,7 @@ ValPtr ParaglobVal::DoClone(CloneState* state)
broker::expected<broker::data> TelemetryVal::DoSerialize() const
{
return broker::make_error(broker::ec::invalid_data,
"cannot serialize metric handles");
return broker::make_error(broker::ec::invalid_data, "cannot serialize metric handles");
}
bool TelemetryVal::DoUnserialize(const broker::data&)
@ -1044,52 +1011,38 @@ bool TelemetryVal::DoUnserialize(const broker::data&)
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
#include <sys/types.h> // for u_char
#include <broker/expected.hh>
#include <paraglob/paraglob.h>
#include <sys/types.h> // for u_char
#include "zeek/IntrusivePtr.h"
#include "zeek/RandTest.h"
@ -14,12 +14,22 @@
#include "zeek/telemetry/Gauge.h"
#include "zeek/telemetry/Histogram.h"
namespace broker { class data; }
namespace broker
{
class data;
}
namespace zeek {
namespace zeek
{
namespace probabilistic { class BloomFilter; }
namespace probabilistic::detail { class CardinalityCounter; }
namespace probabilistic
{
class BloomFilter;
}
namespace probabilistic::detail
{
class CardinalityCounter;
}
class OpaqueVal;
using OpaqueValPtr = IntrusivePtr<OpaqueVal>;
@ -28,12 +38,13 @@ class BloomFilterVal;
using BloomFilterValPtr = IntrusivePtr<BloomFilterVal>;
/**
* Singleton that registers all available all available types of opaque
* values. This faciliates their serialization into Broker values.
*/
class OpaqueMgr {
* Singleton that registers all available all available types of opaque
* values. This faciliates their serialization into Broker values.
*/
class OpaqueMgr
{
public:
using Factory = OpaqueValPtr ();
using Factory = OpaqueValPtr();
/**
* Return's a unique ID for the type of an opaque value.
@ -66,27 +77,26 @@ public:
* Internal helper class to register an OpaqueVal-derived classes
* with the manager.
*/
template<class T>
class Register {
template <class T> class Register
{
public:
Register(const char* id)
{ OpaqueMgr::mgr()->_types.emplace(id, &T::OpaqueInstantiate); }
};
Register(const char* id) { OpaqueMgr::mgr()->_types.emplace(id, &T::OpaqueInstantiate); }
};
private:
std::unordered_map<std::string, Factory*> _types;
};
};
/** Macro to insert into an OpaqueVal-derived class's declaration. */
#define DECLARE_OPAQUE_VALUE(T) \
friend class zeek::OpaqueMgr::Register<T>; \
friend zeek::IntrusivePtr<T> zeek::make_intrusive<T>(); \
broker::expected<broker::data> DoSerialize() const override; \
bool DoUnserialize(const broker::data& data) override; \
const char* OpaqueName() const override { return #T; } \
static zeek::OpaqueValPtr OpaqueInstantiate() { return zeek::make_intrusive<T>(); }
#define DECLARE_OPAQUE_VALUE(T) \
friend class zeek::OpaqueMgr::Register<T>; \
friend zeek::IntrusivePtr<T> zeek::make_intrusive<T>(); \
broker::expected<broker::data> DoSerialize() const override; \
bool DoUnserialize(const broker::data& data) override; \
const char* OpaqueName() const override { return #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)
/** 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
* (other than bif functions). See OpaqueVal.h for derived classes.
*/
class OpaqueVal : public Val {
class OpaqueVal : public Val
{
public:
explicit OpaqueVal(OpaqueTypePtr t);
~OpaqueVal() override;
@ -164,9 +175,10 @@ protected:
* during unserialization. Returns the type at reference count +1.
*/
static TypePtr UnserializeType(const broker::data& data);
};
};
class HashVal : public OpaqueVal {
class HashVal : public OpaqueVal
{
public:
template <class T>
static void digest_all(detail::HashAlgorithm alg, const T& vlist, u_char* result)
@ -197,17 +209,18 @@ protected:
private:
// This flag exists because Get() can only be called once.
bool valid;
};
};
class MD5Val : public HashVal {
class MD5Val : public HashVal
{
public:
template <class T>
static void digest(const T& vlist, u_char result[MD5_DIGEST_LENGTH])
{ digest_all(detail::Hash_MD5, vlist, result); }
template <class T> static void digest(const T& vlist, u_char result[MD5_DIGEST_LENGTH])
{
digest_all(detail::Hash_MD5, vlist, result);
}
template <class T>
static void hmac(const T& vlist,
u_char key[MD5_DIGEST_LENGTH],
static void hmac(const T& vlist, u_char key[MD5_DIGEST_LENGTH],
u_char result[MD5_DIGEST_LENGTH])
{
digest(vlist, result);
@ -233,13 +246,15 @@ protected:
DECLARE_OPAQUE_VALUE(MD5Val)
private:
EVP_MD_CTX* ctx;
};
};
class SHA1Val : public HashVal {
class SHA1Val : public HashVal
{
public:
template <class T>
static void digest(const T& vlist, u_char result[SHA_DIGEST_LENGTH])
{ digest_all(detail::Hash_SHA1, vlist, result); }
template <class T> static void digest(const T& vlist, u_char result[SHA_DIGEST_LENGTH])
{
digest_all(detail::Hash_SHA1, vlist, result);
}
SHA1Val();
~SHA1Val();
@ -256,13 +271,15 @@ protected:
DECLARE_OPAQUE_VALUE(SHA1Val)
private:
EVP_MD_CTX* ctx;
};
};
class SHA256Val : public HashVal {
class SHA256Val : public HashVal
{
public:
template <class T>
static void digest(const T& vlist, u_char result[SHA256_DIGEST_LENGTH])
{ digest_all(detail::Hash_SHA256, vlist, result); }
template <class T> static void digest(const T& vlist, u_char result[SHA256_DIGEST_LENGTH])
{
digest_all(detail::Hash_SHA256, vlist, result);
}
SHA256Val();
~SHA256Val();
@ -279,15 +296,15 @@ protected:
DECLARE_OPAQUE_VALUE(SHA256Val)
private:
EVP_MD_CTX* ctx;
};
};
class EntropyVal : public OpaqueVal {
class EntropyVal : public OpaqueVal
{
public:
EntropyVal();
bool Feed(const void* data, size_t size);
bool Get(double *r_ent, double *r_chisq, double *r_mean,
double *r_montepicalc, double *r_scc);
bool Get(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc, double* r_scc);
protected:
friend class Val;
@ -295,17 +312,17 @@ protected:
DECLARE_OPAQUE_VALUE(EntropyVal)
private:
detail::RandTest state;
};
};
class BloomFilterVal : public OpaqueVal {
class BloomFilterVal : public OpaqueVal
{
public:
explicit BloomFilterVal(probabilistic::BloomFilter* bf);
~BloomFilterVal() override;
ValPtr DoClone(CloneState* state) override;
const TypePtr& Type() const
{ return type; }
const TypePtr& Type() const { return type; }
bool Typify(TypePtr type);
@ -315,8 +332,7 @@ public:
bool Empty() const;
std::string InternalState() const;
static BloomFilterValPtr Merge(const BloomFilterVal* x,
const BloomFilterVal* y);
static BloomFilterValPtr Merge(const BloomFilterVal* x, const BloomFilterVal* y);
protected:
friend class Val;
@ -331,10 +347,10 @@ private:
TypePtr type;
detail::CompositeHash* hash;
probabilistic::BloomFilter* bloom_filter;
};
};
class CardinalityVal : public OpaqueVal {
class CardinalityVal : public OpaqueVal
{
public:
explicit CardinalityVal(probabilistic::detail::CardinalityCounter*);
~CardinalityVal() override;
@ -343,12 +359,11 @@ public:
void Add(const Val* val);
const TypePtr& Type() const
{ return type; }
const TypePtr& Type() const { return type; }
bool Typify(TypePtr type);
probabilistic::detail::CardinalityCounter* Get() { return c; };
probabilistic::detail::CardinalityCounter* Get() { return c; };
protected:
CardinalityVal();
@ -358,28 +373,30 @@ private:
TypePtr type;
detail::CompositeHash* hash;
probabilistic::detail::CardinalityCounter* c;
};
};
class ParaglobVal : public OpaqueVal {
class ParaglobVal : public OpaqueVal
{
public:
explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p);
VectorValPtr Get(StringVal* &pattern);
VectorValPtr Get(StringVal*& pattern);
ValPtr DoClone(CloneState* state) override;
bool operator==(const ParaglobVal& other) const;
protected:
ParaglobVal() : OpaqueVal(paraglob_type) {}
ParaglobVal() : OpaqueVal(paraglob_type) { }
DECLARE_OPAQUE_VALUE(ParaglobVal)
private:
std::unique_ptr<paraglob::Paraglob> internal_paraglob;
};
};
/**
* Base class for metric handles. Handle types are not serializable.
*/
class TelemetryVal : public OpaqueVal {
class TelemetryVal : public OpaqueVal
{
protected:
explicit TelemetryVal(telemetry::IntCounter);
explicit TelemetryVal(telemetry::IntCounterFamily);
@ -396,34 +413,25 @@ protected:
broker::expected<broker::data> DoSerialize() const override;
bool DoUnserialize(const broker::data& data) override;
};
};
template <class Handle>
class TelemetryValImpl : public TelemetryVal {
template <class Handle> class TelemetryValImpl : public TelemetryVal
{
public:
using HandleType = Handle;
explicit TelemetryValImpl(Handle hdl) : TelemetryVal(hdl), hdl(hdl) { }
Handle GetHandle() const noexcept
{
return hdl;
}
Handle GetHandle() const noexcept { return hdl; }
protected:
ValPtr DoClone(CloneState*) override
{
return make_intrusive<TelemetryValImpl>(hdl);
}
ValPtr DoClone(CloneState*) override { return make_intrusive<TelemetryValImpl>(hdl); }
const char* OpaqueName() const override
{
return Handle::OpaqueName;
}
const char* OpaqueName() const override { return Handle::OpaqueName; }
private:
Handle hdl;
};
};
using IntCounterMetricVal = TelemetryValImpl<telemetry::IntCounter>;
using IntCounterMetricFamilyVal = TelemetryValImpl<telemetry::IntCounterFamily>;
@ -438,4 +446,4 @@ using IntHistogramMetricFamilyVal = TelemetryValImpl<telemetry::IntHistogramFami
using DblHistogramMetricVal = TelemetryValImpl<telemetry::DblHistogram>;
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.
#include "zeek/zeek-config.h"
#include "zeek/Options.h"
#include "zeek/script_opt/ScriptOpt.h"
#include <unistd.h>
#include "zeek/script_opt/ScriptOpt.h"
#include "zeek/zeek-config.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
@ -19,7 +19,8 @@
#include "zeek/bsd-getopt-long.h"
#include "zeek/logging/writers/ascii/Ascii.h"
namespace zeek {
namespace zeek
{
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 --test [doctest-options] -- [options] [file ...]\n", prog);
fprintf(stderr, " <file> | Zeek script file, or read stdin\n");
fprintf(stderr, " -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,
" -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, " -e|--exec <zeek code> | augment loaded scripts by given code\n");
fprintf(stderr, " -f|--filter <filter> | tcpdump filter\n");
fprintf(stderr, " -h|--help | command line help\n");
fprintf(stderr, " -i|--iface <interface> | read from given interface (only one allowed)\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,
" -i|--iface <interface> | read from given interface (only one allowed)\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, " -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, " -w|--writefile <writefile> | write to given tcpdump file\n");
#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
fprintf(stderr, " -C|--no-checksums | ignore checksums\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, " -H|--save-seeds <file> | save seeds to given file\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, " -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, " -N|--print-plugins | print available plugins and exit (-NN "
"for verbose)\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, " -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, " -T|--re-level <level> | set 'RE_level' for rules\n");
fprintf(stderr, " -U|--status-file <file> | Record process status in file\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
fprintf(stderr, " -m|--mem-leaks | show leaks [perftools]\n");
fprintf(stderr, " -M|--mem-profile | record heap [perftools]\n");
#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, " --test | run unit tests ('--test -h' for help, only when compiling with ENABLE_ZEEK_UNIT_TESTS)\n");
fprintf(stderr, " $ZEEKPATH | file search path (%s)\n", util::zeek_path().c_str());
fprintf(stderr, " $ZEEK_PLUGIN_PATH | plugin search path (%s)\n", 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, " --test | run unit tests ('--test -h' for help, "
"only when compiling with ENABLE_ZEEK_UNIT_TESTS)\n");
fprintf(stderr, " $ZEEKPATH | file search path (%s)\n",
util::zeek_path().c_str());
fprintf(stderr, " $ZEEK_PLUGIN_PATH | plugin search path (%s)\n",
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_LOG_SUFFIX | ASCII log file extension (.%s)\n", logging::writer::detail::Ascii::LogExt().c_str());
fprintf(stderr, " $ZEEK_PROFILER_FILE | Output file for script execution statistics (not set)\n");
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, " $ZEEK_LOG_SUFFIX | ASCII log file extension (.%s)\n",
logging::writer::detail::Ascii::LogExt().c_str());
fprintf(stderr, " $ZEEK_PROFILER_FILE | Output file for script execution "
"statistics (not set)\n");
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");
@ -152,7 +183,8 @@ static void print_analysis_help()
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-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, " no-ZAM-opt omit low-level ZAM optimization\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
{
fprintf(stderr,"zeek: unrecognized -O/--optimize option: %s\n\n",
opt);
fprintf(stderr, "zeek: unrecognized -O/--optimize option: %s\n\n", opt);
print_analysis_help();
exit(1);
}
@ -251,17 +282,17 @@ Options parse_cmdline(int argc, char** argv)
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"
" 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);
#endif
#endif
auto is_separator = [](const char* cstr)
{
{
return strcmp(cstr, "--") == 0;
};
};
auto first = argv;
auto last = argv + argc;
auto separator = std::find_if(first, last, is_separator);
@ -285,9 +316,10 @@ Options parse_cmdline(int argc, char** argv)
if ( argc > 1 )
{
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;
for ( ; i < argc && ! endsWith(argv[i], "--"); ++i )
@ -327,53 +359,53 @@ Options parse_cmdline(int argc, char** argv)
}
constexpr struct option long_opts[] = {
{"parse-only", no_argument, nullptr, 'a'},
{"bare-mode", no_argument, nullptr, 'b'},
{"debug-script", no_argument, nullptr, 'd'},
{"exec", required_argument, nullptr, 'e'},
{"filter", required_argument, nullptr, 'f'},
{"help", no_argument, nullptr, 'h'},
{"iface", required_argument, nullptr, 'i'},
{"zeekygen", required_argument, nullptr, 'X'},
{"prefix", required_argument, nullptr, 'p'},
{"readfile", required_argument, nullptr, 'r'},
{"rulefile", required_argument, nullptr, 's'},
{"tracefile", required_argument, nullptr, 't'},
{"writefile", required_argument, nullptr, 'w'},
{"usage-issues", no_argument, nullptr, 'u'},
{"version", no_argument, nullptr, 'v'},
{"no-checksums", no_argument, nullptr, 'C'},
{"force-dns", no_argument, nullptr, 'F'},
{"deterministic", no_argument, nullptr, 'D'},
{"load-seeds", required_argument, nullptr, 'G'},
{"save-seeds", required_argument, nullptr, 'H'},
{"print-plugins", no_argument, nullptr, 'N'},
{"optimize", required_argument, nullptr, 'O'},
{"optimize-only", required_argument, nullptr, 'o'},
{"prime-dns", no_argument, nullptr, 'P'},
{"time", no_argument, nullptr, 'Q'},
{"debug-rules", no_argument, nullptr, 'S'},
{"re-level", required_argument, nullptr, 'T'},
{"watchdog", no_argument, nullptr, 'W'},
{"print-id", required_argument, nullptr, 'I'},
{"status-file", required_argument, nullptr, 'U'},
{"debug", required_argument, nullptr, 'B'},
{"parse-only", no_argument, nullptr, 'a'},
{"bare-mode", no_argument, nullptr, 'b'},
{"debug-script", no_argument, nullptr, 'd'},
{"exec", required_argument, nullptr, 'e'},
{"filter", required_argument, nullptr, 'f'},
{"help", no_argument, nullptr, 'h'},
{"iface", required_argument, nullptr, 'i'},
{"zeekygen", required_argument, nullptr, 'X'},
{"prefix", required_argument, nullptr, 'p'},
{"readfile", required_argument, nullptr, 'r'},
{"rulefile", required_argument, nullptr, 's'},
{"tracefile", required_argument, nullptr, 't'},
{"writefile", required_argument, nullptr, 'w'},
{"usage-issues", no_argument, nullptr, 'u'},
{"version", no_argument, nullptr, 'v'},
{"no-checksums", no_argument, nullptr, 'C'},
{"force-dns", no_argument, nullptr, 'F'},
{"deterministic", no_argument, nullptr, 'D'},
{"load-seeds", required_argument, nullptr, 'G'},
{"save-seeds", required_argument, nullptr, 'H'},
{"print-plugins", no_argument, nullptr, 'N'},
{"optimize", required_argument, nullptr, 'O'},
{"optimize-only", required_argument, nullptr, 'o'},
{"prime-dns", no_argument, nullptr, 'P'},
{"time", no_argument, nullptr, 'Q'},
{"debug-rules", no_argument, nullptr, 'S'},
{"re-level", required_argument, nullptr, 'T'},
{"watchdog", no_argument, nullptr, 'W'},
{"print-id", required_argument, nullptr, 'I'},
{"status-file", required_argument, nullptr, 'U'},
{"debug", required_argument, nullptr, 'B'},
#ifdef USE_PERFTOOLS_DEBUG
{"mem-leaks", no_argument, nullptr, 'm'},
{"mem-profile", no_argument, nullptr, 'M'},
#ifdef USE_PERFTOOLS_DEBUG
{"mem-leaks", no_argument, nullptr, 'm'},
{"mem-profile", no_argument, nullptr, 'M'},
#endif
{"pseudo-realtime", optional_argument, nullptr, 'E'},
{"jobs", optional_argument, nullptr, 'j'},
{"test", no_argument, nullptr, '#'},
{"pseudo-realtime", optional_argument, nullptr, 'E'},
{"jobs", optional_argument, nullptr, 'j'},
{"test", no_argument, nullptr, '#'},
{nullptr, 0, nullptr, 0},
{nullptr, 0, nullptr, 0},
};
char opts[256];
util::safe_strncpy(opts, "B:e:f:G:H:I:i:j::n:O:o:p:r:s:T:t:U:w:X:CDFMNPQSWabdhmuv",
sizeof(opts));
sizeof(opts));
int op;
int long_optsind;
@ -385,178 +417,180 @@ Options parse_cmdline(int argc, char** argv)
for ( size_t i = 0; i < zeek_args.size(); ++i )
zargs[i] = zeek_args[i].data();
while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) != EOF )
switch ( op ) {
case 'a':
rval.parse_only = true;
break;
case 'b':
rval.bare_mode = true;
break;
case 'd':
rval.debug_scripts = true;
break;
case 'e':
rval.script_code_to_exec = optarg;
break;
case 'f':
rval.pcap_filter = optarg;
break;
case 'h':
rval.print_usage = true;
break;
case 'i':
if ( rval.interface )
{
fprintf(stderr, "ERROR: Only a single interface option (-i) is allowed.\n");
exit(1);
}
if ( rval.pcap_file )
{
fprintf(stderr, "ERROR: Using -i is not allow when reading a pcap file.\n");
exit(1);
}
rval.interface = optarg;
break;
case 'j':
rval.supervisor_mode = true;
if ( optarg )
{
// TODO: for supervised offline pcap reading, the argument is
// expected to be number of workers like "-j 4" or possibly a
// list of worker/proxy/logger counts like "-j 4,2,1"
}
break;
case 'p':
rval.script_prefixes.emplace_back(optarg);
break;
case 'r':
if ( rval.pcap_file )
{
fprintf(stderr, "ERROR: Only a single readfile option (-r) is allowed.\n");
exit(1);
}
if ( rval.interface )
{
fprintf(stderr, "Using -r is not allowed when reading a live interface.\n");
exit(1);
}
rval.pcap_file = optarg;
break;
case 's':
rval.signature_files.emplace_back(optarg);
break;
case 't':
rval.debug_script_tracing_file = optarg;
break;
case 'u':
++rval.analysis_options.usage_issues;
break;
case 'v':
rval.print_version = true;
break;
case 'w':
rval.pcap_output_file = optarg;
break;
case 'B':
#ifdef DEBUG
rval.debug_log_streams = optarg;
#else
if ( util::streq(optarg, "help") )
{
fprintf(stderr,"debug streams unavailable\n");
while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) !=
EOF )
switch ( op )
{
case 'a':
rval.parse_only = true;
break;
case 'b':
rval.bare_mode = true;
break;
case 'd':
rval.debug_scripts = true;
break;
case 'e':
rval.script_code_to_exec = optarg;
break;
case 'f':
rval.pcap_filter = optarg;
break;
case 'h':
rval.print_usage = true;
break;
case 'i':
if ( rval.interface )
{
fprintf(stderr, "ERROR: Only a single interface option (-i) is allowed.\n");
exit(1);
}
#endif
break;
}
case 'C':
rval.ignore_checksums = true;
break;
case 'D':
rval.deterministic_mode = true;
break;
case 'E':
rval.pseudo_realtime = 1.0;
if ( optarg )
rval.pseudo_realtime = atof(optarg);
break;
case 'F':
if ( rval.dns_mode != detail::DNS_DEFAULT )
usage(zargs[0], 1);
rval.dns_mode = detail::DNS_FORCE;
break;
case 'G':
rval.random_seed_input_file = optarg;
break;
case 'H':
rval.random_seed_output_file = optarg;
break;
case 'I':
rval.identifier_to_print = optarg;
break;
case 'N':
++rval.print_plugins;
break;
case 'O':
set_analysis_option(optarg, rval);
break;
case 'o':
rval.analysis_options.only_func = optarg;
break;
case 'P':
if ( rval.dns_mode != detail::DNS_DEFAULT )
usage(zargs[0], 1);
rval.dns_mode = detail::DNS_PRIME;
break;
case 'Q':
rval.print_execution_time = true;
break;
case 'S':
rval.print_signature_debug_info = true;
break;
case 'T':
rval.signature_re_level = atoi(optarg);
break;
case 'U':
rval.process_status_file = optarg;
break;
case 'W':
rval.use_watchdog = true;
break;
case 'X':
rval.zeekygen_config_file = optarg;
break;
if ( rval.pcap_file )
{
fprintf(stderr, "ERROR: Using -i is not allow when reading a pcap file.\n");
exit(1);
}
rval.interface = optarg;
break;
case 'j':
rval.supervisor_mode = true;
if ( optarg )
{
// TODO: for supervised offline pcap reading, the argument is
// expected to be number of workers like "-j 4" or possibly a
// list of worker/proxy/logger counts like "-j 4,2,1"
}
break;
case 'p':
rval.script_prefixes.emplace_back(optarg);
break;
case 'r':
if ( rval.pcap_file )
{
fprintf(stderr, "ERROR: Only a single readfile option (-r) is allowed.\n");
exit(1);
}
if ( rval.interface )
{
fprintf(stderr, "Using -r is not allowed when reading a live interface.\n");
exit(1);
}
rval.pcap_file = optarg;
break;
case 's':
rval.signature_files.emplace_back(optarg);
break;
case 't':
rval.debug_script_tracing_file = optarg;
break;
case 'u':
++rval.analysis_options.usage_issues;
break;
case 'v':
rval.print_version = true;
break;
case 'w':
rval.pcap_output_file = optarg;
break;
case 'B':
#ifdef DEBUG
rval.debug_log_streams = optarg;
#else
if ( util::streq(optarg, "help") )
{
fprintf(stderr, "debug streams unavailable\n");
exit(1);
}
#endif
break;
case 'C':
rval.ignore_checksums = true;
break;
case 'D':
rval.deterministic_mode = true;
break;
case 'E':
rval.pseudo_realtime = 1.0;
if ( optarg )
rval.pseudo_realtime = atof(optarg);
break;
case 'F':
if ( rval.dns_mode != detail::DNS_DEFAULT )
usage(zargs[0], 1);
rval.dns_mode = detail::DNS_FORCE;
break;
case 'G':
rval.random_seed_input_file = optarg;
break;
case 'H':
rval.random_seed_output_file = optarg;
break;
case 'I':
rval.identifier_to_print = optarg;
break;
case 'N':
++rval.print_plugins;
break;
case 'O':
set_analysis_option(optarg, rval);
break;
case 'o':
rval.analysis_options.only_func = optarg;
break;
case 'P':
if ( rval.dns_mode != detail::DNS_DEFAULT )
usage(zargs[0], 1);
rval.dns_mode = detail::DNS_PRIME;
break;
case 'Q':
rval.print_execution_time = true;
break;
case 'S':
rval.print_signature_debug_info = true;
break;
case 'T':
rval.signature_re_level = atoi(optarg);
break;
case 'U':
rval.process_status_file = optarg;
break;
case 'W':
rval.use_watchdog = true;
break;
case 'X':
rval.zeekygen_config_file = optarg;
break;
#ifdef USE_PERFTOOLS_DEBUG
case 'm':
rval.perftools_check_leaks = 1;
break;
case 'M':
rval.perftools_profile = 1;
break;
case 'm':
rval.perftools_check_leaks = 1;
break;
case 'M':
rval.perftools_profile = 1;
break;
#endif
case '#':
fprintf(stderr, "ERROR: --test only allowed as first argument.\n");
usage(zargs[0], 1);
break;
case '#':
fprintf(stderr, "ERROR: --test only allowed as first argument.\n");
usage(zargs[0], 1);
break;
case 0:
// This happens for long options that don't have
// a short-option equivalent.
break;
case 0:
// This happens for long options that don't have
// a short-option equivalent.
break;
case '?':
default:
usage(zargs[0], 1);
break;
}
case '?':
default:
usage(zargs[0], 1);
break;
}
// Process remaining arguments. X=Y arguments indicate script
// variable/parameter assignments. X::Y arguments indicate plugins to
@ -572,7 +606,7 @@ Options parse_cmdline(int argc, char** argv)
}
auto canonify_script_path = [](std::string* path)
{
{
if ( path->empty() )
return;
@ -605,13 +639,12 @@ Options parse_cmdline(int argc, char** argv)
if ( ! getcwd(cwd, sizeof(cwd)) )
{
fprintf(stderr, "failed to get current directory: %s\n",
strerror(errno));
fprintf(stderr, "failed to get current directory: %s\n", strerror(errno));
exit(1);
}
*path = std::string(cwd) + "/" + *path;
};
};
if ( rval.supervisor_mode )
{
@ -625,4 +658,4 @@ Options parse_cmdline(int argc, char** argv)
return rval;
}
} // namespace zeek
} // namespace zeek

View file

@ -9,13 +9,15 @@
#include "zeek/DNS_Mgr.h"
#include "zeek/script_opt/ScriptOpt.h"
namespace zeek {
namespace zeek
{
/**
* Options that define general Zeek processing behavior, usually determined
* from command-line arguments.
*/
struct Options {
struct Options
{
/**
* 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
@ -40,7 +42,7 @@ struct Options {
std::optional<std::string> identifier_to_print;
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;
bool ignore_checksums = false;
@ -79,7 +81,7 @@ struct Options {
// For script optimization:
detail::AnalyOpt analysis_options;
};
};
/**
* Parse Zeek command-line arguments.
@ -101,4 +103,4 @@ void usage(const char* prog, int code = 1);
*/
bool fake_dns();
} // namespace zeek
} // namespace zeek

View file

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

View file

@ -4,7 +4,8 @@
#include "zeek/Type.h"
namespace zeek::detail {
namespace zeek::detail
{
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)
{
return v < static_cast<double>(INT64_MIN) ||
v > static_cast<double>(INT64_MAX);
return v < static_cast<double>(INT64_MIN) || v > static_cast<double>(INT64_MAX);
}
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;
}
extern bool would_overflow(const zeek::Type* from_type,
const zeek::Type* to_type, const Val* val);
extern bool would_overflow(const zeek::Type* from_type, const zeek::Type* to_type, const Val* val);
}
}

View file

@ -1,7 +1,9 @@
#include "zeek/PacketFilter.h"
#include "zeek/IP.h"
namespace zeek::detail {
namespace zeek::detail
{
void PacketFilter::DeleteFilter(void* data)
{
@ -82,40 +84,39 @@ bool PacketFilter::RemoveDst(Val* dst)
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 )
return MatchFilter(*f, *ip, len, caplen);
f = (Filter*) dst_filter.Lookup(ip->DstAddr(), 128);
f = (Filter*)dst_filter.Lookup(ip->DstAddr(), 128);
if ( f )
return MatchFilter(*f, *ip, len, caplen);
return default_match;
}
bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip,
int len, int caplen)
bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip, int len, int caplen)
{
if ( ip.NextProto() == IPPROTO_TCP && f.tcp_flags )
{
// Caution! The packet sanity checks have not been performed yet
int ip_hdr_len = ip.HdrLen();
len -= ip_hdr_len; // remove IP header
len -= ip_hdr_len; // remove IP header
caplen -= ip_hdr_len;
if ( (unsigned int) len < sizeof(struct tcphdr) ||
(unsigned int) caplen < sizeof(struct tcphdr) )
if ( (unsigned int)len < sizeof(struct tcphdr) ||
(unsigned int)caplen < sizeof(struct tcphdr) )
// Packet too short, will be dropped anyway.
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 )
// At least one of the flags is set, so don't drop
// At least one of the flags is set, so don't drop
return false;
}
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/PrefixTable.h"
namespace zeek {
namespace zeek
{
class IP_Hdr;
class Val;
namespace detail {
namespace detail
{
class PacketFilter {
class PacketFilter
{
public:
explicit PacketFilter(bool arg_default);
~PacketFilter() {}
~PacketFilter() { }
// 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
@ -38,10 +41,11 @@ public:
bool Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen);
private:
struct Filter {
struct Filter
{
uint32_t tcp_flags;
double probability;
};
};
static void DeleteFilter(void* data);
@ -50,7 +54,7 @@ private:
bool default_match;
PrefixTable src_filter;
PrefixTable dst_filter;
};
};
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

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

View file

@ -2,11 +2,12 @@
#pragma once
namespace zeek::detail {
namespace zeek::detail
{
class Pipe {
class Pipe
{
public:
/**
* 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.
@ -17,12 +18,12 @@ public:
* than create ones from a new pipe. Should point to memory containing
* two consecutive file descriptors, the "read" one and then the "write" one.
*/
explicit Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0,
int status_flags1 = 0, int* fds = nullptr);
explicit Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0, int status_flags1 = 0,
int* fds = nullptr);
/**
* Close the pair of file descriptors owned by the object.
*/
* Close the pair of file descriptors owned by the object.
*/
~Pipe();
/**
@ -39,14 +40,12 @@ public:
/**
* @return the file descriptor associated with the read-end of the pipe.
*/
int ReadFD() const
{ return fds[0]; }
int ReadFD() const { return fds[0]; }
/**
* @return the file descriptor associated with the write-end of the pipe.
*/
int WriteFD() const
{ return fds[1]; }
int WriteFD() const { return fds[1]; }
/**
* Sets the given file descriptor flags for both the read and write end
@ -64,14 +63,14 @@ private:
int fds[2];
int flags[2];
int status_flags[2];
};
};
/**
* A pair of pipes that can be used for bi-directinoal IPC.
*/
class PipePair {
class PipePair
{
public:
/**
* Create a pair of pipes
* @param flags file descriptor flags to set on pipes
@ -87,53 +86,45 @@ public:
/**
* @return the pipe used for receiving input
*/
Pipe& In()
{ return pipes[swapped]; }
Pipe& In() { return pipes[swapped]; }
/**
* @return the pipe used for sending output
*/
Pipe& Out()
{ return pipes[!swapped]; }
Pipe& Out() { return pipes[! swapped]; }
/**
* @return the pipe used for receiving input
*/
const Pipe& In() const
{ return pipes[swapped]; }
const Pipe& In() const { return pipes[swapped]; }
/**
* @return the pipe used for sending output
*/
const Pipe& Out() const
{ return pipes[!swapped]; }
const Pipe& Out() const { return pipes[! swapped]; }
/**
* @return a file descriptor that may used for receiving messages by
* polling/reading it.
*/
int InFD() const
{ return In().ReadFD(); }
int InFD() const { return In().ReadFD(); }
/**
* @return a file descriptor that may be used for sending messages by
* writing to it.
*/
int OutFD() const
{ return Out().WriteFD(); }
int OutFD() const { return Out().WriteFD(); }
/**
* 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
* reading/writing.
*/
void Swap()
{ swapped = ! swapped; }
void Swap() { swapped = ! swapped; }
private:
Pipe pipes[2];
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 <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <map>
#include <string>
#include <vector>
#include <map>
#include "zeek/Debug.h"
#include "zeek/util.h"
#include "zeek/Reporter.h"
#include "zeek/util.h"
#include "zeek/zeek-config.h"
using namespace std;
struct PolicyFile {
PolicyFile () { filedata = nullptr; lmtime = 0; }
~PolicyFile () { delete [] filedata; filedata = nullptr; }
struct PolicyFile
{
PolicyFile()
{
filedata = nullptr;
lmtime = 0;
}
~PolicyFile()
{
delete[] filedata;
filedata = nullptr;
}
time_t lmtime;
char* filedata;
vector<const char*> lines;
};
};
typedef map<string, PolicyFile*> PolicyFileMap;
static PolicyFileMap policy_files;
namespace zeek::detail {
namespace zeek::detail
{
int how_many_lines_in(const char* policy_filename)
{
@ -97,9 +106,9 @@ bool LoadPolicyFileText(const char* policy_filename)
// ### This code is not necessarily Unicode safe!
// (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 )
reporter->InternalError("Failed to fread() file data");
reporter->InternalError("Failed to fread() file data");
pf->filedata[size] = 0;
fclose(f);
@ -122,8 +131,8 @@ bool LoadPolicyFileText(const char* policy_filename)
}
// REMEMBER: line number arguments are indexed from 0.
bool PrintLines(const char* policy_filename, unsigned int start_line,
unsigned int how_many_lines, bool show_numbers)
bool PrintLines(const char* policy_filename, unsigned int start_line, unsigned int how_many_lines,
bool show_numbers)
{
if ( ! policy_filename )
return true;
@ -157,8 +166,8 @@ bool PrintLines(const char* policy_filename, unsigned int start_line,
if ( start_line > pf->lines.size() )
{
debug_msg("Line number %d out of range; %s has %d lines\n",
start_line, policy_filename, int(pf->lines.size()));
debug_msg("Line number %d out of range; %s has %d lines\n", start_line, policy_filename,
int(pf->lines.size()));
return false;
}
@ -177,4 +186,4 @@ bool PrintLines(const char* policy_filename, unsigned int start_line,
return true;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

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

View file

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

View file

@ -1,33 +1,42 @@
#pragma once
extern "C" {
#include "zeek/patricia.h"
}
extern "C"
{
#include "zeek/patricia.h"
}
#include <tuple>
#include <list>
#include <tuple>
#include "zeek/IPAddr.h"
namespace zeek {
namespace zeek
{
class Val;
class SubNetVal;
namespace detail {
namespace detail
{
class PrefixTable {
class PrefixTable
{
private:
struct iterator {
patricia_node_t* Xstack[PATRICIA_MAXBITS+1];
struct iterator
{
patricia_node_t* Xstack[PATRICIA_MAXBITS + 1];
patricia_node_t** Xsp;
patricia_node_t* Xrn;
patricia_node_t* Xnode;
};
};
public:
PrefixTable() { tree = New_Patricia(128); delete_function = nullptr; }
~PrefixTable() { Destroy_Patricia(tree, delete_function); }
PrefixTable()
{
tree = New_Patricia(128);
delete_function = nullptr;
}
~PrefixTable() { Destroy_Patricia(tree, delete_function); }
// Addr in network byte order. If data is zero, acts like a set.
// Returns ptr to old data if already existing.
@ -51,10 +60,10 @@ public:
void* Remove(const IPAddr& addr, int width);
void* Remove(const Val* value);
void Clear() { Clear_Patricia(tree, delete_function); }
void Clear() { Clear_Patricia(tree, delete_function); }
// Sets a function to call for each node when table is cleared/destroyed.
void SetDeleteFunction(data_fn_t del_fn) { delete_function = del_fn; }
void SetDeleteFunction(data_fn_t del_fn) { delete_function = del_fn; }
iterator InitIterator();
void* GetNext(iterator* i);
@ -65,7 +74,7 @@ private:
patricia_tree_t* tree;
data_fn_t delete_function;
};
};
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

@ -1,6 +1,5 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/zeek-config.h"
#include "zeek/PriorityQueue.h"
#include <stdio.h>
@ -8,8 +7,10 @@
#include "zeek/Reporter.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)
{
@ -21,7 +22,7 @@ PriorityQueue::~PriorityQueue()
for ( int i = 0; i < heap_size; ++i )
delete heap[i];
delete [] heap;
delete[] heap;
}
PQ_Element* PriorityQueue::Remove()
@ -35,15 +36,14 @@ PQ_Element* PriorityQueue::Remove()
SetElement(0, heap[heap_size]);
BubbleDown(0);
top->SetOffset(-1); // = not in heap
top->SetOffset(-1); // = not in heap
return top;
}
PQ_Element* PriorityQueue::Remove(PQ_Element* e)
{
if ( e->Offset() < 0 || e->Offset() >= heap_size ||
heap[e->Offset()] != e )
return nullptr; // not in heap
if ( e->Offset() < 0 || e->Offset() >= heap_size || heap[e->Offset()] != e )
return nullptr; // not in heap
e->MinimizeTime();
BubbleUp(e->Offset());
@ -79,7 +79,7 @@ bool PriorityQueue::Resize(int new_size)
for ( int i = 0; i < max_heap_size; ++i )
tmp[i] = heap[i];
delete [] heap;
delete[] heap;
heap = tmp;
max_heap_size = new_size;
@ -108,7 +108,7 @@ void PriorityQueue::BubbleDown(int bin)
int r = RightChild(bin);
if ( l >= heap_size )
return; // No children.
return; // No children.
if ( r >= heap_size )
{ // Just a left child.
@ -138,4 +138,4 @@ void PriorityQueue::BubbleDown(int bin)
}
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -2,34 +2,37 @@
#pragma once
#include "zeek/zeek-config.h"
#include <math.h>
#include <stdint.h>
namespace zeek::detail {
#include "zeek/zeek-config.h"
namespace zeek::detail
{
class PriorityQueue;
class PQ_Element {
class PQ_Element
{
public:
explicit PQ_Element(double t) : time(t) {}
explicit PQ_Element(double t) : time(t) { }
virtual ~PQ_Element() = default;
double Time() const { return time; }
double Time() const { return time; }
int Offset() const { return offset; }
void SetOffset(int off) { offset = off; }
int Offset() const { return offset; }
void SetOffset(int off) { offset = off; }
void MinimizeTime() { time = -HUGE_VAL; }
void MinimizeTime() { time = -HUGE_VAL; }
protected:
PQ_Element() = default;
double time = 0.0;
int offset = -1;
};
};
class PriorityQueue {
class PriorityQueue
{
public:
explicit PriorityQueue(int initial_size = 16);
~PriorityQueue();
@ -55,8 +58,8 @@ public:
// memory to add the element), true on success.
bool Add(PQ_Element* e);
int Size() const { return heap_size; }
int PeakSize() const { return peak_heap_size; }
int Size() const { return heap_size; }
int PeakSize() const { return peak_heap_size; }
uint64_t CumulativeNum() const { return cumulative_num; }
protected:
@ -65,20 +68,11 @@ protected:
void BubbleUp(int bin);
void BubbleDown(int bin);
int Parent(int bin) const
{
return bin >> 1;
}
int Parent(int bin) const { return bin >> 1; }
int LeftChild(int bin) const
{
return bin << 1;
}
int LeftChild(int bin) const { return bin << 1; }
int RightChild(int bin) const
{
return LeftChild(bin) + 1;
}
int RightChild(int bin) const { return LeftChild(bin) + 1; }
void SetElement(int bin, PQ_Element* e)
{
@ -98,6 +92,6 @@ protected:
int peak_heap_size = 0;
int max_heap_size = 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
// sizeof(data) <= sizeof(void*).
namespace zeek {
namespace zeek
{
template<typename T>
class [[deprecated("Remove in v5.1. This class is deprecated (and is likely broken, see #1528). Use std::vector<T>.")]] Queue {
template <typename T>
class [[deprecated("Remove in v5.1. This class is deprecated (and is likely broken, see #1528). "
"Use std::vector<T>.")]] Queue
{
public:
explicit Queue(int size = 0)
{
@ -42,7 +45,7 @@ public:
}
else
{
if ( (entries = new T[chunk_size+1]) )
if ( (entries = new T[chunk_size + 1]) )
max_entries = chunk_size;
else
{
@ -52,11 +55,11 @@ public:
}
}
~Queue() { delete[] entries; }
~Queue() { delete[] entries; }
int length() const { return num_entries; }
int capacity() const { return max_entries; }
int resize(int new_size = 0) // 0 => size to fit current number of entries
int length() const { return num_entries; }
int capacity() const { return max_entries; }
int resize(int new_size = 0) // 0 => size to fit current number of entries
{
if ( new_size < num_entries )
new_size = num_entries; // do not lose any entries
@ -66,22 +69,19 @@ public:
// Note, allocate extra space, so that we can always
// use the [max_entries] element.
// ### 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 ( head <= tail )
memcpy( new_entries, entries + head,
sizeof(T) * num_entries );
memcpy(new_entries, entries + head, sizeof(T) * num_entries);
else
{
int len = num_entries - tail;
memcpy( new_entries, entries + head,
sizeof(T) * len );
memcpy( new_entries + len, entries,
sizeof(T) * tail );
memcpy(new_entries, entries + head, sizeof(T) * len);
memcpy(new_entries + len, entries, sizeof(T) * tail);
}
delete [] entries;
delete[] entries;
entries = new_entries;
max_entries = new_size;
head = 0;
@ -96,19 +96,19 @@ public:
}
// remove all entries without delete[] entry
void clear() { head = tail = num_entries = 0; }
void clear() { head = tail = num_entries = 0; }
// helper functions for iterating over queue
T& front() { return entries[head]; }
T& back() { return entries[tail]; }
const T& front() const { return entries[head]; }
const T& back() const { return entries[tail]; }
T& front() { return entries[head]; }
T& back() { return entries[tail]; }
const T& front() const { return entries[head]; }
const T& back() const { return entries[tail]; }
void push_front(const T& a) // add in front of queue
void push_front(const T& a) // add in front of queue
{
if ( num_entries == max_entries )
{
resize(max_entries+chunk_size); // make more room
resize(max_entries + chunk_size); // make more room
chunk_size *= 2;
}
@ -122,11 +122,11 @@ public:
}
}
void push_back(const T& a) // add at end of queue
void push_back(const T& a) // add at end of queue
{
if ( num_entries == max_entries )
{
resize(max_entries+chunk_size); // make more room
resize(max_entries + chunk_size); // make more room
chunk_size *= 2;
}
@ -159,7 +159,7 @@ public:
}
// return nth *PHYSICAL* entry of queue (do not remove)
T& operator[](int i) const { return entries[i]; }
T& operator[](int i) const { return entries[i]; }
// Type traits needed for some of the std algorithms to work
using value_type = T;
@ -187,17 +187,16 @@ public:
const_reverse_iterator crend() const { return rend(); }
protected:
T* entries;
int chunk_size; // increase size by this amount when necessary
int max_entries; // entry's index range: 0 .. max_entries
int chunk_size; // increase size by this amount when necessary
int max_entries; // entry's index range: 0 .. max_entries
int num_entries;
int head; // beginning of the queue in the ring
int tail; // just beyond the end of the queue in the ring
int head; // beginning 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>
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
} // namespace zeek

View file

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

View file

@ -2,27 +2,29 @@
#pragma once
#include <sys/types.h> // for u_char
#include <ctype.h>
#include <set>
#include <sys/types.h> // for u_char
#include <map>
#include <set>
#include <string>
#include "zeek/List.h"
#include "zeek/CCL.h"
#include "zeek/EquivClass.h"
#include "zeek/List.h"
typedef int (*cce_func)(int);
// This method is automatically generated by flex and shouldn't be namespaced
extern int re_lex(void);
namespace zeek {
namespace zeek
{
class String;
class RE_Matcher;
namespace detail {
namespace detail
{
class NFA_Machine;
class DFA_Machine;
@ -45,21 +47,26 @@ using MatchPos = uint64_t;
using AcceptingMatchSet = std::map<AcceptIdx, MatchPos>;
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
// MATCH_ANYWHERE or MATCH_EXACTLY.
class Specific_RE_Matcher {
class Specific_RE_Matcher
{
public:
explicit Specific_RE_Matcher(match_type mt, int multiline=0);
explicit Specific_RE_Matcher(match_type mt, int multiline = 0);
~Specific_RE_Matcher();
void AddPat(const char* pat);
void MakeCaseInsensitive();
void SetPat(const char* pat) { pattern_text = util::copy_string(pat); }
void SetPat(const char* pat) { pattern_text = util::copy_string(pat); }
bool Compile(bool lazy = false);
@ -82,7 +89,7 @@ public:
return nullptr;
}
CCL* LookupCCL(int index) { return ccl_list[index]; }
CCL* LookupCCL(int index) { return ccl_list[index]; }
CCL* AnyCCL();
void ConvertCCLs();
@ -107,16 +114,17 @@ public:
int LongestMatch(const String* s);
int LongestMatch(const u_char* bv, int n);
EquivClass* EC() { return &equiv_class; }
EquivClass* EC() { return &equiv_class; }
const char* PatternText() const { return pattern_text; }
const char* PatternText() const { return pattern_text; }
DFA_Machine* DFA() const { return dfa; }
DFA_Machine* DFA() const { return dfa; }
void Dump(FILE* f);
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See GHI-572.")]]
unsigned int MemoryAllocation() const;
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const;
protected:
void AddAnywherePat(const char* pat);
@ -142,9 +150,10 @@ protected:
DFA_Machine* dfa;
CCL* any_ccl;
AcceptingSet* accepted;
};
};
class RE_Match_State {
class RE_Match_State
{
public:
explicit RE_Match_State(Specific_RE_Matcher* matcher)
{
@ -154,11 +163,10 @@ public:
current_state = nullptr;
}
const AcceptingMatchSet& AcceptedMatches() const
{ return accepted_matches; }
const AcceptingMatchSet& AcceptedMatches() const { return accepted_matches; }
// Returns the number of bytes feeded into the matcher so far
int Length() { return current_pos; }
int Length() { return current_pos; }
// Returns true if this inputs leads to at least one new match.
// If clear is true, starts matching over.
@ -180,14 +188,15 @@ protected:
AcceptingMatchSet accepted_matches;
DFA_State* current_state;
int current_pos;
};
};
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);
} // namespace detail
} // namespace detail
class RE_Matcher final {
class RE_Matcher final
{
public:
RE_Matcher();
explicit RE_Matcher(const char* pat);
@ -198,49 +207,42 @@ public:
// Makes the matcher as specified to date case-insensitive.
void MakeCaseInsensitive();
bool IsCaseInsensitive() const { return is_case_insensitive; }
bool IsCaseInsensitive() const { return is_case_insensitive; }
bool Compile(bool lazy = false);
// Returns true if s exactly matches the pattern, false otherwise.
bool MatchExactly(const char* s)
{ return re_exact->MatchAll(s); }
bool MatchExactly(const String* s)
{ return re_exact->MatchAll(s); }
bool MatchExactly(const char* 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
// occurs, or 0 if there is no such position in s. Note that
// if the pattern matches empty strings, matching continues
// in an attempt to match at least one character.
int MatchAnywhere(const char* s)
{ return re_anywhere->Match(s); }
int MatchAnywhere(const String* s)
{ return re_anywhere->Match(s); }
int MatchAnywhere(const char* 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
// length of matched prefix. It returns -1 on mismatch.
int MatchPrefix(const char* s)
{ return re_exact->LongestMatch(s); }
int MatchPrefix(const String* s)
{ return re_exact->LongestMatch(s); }
int MatchPrefix(const u_char* s, int n)
{ return re_exact->LongestMatch(s, n); }
int MatchPrefix(const char* s) { return re_exact->LongestMatch(s); }
int MatchPrefix(const String* s) { 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* AnywherePatternText() const { return re_anywhere->PatternText(); }
const char* PatternText() const { return re_exact->PatternText(); }
const char* AnywherePatternText() const { return re_anywhere->PatternText(); }
// Original text used to construct this matcher. Empty unless
// 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.")]]
unsigned int MemoryAllocation() const
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
"GHI-572.")]] unsigned int
MemoryAllocation() const
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return padded_sizeof(*this)
+ (re_anywhere ? re_anywhere->MemoryAllocation() : 0)
+ (re_exact ? re_exact->MemoryAllocation() : 0);
return padded_sizeof(*this) + (re_anywhere ? re_anywhere->MemoryAllocation() : 0) +
(re_exact ? re_exact->MemoryAllocation() : 0);
#pragma GCC diagnostic pop
}
@ -251,6 +253,6 @@ protected:
detail::Specific_RE_Matcher* re_exact;
bool is_case_insensitive = false;
};
};
} // namespace zeek
} // namespace zeek

View file

@ -1,15 +1,15 @@
/*
Apply various randomness tests to a stream of bytes
Apply various randomness tests to a stream of bytes
by John Walker -- September 1996
http://www.fourmilab.ch/random
by John Walker -- September 1996
http://www.fourmilab.ch/random
This software is in the public domain. Permission to use, copy, modify,
and distribute this software and its documentation for any purpose and
without fee is hereby granted, without any conditions or restrictions.
This software is provided as is without express or implied warranty.
This software is in the public domain. Permission to use, copy, modify,
and distribute this software and its documentation for any purpose and
without fee is hereby granted, without any conditions or restrictions.
This software is provided as is without express or implied warranty.
Modified for Bro by Seth Hall - July 2010
Modified for Bro by Seth Hall - July 2010
*/
#include "zeek/RandTest.h"
@ -20,14 +20,15 @@ constexpr double log2of10 = 3.32192809488736234787;
/* RT_LOG2 -- Calculate log to the base 2 */
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);
constexpr double RT_INCIRC = 281474943156225.0;
namespace zeek::detail {
namespace zeek::detail
{
RandTest::RandTest()
{
@ -37,45 +38,45 @@ RandTest::RandTest()
inmont = mcount = 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;
}
}
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;
while (bufl-- > 0)
while ( bufl-- > 0 )
{
oc = *bp++;
ccount[oc]++; /* Update counter for this bin */
ccount[oc]++; /* Update counter for this bin */
totalc++;
/* Update inside / outside circle counts for Monte Carlo
computation of PI */
monte[mp++] = oc; /* Save character for Monte Carlo */
if (mp >= RT_MONTEN) /* Calculate every RT_MONTEN character */
computation of PI */
monte[mp++] = oc; /* Save character for Monte Carlo */
if ( mp >= RT_MONTEN ) /* Calculate every RT_MONTEN character */
{
mp = 0;
mcount++;
montex = 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];
montey = (montey * 256.0) + monte[(RT_MONTEN / 2) + mj];
}
if (montex*montex + montey*montey <= RT_INCIRC)
if ( montex * montex + montey * montey <= RT_INCIRC )
{
inmont++;
}
}
/* Update calculation of serial correlation coefficient */
if (sccfirst)
if ( sccfirst )
{
sccfirst = 0;
scclast = 0;
@ -93,42 +94,45 @@ void RandTest::add(const void *buf, int bufl)
}
}
void RandTest::end(double* r_ent, double* r_chisq,
double* r_mean, double* r_montepicalc, double* r_scc)
void RandTest::end(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc,
double* r_scc)
{
int i;
double ent, chisq, scc, datasum;
ent = 0.0; chisq = 0.0; scc = 0.0; datasum = 0.0;
double prob[256]; /* Probabilities per bin for entropy */
ent = 0.0;
chisq = 0.0;
scc = 0.0;
datasum = 0.0;
double prob[256]; /* Probabilities per bin for entropy */
/* Complete calculation of serial correlation coefficient */
scct1 = scct1 + scclast * sccu0;
scct2 = scct2 * scct2;
scc = totalc * scct3 - scct2;
if (scc == 0.0)
scc = -100000;
if ( scc == 0.0 )
scc = -100000;
else
scc = (totalc * scct1 - scct2) / scc;
scc = (totalc * scct1 - scct2) / scc;
/* Scan bins and calculate probability for each bin and
Chi-Square distribution. The probability will be reused
in the entropy calculation below. While we're at it,
we sum of all the data which will be used to compute the
mean. */
cexp = totalc / 256.0; /* Expected count per bin */
for (i = 0; i < 256; i++)
cexp = totalc / 256.0; /* Expected count per bin */
for ( i = 0; i < 256; i++ )
{
double a = ccount[i] - cexp;
prob[i] = ((double) ccount[i]) / totalc;
prob[i] = ((double)ccount[i]) / totalc;
chisq += (a * a) / cexp;
datasum += ((double) i) * ccount[i];
datasum += ((double)i) * ccount[i];
}
/* 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]);
}
@ -136,7 +140,7 @@ void RandTest::end(double* r_ent, double* r_chisq,
/* Calculate Monte Carlo value for PI from percentage of hits
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 */
*r_ent = ent;
@ -146,4 +150,4 @@ void RandTest::end(double* r_ent, double* r_chisq,
*r_scc = scc;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -1,38 +1,41 @@
#pragma once
#include "zeek/zeek-config.h"
#include <stdint.h>
#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. */
#include "zeek/zeek-config.h"
namespace zeek {
#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. */
namespace zeek
{
class EntropyVal;
namespace detail {
namespace detail
{
class RandTest {
class RandTest
{
public:
RandTest();
void add(const void* buf, int bufl);
void end(double* r_ent, double* r_chisq, double* r_mean,
double* r_montepicalc, double* r_scc);
void end(double* r_ent, double* r_chisq, double* r_mean, double* r_montepicalc, double* r_scc);
private:
friend class zeek::EntropyVal;
int64_t ccount[256]; /* Bins to count occurrences of values */
int64_t totalc; /* Total bytes counted */
int64_t ccount[256]; /* Bins to count occurrences of values */
int64_t totalc; /* Total bytes counted */
int mp;
int sccfirst;
unsigned int monte[RT_MONTEN];
int64_t inmont, mcount;
double cexp, montex, montey, montepi,
sccu0, scclast, scct1, scct2, scct3;
};
double cexp, montex, montey, montepi, sccu0, scclast, scct1, scct2, scct3;
};
} // namespace detail
} // namespace zeek
} // namespace detail
} // namespace zeek

View file

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