mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/timw/386-clang-format'
* origin/topic/timw/386-clang-format: Minor fixes for build problems after reformatting Reformat the world Fixes for includes ahead of reformatting GH-386: Add clang-format config and scripts
This commit is contained in:
commit
9068b71750
723 changed files with 35332 additions and 35168 deletions
98
.clang-format
Normal file
98
.clang-format
Normal file
|
@ -0,0 +1,98 @@
|
|||
# Clang-format configuration for Zeek. This configuration requires
|
||||
# at least clang-format 12.0.1 to format correctly.
|
||||
#
|
||||
# The easiest way to run this from the command-line is using the
|
||||
# python script in auxil/run-clang-format:
|
||||
#
|
||||
# python3 auxil/run-clang-format/run-clang-format.py --clang-format-executable /path/to/clang-format -r src -i
|
||||
|
||||
Language: Cpp
|
||||
Standard: c++17
|
||||
|
||||
BreakBeforeBraces: Whitesmiths
|
||||
|
||||
# BraceWrapping:
|
||||
# AfterCaseLabel: true
|
||||
# AfterClass: false
|
||||
# AfterControlStatement: Always
|
||||
# AfterEnum: false
|
||||
# AfterFunction: true
|
||||
# AfterNamespace: false
|
||||
# AfterStruct: false
|
||||
# AfterUnion: false
|
||||
# AfterExternBlock: false
|
||||
# BeforeCatch: true
|
||||
# BeforeElse: true
|
||||
# BeforeWhile: false
|
||||
# IndentBraces: true
|
||||
# SplitEmptyFunction: false
|
||||
# SplitEmptyRecord: false
|
||||
# SplitEmptyNamespace: false
|
||||
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: true
|
||||
AlignTrailingComments: false
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
ColumnLimit: 100
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
FixNamespaceComments: false
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: true
|
||||
IndentExternBlock: NoIndent
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
NamespaceIndentation: None
|
||||
PointerAlignment: Left
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: true
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
TabWidth: 4
|
||||
UseTab: AlignWithSpaces
|
||||
|
||||
IncludeBlocks: Regroup
|
||||
|
||||
# Include categories go like this:
|
||||
# 0: reserved, since this automatically is the primary header for any .cc file
|
||||
# 1: zeek-config.h
|
||||
# 2: any c-style header
|
||||
# 3: any c++-style header
|
||||
# 4: any header that starts with "zeek/"
|
||||
# 5: everything else, which should catch any of the auto-generated code from the
|
||||
# build directory as well
|
||||
#
|
||||
# Sections 0-1 and 2-3 get group together in their respective blocks
|
||||
IncludeCategories:
|
||||
- Regex: '^"zeek-config\.h"'
|
||||
Priority: 0
|
||||
SortPriority: 1
|
||||
- Regex: '^<[[:print:]]+\.(h|hh)>'
|
||||
Priority: 2
|
||||
SortPriority: 2
|
||||
- Regex: '^<[[:print:]]+>'
|
||||
Priority: 2
|
||||
SortPriority: 3
|
||||
- Regex: '^"zeek/'
|
||||
Priority: 4
|
||||
- Regex: '.*'
|
||||
Priority: 5
|
17
.clang-format-ignore
Normal file
17
.clang-format-ignore
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Ignore everything 3rdparty
|
||||
src/3rdparty/*
|
||||
|
||||
# These are files that are technically sourced from other places but aren't in 3rdparty
|
||||
# and shouldn't be reformatted.
|
||||
src/ConvertUTF.*
|
||||
src/bro_inet_ntop.*
|
||||
src/bsd-getopt-long.*
|
||||
src/in_cksum.*
|
||||
src/nb_dns.*
|
||||
src/modp_numtoa.*
|
||||
src/patricia.*
|
||||
src/strsep.c
|
||||
src/setsignal.c
|
||||
|
||||
# These files are generated code
|
||||
src/DebugCmdInfoConstants.*
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -49,3 +49,6 @@
|
|||
[submodule "auxil/zeek-client"]
|
||||
path = auxil/zeek-client
|
||||
url = https://github.com/zeek/zeek-client
|
||||
[submodule "auxil/run-clang-format"]
|
||||
path = auxil/run-clang-format
|
||||
url = https://github.com/Sarcasm/run-clang-format
|
||||
|
|
9
CHANGES
9
CHANGES
|
@ -1,3 +1,12 @@
|
|||
4.2.0-dev.174 | 2021-09-16 15:36:52 -0700
|
||||
|
||||
* Minor fixes for build problems after reformatting (Tim Wojtulewicz, Corelight)
|
||||
|
||||
* Reformat the world (Tim Wojtulewicz, Corelight)
|
||||
|
||||
* Fixes for includes ahead of reformatting (Tim Wojtulewicz, Corelight)
|
||||
|
||||
* GH-386: Add clang-format config and scripts (Tim Wojtulewicz, Corelight)
|
||||
|
||||
4.2.0-dev.169 | 2021-09-16 11:15:14 +0200
|
||||
|
||||
|
|
8
NEWS
8
NEWS
|
@ -9,6 +9,14 @@ Zeek 4.2.0
|
|||
New Functionality
|
||||
-----------------
|
||||
|
||||
- Zeek now supports formatting the C++ code using clang-format. It requires at
|
||||
least clang-format 12.0.1 due to some additions that were made in that version
|
||||
to better support the Whitesmiths style. Zeek also includes a set of python
|
||||
scripts to more easily reformat in the auxil/run-clang-format directory. An
|
||||
example command to reformat the code:
|
||||
|
||||
`python3 auxil/run-clang-format/run-clang-format.py --clang-format-executable `which clang-format-12` -r src -i`
|
||||
|
||||
Changed Functionality
|
||||
---------------------
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
4.2.0-dev.169
|
||||
4.2.0-dev.174
|
||||
|
|
1
auxil/run-clang-format
Submodule
1
auxil/run-clang-format
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 39081c9c42768ab5e8321127a7494ad1647c6a2f
|
65
ci/run-clang-format.sh
Executable file
65
ci/run-clang-format.sh
Executable file
|
@ -0,0 +1,65 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2020 by the Zeek Project. See LICENSE for details.
|
||||
|
||||
base=$(git rev-parse --show-toplevel)
|
||||
fix=0
|
||||
pre_commit_hook=0
|
||||
|
||||
# Directories to run on by default. When changing, adapt .pre-commit-config.yam
|
||||
# as well.
|
||||
files="src"
|
||||
|
||||
error() {
|
||||
test "${pre_commit_hook}" = 0 && echo "$@" >&2 && exit 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
if [ $# != 0 ]; then
|
||||
case "$1" in
|
||||
--fixit)
|
||||
shift
|
||||
fix=1
|
||||
;;
|
||||
|
||||
--pre-commit-hook)
|
||||
shift
|
||||
fix=1
|
||||
pre_commit_hook=1
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo "usage: $(basename $0) [--fixit | --pre-commit-hook] [<files>]"
|
||||
exit 1
|
||||
esac
|
||||
fi
|
||||
|
||||
test $# != 0 && files="$@"
|
||||
|
||||
if [ -z "${CLANG_FORMAT}" ]; then
|
||||
CLANG_FORMAT=$(which clang-format 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -z "${CLANG_FORMAT}" -o ! -x "${CLANG_FORMAT}" ]; then
|
||||
error "Cannot find clang-format. If not in PATH, set CLANG_FORMAT."
|
||||
fi
|
||||
|
||||
if ! (cd / && ${CLANG_FORMAT} -dump-config | grep -q SpacesInConditionalStatement); then
|
||||
error "${CLANG_FORMAT} does not support SpacesInConditionalStatement. Install custom version and put it into PATH, or point CLANG_FORMAT to it."
|
||||
fi
|
||||
|
||||
if [ ! -e .clang-format ]; then
|
||||
error "Must execute in top-level directory."
|
||||
fi
|
||||
|
||||
cmd="${base}/auxil/run-clang-format/run-clang-format.py -r --clang-format-executable ${CLANG_FORMAT} --exclude '*/3rdparty/*' ${files}"
|
||||
tmp=/tmp/$(basename $0).$$.tmp
|
||||
trap "rm -f ${tmp}" EXIT
|
||||
eval "${cmd}" >"${tmp}"
|
||||
|
||||
if [ "${fix}" = 1 ]; then
|
||||
test -s "${tmp}" && cat "${tmp}" | git apply -p0
|
||||
true
|
||||
else
|
||||
cat "${tmp}"
|
||||
fi
|
49
src/Anon.cc
49
src/Anon.cc
|
@ -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 )
|
||||
{
|
||||
|
@ -82,7 +82,8 @@ bool AnonymizeIPAddr::PreservePrefix(ipaddr32_t /* input */, int /* num_bits */)
|
|||
|
||||
bool AnonymizeIPAddr::PreserveNet(ipaddr32_t input)
|
||||
{
|
||||
switch ( addr_to_class(ntohl(input)) ) {
|
||||
switch ( addr_to_class(ntohl(input)) )
|
||||
{
|
||||
case 'A':
|
||||
return PreservePrefix(input, 8);
|
||||
case 'B':
|
||||
|
@ -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)
|
||||
//
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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,7 +390,8 @@ ipaddr32_t anonymize_ip(ipaddr32_t ip, enum ip_addr_anonymization_class_t cl)
|
|||
|
||||
int method = -1;
|
||||
|
||||
switch ( cl ) {
|
||||
switch ( cl )
|
||||
{
|
||||
case ORIG_ADDR: // client address
|
||||
preserve_addr = anon_preserve_orig_addr.get();
|
||||
method = orig_addr_anonymization;
|
||||
|
@ -442,10 +439,8 @@ 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
|
||||
|
|
34
src/Anon.h
34
src/Anon.h
|
@ -10,22 +10,25 @@
|
|||
|
||||
#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 {
|
||||
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,
|
||||
|
@ -39,7 +42,8 @@ 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;
|
||||
|
||||
|
@ -55,7 +59,8 @@ protected:
|
|||
std::map<ipaddr32_t, ipaddr32_t> mapping;
|
||||
};
|
||||
|
||||
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr {
|
||||
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr
|
||||
{
|
||||
public:
|
||||
AnonymizeIPAddr_Seq() { seq = 1; }
|
||||
ipaddr32_t anonymize(ipaddr32_t addr) override;
|
||||
|
@ -64,23 +69,27 @@ 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;
|
||||
};
|
||||
|
||||
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr {
|
||||
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr
|
||||
{
|
||||
public:
|
||||
AnonymizeIPAddr_A50() { init(); }
|
||||
~AnonymizeIPAddr_A50() override;
|
||||
|
@ -89,7 +98,8 @@ public:
|
|||
bool PreservePrefix(ipaddr32_t input, int num_bits) override;
|
||||
|
||||
protected:
|
||||
struct Node {
|
||||
struct Node
|
||||
{
|
||||
ipaddr32_t input;
|
||||
ipaddr32_t output;
|
||||
Node* child[2];
|
||||
|
|
112
src/Attr.cc
112
src/Attr.cc
|
@ -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
|
||||
{
|
||||
|
@ -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());
|
||||
|
@ -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,7 +301,8 @@ void Attributes::DescribeReST(ODesc* d, bool shorten) const
|
|||
|
||||
void Attributes::CheckAttr(Attr* a)
|
||||
{
|
||||
switch ( a->Tag() ) {
|
||||
switch ( a->Tag() )
|
||||
{
|
||||
case ATTR_DEPRECATED:
|
||||
case ATTR_REDEF:
|
||||
case ATTR_IS_ASSIGNED:
|
||||
|
@ -310,10 +322,8 @@ void Attributes::CheckAttr(Attr* a)
|
|||
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");
|
||||
a->GetExpr()->Error(is_add ? "&add_func must be a function"
|
||||
: "&delete_func must be a function");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -321,9 +331,8 @@ void Attributes::CheckAttr(Attr* a)
|
|||
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");
|
||||
is_add ? "&add_func function must yield same type as variable"
|
||||
: "&delete_func function must yield same type as variable");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -354,8 +363,7 @@ void Attributes::CheckAttr(Attr* a)
|
|||
// Ok.
|
||||
break;
|
||||
|
||||
if ( type->Tag() == TYPE_TABLE &&
|
||||
type->AsTableType()->IsUnspecifiedTable() )
|
||||
if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() )
|
||||
// Ok.
|
||||
break;
|
||||
|
||||
|
@ -423,7 +431,8 @@ void Attributes::CheckAttr(Attr* a)
|
|||
// Ok.
|
||||
break;
|
||||
|
||||
if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) )
|
||||
if ( (atype->Tag() == TYPE_TABLE &&
|
||||
atype->AsTableType()->IsUnspecifiedTable()) )
|
||||
{
|
||||
auto e = check_and_promote_expr(a->GetExpr(), type);
|
||||
|
||||
|
@ -435,8 +444,7 @@ void Attributes::CheckAttr(Attr* a)
|
|||
}
|
||||
|
||||
// Table defaults may be promotable.
|
||||
if ( ytype && ytype->Tag() == TYPE_RECORD &&
|
||||
atype->Tag() == TYPE_RECORD &&
|
||||
if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
||||
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) )
|
||||
// Ok.
|
||||
break;
|
||||
|
@ -469,15 +477,15 @@ void Attributes::CheckAttr(Attr* a)
|
|||
|
||||
for ( const auto& a : attrs )
|
||||
{
|
||||
if ( a->Tag() == ATTR_EXPIRE_READ ||
|
||||
a->Tag() == ATTR_EXPIRE_WRITE ||
|
||||
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");
|
||||
Error("set/table can only have one of &read_expire, &write_expire, "
|
||||
"&create_expire");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -509,7 +517,6 @@ void Attributes::CheckAttr(Attr* a)
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
case ATTR_ON_CHANGE:
|
||||
{
|
||||
if ( type->Tag() != TYPE_TABLE )
|
||||
|
@ -520,7 +527,8 @@ void Attributes::CheckAttr(Attr* a)
|
|||
|
||||
const auto& change_func = a->GetExpr();
|
||||
|
||||
if ( change_func->GetType()->Tag() != TYPE_FUNC || change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
|
||||
if ( change_func->GetType()->Tag() != TYPE_FUNC ||
|
||||
change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
|
||||
Error("&on_change attribute is not a function");
|
||||
|
||||
const FuncType* c_ft = change_func->GetType()->AsFuncType();
|
||||
|
@ -671,14 +679,12 @@ void Attributes::CheckAttr(Attr* a)
|
|||
break;
|
||||
|
||||
case ATTR_GROUP:
|
||||
if ( type->Tag() != TYPE_FUNC ||
|
||||
type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
|
||||
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 )
|
||||
if ( type->Tag() != TYPE_FUNC || type->AsFuncType()->Flavor() != FUNC_FLAVOR_EVENT )
|
||||
Error("&error_handler only applicable to events");
|
||||
break;
|
||||
|
||||
|
@ -697,7 +703,8 @@ void Attributes::CheckAttr(Attr* a)
|
|||
|
||||
const auto& atype = a->GetExpr()->GetType();
|
||||
|
||||
if ( atype->Tag() != TYPE_STRING ) {
|
||||
if ( atype->Tag() != TYPE_STRING )
|
||||
{
|
||||
Error("type column needs to have a string argument");
|
||||
break;
|
||||
}
|
||||
|
@ -705,7 +712,6 @@ void Attributes::CheckAttr(Attr* a)
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
BadTag("Attributes::CheckAttr", attr_name(a->Tag()));
|
||||
}
|
||||
|
|
28
src/Attr.h
28
src/Attr.h
|
@ -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,
|
||||
|
@ -55,7 +58,8 @@ 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;
|
||||
|
||||
|
@ -66,8 +70,7 @@ public:
|
|||
|
||||
AttrTag Tag() const { return tag; }
|
||||
|
||||
const ExprPtr& GetExpr() const
|
||||
{ return expr; }
|
||||
const ExprPtr& GetExpr() const { return expr; }
|
||||
|
||||
void SetAttrExpr(ExprPtr e);
|
||||
|
||||
|
@ -103,10 +106,10 @@ protected:
|
|||
};
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -48,7 +50,6 @@ void Base64Converter::Encode(int len, const unsigned char* data, int* pblen, cha
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int* Base64Converter::InitBase64Table(const std::string& alphabet)
|
||||
{
|
||||
assert(alphabet.size() == 64);
|
||||
|
@ -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);
|
||||
|
@ -194,7 +192,8 @@ int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf)
|
|||
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;
|
||||
|
@ -236,8 +235,7 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -270,8 +268,7 @@ 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;
|
||||
}
|
||||
|
||||
|
|
13
src/Base64.h
13
src/Base64.h
|
@ -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
|
||||
|
@ -59,7 +63,6 @@ protected:
|
|||
int* base64_table;
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,28 +2,29 @@
|
|||
|
||||
#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;
|
||||
|
||||
|
|
10
src/CCL.cc
10
src/CCL.cc
|
@ -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
|
||||
|
|
16
src/CCL.h
16
src/CCL.h
|
@ -5,11 +5,13 @@
|
|||
#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();
|
||||
|
@ -24,10 +26,14 @@ public:
|
|||
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;
|
||||
|
|
173
src/CompHash.cc
173
src/CompHash.cc
|
@ -1,24 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
#include "zeek/CompHash.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "zeek/ZeekString.h"
|
||||
#include "zeek/Dict.h"
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/RE.h"
|
||||
#include "zeek/Reporter.h"
|
||||
#include "zeek/Func.h"
|
||||
#include "zeek/IPAddr.h"
|
||||
#include "zeek/RE.h"
|
||||
#include "zeek/Reporter.h"
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/ZeekString.h"
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
namespace zeek::detail {
|
||||
namespace zeek::detail
|
||||
{
|
||||
|
||||
CompositeHash::CompositeHash(TypeListPtr composite_type)
|
||||
: type(std::move(composite_type))
|
||||
CompositeHash::CompositeHash(TypeListPtr composite_type) : type(std::move(composite_type))
|
||||
{
|
||||
singleton_tag = TYPE_INTERNAL_ERROR;
|
||||
|
||||
|
@ -61,8 +61,7 @@ CompositeHash::CompositeHash(TypeListPtr composite_type)
|
|||
|
||||
if ( size > 0 )
|
||||
// Fixed size. Make sure what we get is fully aligned.
|
||||
key = reinterpret_cast<char*>
|
||||
(new double[size/sizeof(double) + 1]);
|
||||
key = reinterpret_cast<char*>(new double[size / sizeof(double) + 1]);
|
||||
else
|
||||
key = nullptr;
|
||||
}
|
||||
|
@ -74,8 +73,8 @@ CompositeHash::~CompositeHash()
|
|||
}
|
||||
|
||||
// Computes the piece of the hash for Val*, returning the new kp.
|
||||
char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
||||
Type* bt, Val* v, bool optional) const
|
||||
char* CompositeHash::SingleValHash(bool type_check, char* kp0, Type* bt, Val* v,
|
||||
bool optional) const
|
||||
{
|
||||
char* kp1 = nullptr;
|
||||
InternalTypeTag t = bt->InternalType();
|
||||
|
@ -98,7 +97,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
switch ( t ) {
|
||||
switch ( t )
|
||||
{
|
||||
case TYPE_INTERNAL_INT:
|
||||
{
|
||||
bro_int_t* kp = AlignAndPadType<bro_int_t>(kp0);
|
||||
|
@ -143,7 +143,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
case TYPE_INTERNAL_VOID:
|
||||
case TYPE_INTERNAL_OTHER:
|
||||
{
|
||||
switch ( v->GetType()->Tag() ) {
|
||||
switch ( v->GetType()->Tag() )
|
||||
{
|
||||
case TYPE_FUNC:
|
||||
{
|
||||
uint32_t* kp = AlignAndPadType<uint32_t>(kp0);
|
||||
|
@ -154,10 +155,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
|
||||
case TYPE_PATTERN:
|
||||
{
|
||||
const char* texts[2] = {
|
||||
v->AsPattern()->PatternText(),
|
||||
v->AsPattern()->AnywherePatternText()
|
||||
};
|
||||
const char* texts[2] = {v->AsPattern()->PatternText(),
|
||||
v->AsPattern()->AnywherePatternText()};
|
||||
|
||||
uint64_t* kp;
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
|
@ -193,8 +192,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
if ( ! (rv_i || optional_attr) )
|
||||
return nullptr;
|
||||
|
||||
if ( ! (kp = SingleValHash(type_check, kp,
|
||||
rt->GetFieldType(i).get(),
|
||||
if ( ! (kp =
|
||||
SingleValHash(type_check, kp, rt->GetFieldType(i).get(),
|
||||
rv_i.get(), optional_attr)) )
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -213,8 +212,10 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
auto tbl = tv->AsTable();
|
||||
auto lv = make_intrusive<ListVal>(TYPE_ANY);
|
||||
|
||||
struct HashKeyComparer {
|
||||
bool operator()(const std::unique_ptr<HashKey>& a, const std::unique_ptr<HashKey>& b) const
|
||||
struct HashKeyComparer
|
||||
{
|
||||
bool operator()(const std::unique_ptr<HashKey>& a,
|
||||
const std::unique_ptr<HashKey>& b) const
|
||||
{
|
||||
if ( a->Hash() != b->Hash() )
|
||||
return a->Hash() < b->Hash();
|
||||
|
@ -249,7 +250,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
{
|
||||
auto val = tv->FindOrDefault(key);
|
||||
|
||||
if ( ! (kp1 = SingleValHash(type_check, kp1, val->GetType().get(),
|
||||
if ( ! (kp1 =
|
||||
SingleValHash(type_check, kp1, val->GetType().get(),
|
||||
val.get(), false)) )
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -276,9 +278,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
|
||||
if ( val )
|
||||
{
|
||||
if ( ! (kp1 = SingleValHash(type_check, kp1,
|
||||
vt->Yield().get(), val.get(),
|
||||
false)) )
|
||||
if ( ! (kp1 = SingleValHash(type_check, kp1, vt->Yield().get(),
|
||||
val.get(), false)) )
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -294,8 +295,9 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
for ( int i = 0; i < lv->Length(); ++i )
|
||||
{
|
||||
Val* entry_val = lv->Idx(i).get();
|
||||
if ( ! (kp1 = SingleValHash(type_check, kp1, entry_val->GetType().get(),
|
||||
entry_val, false)) )
|
||||
if ( ! (kp1 = SingleValHash(type_check, kp1,
|
||||
entry_val->GetType().get(), entry_val,
|
||||
false)) )
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +305,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
|
||||
default:
|
||||
{
|
||||
reporter->InternalError("bad index type in CompositeHash::SingleValHash");
|
||||
reporter->InternalError(
|
||||
"bad index type in CompositeHash::SingleValHash");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +336,6 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
return kp1;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_check) const
|
||||
{
|
||||
auto v = &argv;
|
||||
|
@ -401,7 +403,8 @@ std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool
|
|||
if ( type_check && v->GetType()->InternalType() != singleton_tag )
|
||||
return nullptr;
|
||||
|
||||
switch ( singleton_tag ) {
|
||||
switch ( singleton_tag )
|
||||
{
|
||||
case TYPE_INTERNAL_INT:
|
||||
return std::make_unique<HashKey>(v->AsInt());
|
||||
|
||||
|
@ -424,10 +427,8 @@ std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool
|
|||
|
||||
if ( v->GetType()->Tag() == TYPE_PATTERN )
|
||||
{
|
||||
const char* texts[2] = {
|
||||
v->AsPattern()->PatternText(),
|
||||
v->AsPattern()->AnywherePatternText()
|
||||
};
|
||||
const char* texts[2] = {v->AsPattern()->PatternText(),
|
||||
v->AsPattern()->AnywherePatternText()};
|
||||
int n = strlen(texts[0]) + strlen(texts[1]) + 2; // 2 for null
|
||||
char* key = new char[n];
|
||||
std::memcpy(key, texts[0], strlen(texts[0]) + 1);
|
||||
|
@ -450,8 +451,7 @@ std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool
|
|||
}
|
||||
}
|
||||
|
||||
int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
||||
bool type_check, int sz, bool optional,
|
||||
int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v, bool type_check, int sz, bool optional,
|
||||
bool calc_static_size) const
|
||||
{
|
||||
InternalTypeTag t = bt->InternalType();
|
||||
|
@ -466,7 +466,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
return 0;
|
||||
}
|
||||
|
||||
switch ( t ) {
|
||||
switch ( t )
|
||||
{
|
||||
case TYPE_INTERNAL_INT:
|
||||
case TYPE_INTERNAL_UNSIGNED:
|
||||
sz = SizeAlign(sz, sizeof(bro_int_t));
|
||||
|
@ -489,7 +490,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
case TYPE_INTERNAL_VOID:
|
||||
case TYPE_INTERNAL_OTHER:
|
||||
{
|
||||
switch ( bt->Tag() ) {
|
||||
switch ( bt->Tag() )
|
||||
{
|
||||
case TYPE_FUNC:
|
||||
{
|
||||
sz = SizeAlign(sz, sizeof(uint32_t));
|
||||
|
@ -502,8 +504,9 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
return (optional && ! calc_static_size) ? sz : 0;
|
||||
|
||||
sz = SizeAlign(sz, 2 * sizeof(uint64_t));
|
||||
sz += strlen(v->AsPattern()->PatternText())
|
||||
+ strlen(v->AsPattern()->AnywherePatternText()) + 2; // 2 for null terminators
|
||||
sz += strlen(v->AsPattern()->PatternText()) +
|
||||
strlen(v->AsPattern()->AnywherePatternText()) +
|
||||
2; // 2 for null terminators
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -522,8 +525,7 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
bool optional_attr = (a && a->Find(ATTR_OPTIONAL));
|
||||
|
||||
auto rv_v = rv ? rv->GetField(i) : nullptr;
|
||||
sz = SingleTypeKeySize(rt->GetFieldType(i).get(),
|
||||
rv_v.get(),
|
||||
sz = SingleTypeKeySize(rt->GetFieldType(i).get(), rv_v.get(),
|
||||
type_check, sz, optional_attr,
|
||||
calc_static_size);
|
||||
if ( ! sz )
|
||||
|
@ -544,16 +546,16 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
for ( int i = 0; i < tv->Size(); ++i )
|
||||
{
|
||||
const auto& key = lv->Idx(i);
|
||||
sz = SingleTypeKeySize(key->GetType().get(), key.get(), type_check, sz, false,
|
||||
calc_static_size);
|
||||
sz = SingleTypeKeySize(key->GetType().get(), key.get(), type_check,
|
||||
sz, false, calc_static_size);
|
||||
if ( ! sz )
|
||||
return 0;
|
||||
|
||||
if ( ! bt->IsSet() )
|
||||
{
|
||||
auto val = tv->FindOrDefault(key);
|
||||
sz = SingleTypeKeySize(val->GetType().get(), val.get(), type_check, sz,
|
||||
false, calc_static_size);
|
||||
sz = SingleTypeKeySize(val->GetType().get(), val.get(),
|
||||
type_check, sz, false, calc_static_size);
|
||||
if ( ! sz )
|
||||
return 0;
|
||||
}
|
||||
|
@ -578,7 +580,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
sz = SingleTypeKeySize(bt->AsVectorType()->Yield().get(),
|
||||
val.get(), type_check, sz, false,
|
||||
calc_static_size);
|
||||
if ( ! sz ) return 0;
|
||||
if ( ! sz )
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -593,9 +596,11 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
ListVal* lv = const_cast<ListVal*>(v->AsListVal());
|
||||
for ( int i = 0; i < lv->Length(); ++i )
|
||||
{
|
||||
sz = SingleTypeKeySize(lv->Idx(i)->GetType().get(), lv->Idx(i).get(),
|
||||
sz =
|
||||
SingleTypeKeySize(lv->Idx(i)->GetType().get(), lv->Idx(i).get(),
|
||||
type_check, sz, false, calc_static_size);
|
||||
if ( ! sz) return 0;
|
||||
if ( ! sz )
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -603,7 +608,8 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v,
|
|||
|
||||
default:
|
||||
{
|
||||
reporter->InternalError("bad index type in CompositeHash::CompositeHash");
|
||||
reporter->InternalError(
|
||||
"bad index type in CompositeHash::CompositeHash");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -645,8 +651,8 @@ int CompositeHash::ComputeKeySize(const Val* v, bool type_check, bool calc_stati
|
|||
int sz = 0;
|
||||
for ( auto i = 0u; i < tl.size(); ++i )
|
||||
{
|
||||
sz = SingleTypeKeySize(tl[i].get(), v ? v->AsListVal()->Idx(i).get() : nullptr,
|
||||
type_check, sz, false, calc_static_size);
|
||||
sz = SingleTypeKeySize(tl[i].get(), v ? v->AsListVal()->Idx(i).get() : nullptr, type_check,
|
||||
sz, false, calc_static_size);
|
||||
if ( ! sz )
|
||||
return 0;
|
||||
}
|
||||
|
@ -734,10 +740,8 @@ ListValPtr CompositeHash::RecoverVals(const HashKey& k) const
|
|||
return l;
|
||||
}
|
||||
|
||||
const char* CompositeHash::RecoverOneVal(
|
||||
const HashKey& k, const char* kp0,
|
||||
const char* const k_end, Type* t,
|
||||
ValPtr* pval, bool optional) const
|
||||
const char* CompositeHash::RecoverOneVal(const HashKey& k, const char* kp0, const char* const k_end,
|
||||
Type* t, ValPtr* pval, bool optional) const
|
||||
{
|
||||
// k->Size() == 0 for a single empty string.
|
||||
if ( kp0 >= k_end && k.Size() > 0 )
|
||||
|
@ -759,7 +763,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
}
|
||||
}
|
||||
|
||||
switch ( it ) {
|
||||
switch ( it )
|
||||
{
|
||||
case TYPE_INTERNAL_INT:
|
||||
{
|
||||
const bro_int_t* const kp = AlignType<bro_int_t>(kp0);
|
||||
|
@ -773,7 +778,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
*pval = val_mgr->Int(*kp);
|
||||
else
|
||||
{
|
||||
reporter->InternalError("bad internal unsigned int in CompositeHash::RecoverOneVal()");
|
||||
reporter->InternalError(
|
||||
"bad internal unsigned int in CompositeHash::RecoverOneVal()");
|
||||
*pval = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -784,7 +790,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
const bro_uint_t* const kp = AlignType<bro_uint_t>(kp0);
|
||||
kp1 = reinterpret_cast<const char*>(kp + 1);
|
||||
|
||||
switch ( tag ) {
|
||||
switch ( tag )
|
||||
{
|
||||
case TYPE_COUNT:
|
||||
*pval = val_mgr->Count(*kp);
|
||||
break;
|
||||
|
@ -794,7 +801,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
break;
|
||||
|
||||
default:
|
||||
reporter->InternalError("bad internal unsigned int in CompositeHash::RecoverOneVal()");
|
||||
reporter->InternalError(
|
||||
"bad internal unsigned int in CompositeHash::RecoverOneVal()");
|
||||
*pval = nullptr;
|
||||
break;
|
||||
}
|
||||
|
@ -822,13 +830,15 @@ const char* CompositeHash::RecoverOneVal(
|
|||
|
||||
IPAddr addr(IPv6, kp, IPAddr::Network);
|
||||
|
||||
switch ( tag ) {
|
||||
switch ( tag )
|
||||
{
|
||||
case TYPE_ADDR:
|
||||
*pval = make_intrusive<AddrVal>(addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
reporter->InternalError("bad internal address in CompositeHash::RecoverOneVal()");
|
||||
reporter->InternalError(
|
||||
"bad internal address in CompositeHash::RecoverOneVal()");
|
||||
*pval = nullptr;
|
||||
break;
|
||||
}
|
||||
|
@ -846,7 +856,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
case TYPE_INTERNAL_VOID:
|
||||
case TYPE_INTERNAL_OTHER:
|
||||
{
|
||||
switch ( t->Tag() ) {
|
||||
switch ( t->Tag() )
|
||||
{
|
||||
case TYPE_FUNC:
|
||||
{
|
||||
const uint32_t* const kp = AlignType<uint32_t>(kp0);
|
||||
|
@ -855,22 +866,28 @@ const char* CompositeHash::RecoverOneVal(
|
|||
const auto& f = Func::GetFuncPtrByID(*kp);
|
||||
|
||||
if ( ! f )
|
||||
reporter->InternalError("failed to look up unique function id %" PRIu32 " in CompositeHash::RecoverOneVal()", *kp);
|
||||
reporter->InternalError(
|
||||
"failed to look up unique function id %" PRIu32
|
||||
" in CompositeHash::RecoverOneVal()",
|
||||
*kp);
|
||||
|
||||
*pval = make_intrusive<FuncVal>(f);
|
||||
const auto& pvt = (*pval)->GetType();
|
||||
|
||||
if ( ! pvt )
|
||||
reporter->InternalError("bad aggregate Val in CompositeHash::RecoverOneVal()");
|
||||
reporter->InternalError(
|
||||
"bad aggregate Val in CompositeHash::RecoverOneVal()");
|
||||
|
||||
else if ( t->Tag() != TYPE_FUNC && ! same_type(pvt, t) )
|
||||
// ### Maybe fix later, but may be fundamentally
|
||||
// un-checkable --US
|
||||
reporter->InternalError("inconsistent aggregate Val in CompositeHash::RecoverOneVal()");
|
||||
reporter->InternalError(
|
||||
"inconsistent aggregate Val in CompositeHash::RecoverOneVal()");
|
||||
|
||||
// ### A crude approximation for now.
|
||||
else if ( t->Tag() == TYPE_FUNC && pvt->Tag() != TYPE_FUNC )
|
||||
reporter->InternalError("inconsistent aggregate Val in CompositeHash::RecoverOneVal()");
|
||||
reporter->InternalError(
|
||||
"inconsistent aggregate Val in CompositeHash::RecoverOneVal()");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -894,7 +911,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
}
|
||||
|
||||
if ( ! re->Compile() )
|
||||
reporter->InternalError("failed compiling table/set key pattern: %s",
|
||||
reporter->InternalError(
|
||||
"failed compiling table/set key pattern: %s",
|
||||
re->PatternText());
|
||||
|
||||
*pval = make_intrusive<PatternVal>(re);
|
||||
|
@ -916,15 +934,17 @@ const char* CompositeHash::RecoverOneVal(
|
|||
Attributes* a = rt->FieldDecl(i)->attrs.get();
|
||||
bool optional = (a && a->Find(ATTR_OPTIONAL));
|
||||
|
||||
kp = RecoverOneVal(k, kp, k_end,
|
||||
rt->GetFieldType(i).get(), &v, optional);
|
||||
kp = RecoverOneVal(k, kp, k_end, rt->GetFieldType(i).get(), &v,
|
||||
optional);
|
||||
|
||||
// An earlier call to reporter->InternalError would have called abort() and broken the
|
||||
// call tree that clang-tidy is relying on to get the error described.
|
||||
// An earlier call to reporter->InternalError would have called
|
||||
// abort() and broken the call tree that clang-tidy is relying on to
|
||||
// get the error described.
|
||||
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Branch)
|
||||
if ( ! (v || optional) )
|
||||
{
|
||||
reporter->InternalError("didn't recover expected number of fields from HashKey");
|
||||
reporter->InternalError(
|
||||
"didn't recover expected number of fields from HashKey");
|
||||
pval = nullptr;
|
||||
break;
|
||||
}
|
||||
|
@ -956,7 +976,8 @@ const char* CompositeHash::RecoverOneVal(
|
|||
for ( int i = 0; i < n; ++i )
|
||||
{
|
||||
ValPtr key;
|
||||
kp1 = RecoverOneVal(k, kp1, k_end, tt->GetIndices().get(), &key, false);
|
||||
kp1 = RecoverOneVal(k, kp1, k_end, tt->GetIndices().get(), &key,
|
||||
false);
|
||||
|
||||
if ( t->IsSet() )
|
||||
tv->Assign(std::move(key), nullptr);
|
||||
|
|
|
@ -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::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,33 +66,25 @@ 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;
|
||||
|
|
80
src/Conn.cc
80
src/Conn.cc
|
@ -1,34 +1,34 @@
|
|||
// 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),
|
||||
key(k)
|
||||
|
@ -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,10 +143,8 @@ 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)
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -273,7 +264,6 @@ const RecordValPtr& Connection::GetVal()
|
|||
|
||||
if ( inner_vlan != 0 )
|
||||
conn_val->Assign(10, inner_vlan);
|
||||
|
||||
}
|
||||
|
||||
if ( adapter )
|
||||
|
@ -320,14 +310,13 @@ static inline bool is_version_sep(const char* s, const char* end)
|
|||
// foo-1.2.3
|
||||
(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]);
|
||||
}
|
||||
|
||||
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,8 +477,7 @@ 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);
|
||||
}
|
||||
|
|
96
src/Conn.h
96
src/Conn.h
|
@ -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,8 +31,12 @@ 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;
|
||||
|
@ -41,17 +44,25 @@ class RuleHdrTest;
|
|||
|
||||
} // 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;
|
||||
|
@ -62,17 +73,17 @@ struct ConnTuple {
|
|||
|
||||
using ConnID [[deprecated("Remove in v5.1. Use zeek::ConnTuple.")]] = ConnTuple;
|
||||
|
||||
static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1,
|
||||
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,10 +112,8 @@ 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);
|
||||
|
||||
|
@ -114,8 +123,8 @@ public:
|
|||
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; }
|
||||
|
@ -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).
|
||||
|
@ -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,12 +223,10 @@ 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; }
|
||||
|
||||
|
@ -235,19 +242,16 @@ public:
|
|||
|
||||
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;
|
||||
|
|
44
src/DFA.cc
44
src/DFA.cc
|
@ -1,18 +1,18 @@
|
|||
// 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,
|
||||
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;
|
||||
|
@ -244,11 +244,10 @@ void DFA_State::Dump(FILE* f, DFA_Machine* m)
|
|||
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,
|
||||
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);
|
||||
|
|
30
src/DFA.h
30
src/DFA.h
|
@ -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;
|
||||
|
@ -22,10 +22,11 @@ class DFA_Machine;
|
|||
#define DFA_UNCOMPUTED_STATE -2
|
||||
#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; }
|
||||
|
@ -73,7 +74,8 @@ protected:
|
|||
|
||||
using DigestStr = std::basic_string<u_char>;
|
||||
|
||||
class DFA_State_Cache {
|
||||
class DFA_State_Cache
|
||||
{
|
||||
public:
|
||||
DFA_State_Cache();
|
||||
~DFA_State_Cache();
|
||||
|
@ -86,7 +88,8 @@ public:
|
|||
|
||||
int NumEntries() const { return states.size(); }
|
||||
|
||||
struct Stats {
|
||||
struct Stats
|
||||
{
|
||||
// Sum of all NFA states
|
||||
unsigned int nfa_states;
|
||||
unsigned int dfa_states;
|
||||
|
@ -107,7 +110,8 @@ private:
|
|||
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;
|
||||
|
@ -123,8 +127,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;
|
||||
|
||||
protected:
|
||||
friend class DFA_State; // for DFA_State::ComputeXtion
|
||||
|
@ -133,8 +138,7 @@ protected:
|
|||
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);
|
||||
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
|
||||
|
|
138
src/DNS_Mgr.cc
138
src/DNS_Mgr.cc
|
@ -1,10 +1,11 @@
|
|||
// 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>
|
||||
|
@ -16,53 +17,52 @@
|
|||
#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 "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; }
|
||||
|
||||
|
@ -75,7 +75,6 @@ public:
|
|||
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
|
||||
|
@ -98,12 +97,13 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
|
|||
{
|
||||
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);
|
||||
|
@ -117,10 +117,7 @@ public:
|
|||
// 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();
|
||||
}
|
||||
string ReqStr() const { return req_host ? req_host : req_addr.AsString(); }
|
||||
|
||||
ListValPtr Addrs();
|
||||
TableValPtr AddrsSet(); // addresses returned as a set
|
||||
|
@ -221,9 +218,8 @@ DNS_Mapping::DNS_Mapping(FILE* f)
|
|||
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);
|
||||
|
@ -292,7 +288,8 @@ ListValPtr DNS_Mapping::Addrs()
|
|||
return addrs_val;
|
||||
}
|
||||
|
||||
TableValPtr DNS_Mapping::AddrsSet() {
|
||||
TableValPtr DNS_Mapping::AddrsSet()
|
||||
{
|
||||
auto l = Addrs();
|
||||
|
||||
if ( ! l )
|
||||
|
@ -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;
|
||||
|
@ -366,15 +361,13 @@ 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);
|
||||
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;
|
||||
|
@ -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,7 +512,8 @@ TableValPtr DNS_Mgr::LookupHost(const char* name)
|
|||
}
|
||||
|
||||
// Not found, or priming.
|
||||
switch ( mode ) {
|
||||
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));
|
||||
|
@ -565,14 +558,14 @@ ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr)
|
|||
}
|
||||
|
||||
// Not found, or priming.
|
||||
switch ( mode ) {
|
||||
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());
|
||||
reporter->FatalError("can't find DNS entry for %s in cache", addr.AsString().c_str());
|
||||
return nullptr;
|
||||
|
||||
case DNS_DEFAULT:
|
||||
|
@ -586,9 +579,7 @@ ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr)
|
|||
}
|
||||
}
|
||||
|
||||
void DNS_Mgr::Verify()
|
||||
{
|
||||
}
|
||||
void DNS_Mgr::Verify() { }
|
||||
|
||||
#define MAX_PENDING_REQUESTS 20
|
||||
|
||||
|
@ -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,9 +632,7 @@ 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;
|
||||
|
@ -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)
|
||||
|
@ -1381,8 +1364,7 @@ void DNS_Mgr::Process()
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -32,14 +33,16 @@ using TableValPtr = IntrusivePtr<TableVal>;
|
|||
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 {
|
||||
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
|
||||
|
@ -49,7 +52,8 @@ enum DNS_MgrMode {
|
|||
// 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;
|
||||
|
@ -75,7 +79,8 @@ public:
|
|||
const char* LookupTextInCache(const std::string& name);
|
||||
|
||||
// Support for async lookups.
|
||||
class LookupCallback {
|
||||
class LookupCallback
|
||||
{
|
||||
public:
|
||||
LookupCallback() { }
|
||||
virtual ~LookupCallback() { }
|
||||
|
@ -89,7 +94,8 @@ public:
|
|||
void AsyncLookupName(const std::string& name, LookupCallback* callback);
|
||||
void AsyncLookupNameText(const std::string& name, LookupCallback* callback);
|
||||
|
||||
struct Stats {
|
||||
struct Stats
|
||||
{
|
||||
unsigned long requests; // These count only async requests.
|
||||
unsigned long successful;
|
||||
unsigned long failed;
|
||||
|
@ -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);
|
||||
|
@ -165,7 +170,8 @@ protected:
|
|||
|
||||
typedef std::list<LookupCallback*> CallbackList;
|
||||
|
||||
struct AsyncRequest {
|
||||
struct AsyncRequest
|
||||
{
|
||||
double time;
|
||||
IPAddr host;
|
||||
std::string name;
|
||||
|
@ -179,8 +185,7 @@ protected:
|
|||
|
||||
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,7 +215,6 @@ protected:
|
|||
callbacks.clear();
|
||||
processed = true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef std::map<IPAddr, AsyncRequest*> AsyncRequestAddrMap;
|
||||
|
@ -227,14 +229,13 @@ protected:
|
|||
typedef std::list<AsyncRequest*> QueuedList;
|
||||
QueuedList asyncs_queued;
|
||||
|
||||
struct AsyncRequestCompare {
|
||||
bool operator()(const AsyncRequest* a, const AsyncRequest* b)
|
||||
struct AsyncRequestCompare
|
||||
{
|
||||
return a->time > b->time;
|
||||
}
|
||||
bool operator()(const AsyncRequest* a, const AsyncRequest* b) { return a->time > b->time; }
|
||||
};
|
||||
|
||||
typedef std::priority_queue<AsyncRequest*, std::vector<AsyncRequest*>, AsyncRequestCompare> TimeoutQueue;
|
||||
typedef std::priority_queue<AsyncRequest*, std::vector<AsyncRequest*>, AsyncRequestCompare>
|
||||
TimeoutQueue;
|
||||
TimeoutQueue asyncs_timeouts;
|
||||
|
||||
unsigned long num_requests;
|
||||
|
|
|
@ -1,31 +1,33 @@
|
|||
// 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;
|
||||
|
||||
|
@ -41,7 +43,6 @@ void BreakpointTimer::Dispatch(double t, bool is_expire)
|
|||
bp->ShouldBreak(t);
|
||||
}
|
||||
|
||||
|
||||
DbgBreakpoint::DbgBreakpoint()
|
||||
{
|
||||
kind = BP_STMT;
|
||||
|
@ -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,7 +201,8 @@ bool DbgBreakpoint::Reset()
|
|||
{
|
||||
ParseLocationRec plr;
|
||||
|
||||
switch ( kind ) {
|
||||
switch ( kind )
|
||||
{
|
||||
case BP_TIME:
|
||||
debug_msg("Time-based breakpoints not yet supported.\n");
|
||||
break;
|
||||
|
@ -258,8 +256,7 @@ BreakCode DbgBreakpoint::HasHit()
|
|||
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,7 +292,8 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
|
|||
if ( ! IsEnabled() )
|
||||
return BC_NO_HIT;
|
||||
|
||||
switch ( kind ) {
|
||||
switch ( kind )
|
||||
{
|
||||
case BP_STMT:
|
||||
case BP_FUNC:
|
||||
if ( at_stmt != s )
|
||||
|
@ -324,7 +322,6 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s)
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
BreakCode DbgBreakpoint::ShouldBreak(double t)
|
||||
{
|
||||
if ( kind != BP_TIME )
|
||||
|
@ -345,7 +342,8 @@ BreakCode DbgBreakpoint::ShouldBreak(double t)
|
|||
|
||||
void DbgBreakpoint::PrintHitMsg()
|
||||
{
|
||||
switch ( kind ) {
|
||||
switch ( kind )
|
||||
{
|
||||
case BP_STMT:
|
||||
case BP_FUNC:
|
||||
case BP_LINE:
|
||||
|
@ -359,9 +357,8 @@ void DbgBreakpoint::PrintHitMsg()
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -3,16 +3,30 @@
|
|||
#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();
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
#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);
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Bro Debugger Help
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#include "zeek/Debug.h"
|
||||
#include "zeek/zeek-config.h"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
81
src/Debug.cc
81
src/Debug.cc
|
@ -1,40 +1,39 @@
|
|||
// 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"
|
||||
}
|
||||
|
||||
|
@ -67,7 +66,8 @@ 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()
|
||||
{
|
||||
|
@ -92,11 +92,9 @@ bool StmtLocMapping::StartsAfter(const StmtLocMapping* 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());
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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() )
|
||||
{
|
||||
|
@ -655,7 +646,8 @@ 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 ) {
|
||||
switch ( cmd_code )
|
||||
{
|
||||
case dcHelp:
|
||||
dbg_cmd_help(cmd_code, args);
|
||||
break;
|
||||
|
@ -772,8 +764,7 @@ 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;
|
||||
|
@ -807,15 +798,13 @@ 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
|
||||
|
@ -848,8 +837,7 @@ int dbg_handle_debug_input()
|
|||
}
|
||||
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);
|
||||
|
@ -960,11 +945,11 @@ 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()");
|
||||
reporter->InternalError(
|
||||
"Assertion failed: frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size()");
|
||||
|
||||
Frame* frame = g_frame_stack[frame_idx];
|
||||
if ( ! (frame) )
|
||||
|
|
46
src/Debug.h
46
src/Debug.h
|
@ -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,8 +30,14 @@ 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;
|
||||
|
@ -43,9 +51,14 @@ 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);
|
||||
|
@ -54,7 +67,8 @@ public:
|
|||
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
|
||||
|
@ -63,7 +77,8 @@ protected:
|
|||
|
||||
extern TraceState g_trace_state;
|
||||
|
||||
class DebuggerState {
|
||||
class DebuggerState
|
||||
{
|
||||
public:
|
||||
DebuggerState();
|
||||
~DebuggerState();
|
||||
|
@ -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
|
||||
|
@ -107,10 +121,15 @@ private:
|
|||
|
||||
// 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(const Location* l, Stmt* s)
|
||||
{
|
||||
loc = *l;
|
||||
stmt = s;
|
||||
}
|
||||
|
||||
bool StartsAfter(const StmtLocMapping* m2);
|
||||
const Location& Loc() const { return loc; }
|
||||
|
@ -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.
|
||||
|
|
101
src/DebugCmds.cc
101
src/DebugCmds.cc
|
@ -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;
|
||||
|
||||
|
@ -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,9 +134,8 @@ 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,
|
||||
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)
|
||||
{
|
||||
|
@ -150,7 +147,6 @@ 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() )
|
||||
|
@ -198,12 +194,10 @@ 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() ||
|
||||
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");
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -359,7 +347,6 @@ int dbg_cmd_help(DebugCmd cmd, const vector<string>& args)
|
|||
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 )
|
||||
{
|
||||
|
@ -516,12 +497,12 @@ 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 ) {
|
||||
switch ( cmd )
|
||||
{
|
||||
case dcDisableBreak:
|
||||
g_debugger_state.breakpoints[bp_change]->SetEnable(false);
|
||||
debug_msg("Breakpoint %d disabled\n", bp_change);
|
||||
|
@ -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,15 +584,11 @@ 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",
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,22 +4,23 @@
|
|||
#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) { }
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
@ -84,7 +72,8 @@ void DebugLogger::ShowStreamsHelp()
|
|||
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");
|
||||
|
@ -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);
|
||||
|
|
|
@ -5,31 +5,37 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#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) ) \
|
||||
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 {
|
||||
enum DebugStream
|
||||
{
|
||||
DBG_SERIAL, // Serialization
|
||||
DBG_RULES, // Signature matching
|
||||
DBG_STRING, // String code
|
||||
|
@ -52,9 +58,11 @@ enum DebugStream {
|
|||
NUM_DBGS // Has to be last
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class DebugLogger {
|
||||
class DebugLogger
|
||||
{
|
||||
public:
|
||||
// Output goes to stderr per default.
|
||||
DebugLogger();
|
||||
|
@ -63,23 +71,19 @@ 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; }
|
||||
|
@ -90,7 +94,8 @@ private:
|
|||
FILE* file;
|
||||
bool verbose;
|
||||
|
||||
struct Stream {
|
||||
struct Stream
|
||||
{
|
||||
const char* prefix;
|
||||
int indent;
|
||||
bool enabled;
|
||||
|
|
20
src/Desc.cc
20
src/Desc.cc
|
@ -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)
|
||||
{
|
||||
|
@ -93,8 +94,7 @@ 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() )
|
||||
|
@ -174,8 +174,7 @@ void ODesc::Add(double d, bool no_exp)
|
|||
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");
|
||||
}
|
||||
|
@ -415,7 +414,6 @@ bool ODesc::FindType(const Type* type)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::string obj_desc(const Obj* o)
|
||||
{
|
||||
static ODesc d;
|
||||
|
|
49
src/Desc.h
49
src/Desc.h
|
@ -3,33 +3,36 @@
|
|||
#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);
|
||||
|
||||
|
@ -65,15 +68,14 @@ public:
|
|||
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();
|
||||
|
@ -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(); }
|
||||
{
|
||||
Add(s);
|
||||
SP();
|
||||
}
|
||||
|
||||
void AddCount(bro_int_t n)
|
||||
{
|
||||
|
@ -118,11 +129,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void SP() {
|
||||
void SP()
|
||||
{
|
||||
if ( ! IsBinary() )
|
||||
Add(" ", 0);
|
||||
}
|
||||
void NL() {
|
||||
void NL()
|
||||
{
|
||||
if ( ! IsBinary() && ! is_short )
|
||||
Add("\n", 0);
|
||||
}
|
||||
|
|
157
src/Dict.cc
157
src/Dict.cc
|
@ -1,18 +1,18 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
#include "zeek/Dict.h"
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <signal.h>
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <fstream>
|
||||
|
||||
#include "zeek/3rdparty/doctest.h"
|
||||
|
||||
#include "zeek/Reporter.h"
|
||||
#include "zeek/util.h"
|
||||
|
||||
|
@ -22,9 +22,12 @@
|
|||
#define ASSERT_VALID(o)
|
||||
#endif // DEBUG
|
||||
|
||||
namespace zeek {
|
||||
namespace zeek
|
||||
{
|
||||
|
||||
class [[deprecated("Remove in v5.1. Use the standard-library-compatible version of iteration.")]] IterCookie {
|
||||
class [[deprecated(
|
||||
"Remove in v5.1. Use the standard-library-compatible version of iteration.")]] IterCookie
|
||||
{
|
||||
public:
|
||||
IterCookie(Dictionary * d) : d(d) { }
|
||||
|
||||
|
@ -65,7 +68,8 @@ public:
|
|||
ASSERT_VALID(this);
|
||||
if ( robust )
|
||||
{
|
||||
d->cookies->erase(std::remove(d->cookies->begin(), d->cookies->end(), this), d->cookies->end());
|
||||
d->cookies->erase(std::remove(d->cookies->begin(), d->cookies->end(), this),
|
||||
d->cookies->end());
|
||||
delete inserted;
|
||||
delete visited;
|
||||
}
|
||||
|
@ -494,9 +498,7 @@ TEST_CASE("dict robust iteration replacement")
|
|||
|
||||
// Iterate past the first couple of elements so we're not done, but the
|
||||
// iterator is still pointing at a valid element.
|
||||
for ( ; count != 2 && it != dict.end_robust(); ++count, ++it )
|
||||
{
|
||||
}
|
||||
for ( ; count != 2 && it != dict.end_robust(); ++count, ++it ) { }
|
||||
|
||||
// Store off the value at this iterator index
|
||||
auto* v = it->GetValue<DictTestDummy*>();
|
||||
|
@ -744,7 +746,9 @@ int Dictionary::Next(int position) const
|
|||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Debugging
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define DUMPIF(f) if(f) Dump(1)
|
||||
#define DUMPIF(f) \
|
||||
if ( f ) \
|
||||
Dump(1)
|
||||
#ifdef DEBUG
|
||||
void Dictionary::AssertValid() const
|
||||
{
|
||||
|
@ -807,7 +811,8 @@ size_t Dictionary::MemoryAllocation() const
|
|||
}
|
||||
|
||||
if ( order )
|
||||
size += padded_sizeof(std::vector<detail::DictEntry>) + zeek::util::pad_size(sizeof(detail::DictEntry) * order->capacity());
|
||||
size += padded_sizeof(std::vector<detail::DictEntry>) +
|
||||
zeek::util::pad_size(sizeof(detail::DictEntry) * order->capacity());
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -839,7 +844,8 @@ void Dictionary::DumpKeys() const
|
|||
char key = char(random() % 26) + 'A';
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
sprintf(key_file, "%d.%d.%zu-%c.key", Length(), max_distance, MemoryAllocation()/Length(), key);
|
||||
sprintf(key_file, "%d.%d.%zu-%c.key", Length(), max_distance, MemoryAllocation() / Length(),
|
||||
key);
|
||||
#pragma GCC diagnostic pop
|
||||
std::ofstream f(key_file, std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for ( int idx = 0; idx < Capacity(); idx++ )
|
||||
|
@ -855,7 +861,8 @@ void Dictionary::DumpKeys() const
|
|||
char key = char(random() % 26) + 'A';
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
sprintf(key_file, "%d.%d.%zu-%d.ckey",Length(), max_distance, MemoryAllocation()/Length(), key);
|
||||
sprintf(key_file, "%d.%d.%zu-%d.ckey", Length(), max_distance,
|
||||
MemoryAllocation() / Length(), key);
|
||||
#pragma GCC diagnostic pop
|
||||
std::ofstream f(key_file, std::ios::out | std::ios::trunc);
|
||||
for ( int idx = 0; idx < Capacity(); idx++ )
|
||||
|
@ -906,16 +913,18 @@ void Dictionary::Dump(int level) const
|
|||
DistanceStats(max_distance, distances, DICT_NUM_DISTANCES);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
printf("cap %'7d ent %'7d %'-7d load %.2f max_dist %2d mem %10zu mem/ent %3zu key/ent %3d lg %2d remaps %1d remap_end %4d ",
|
||||
printf("cap %'7d ent %'7d %'-7d load %.2f max_dist %2d mem %10zu mem/ent %3zu key/ent %3d lg "
|
||||
"%2d remaps %1d remap_end %4d ",
|
||||
Capacity(), Length(), MaxLength(), (double)Length() / (table ? Capacity() : 1),
|
||||
max_distance, MemoryAllocation(), (MemoryAllocation())/(Length()?Length():1), key_size / (Length()?Length():1),
|
||||
log2_buckets, remaps, remap_end);
|
||||
max_distance, MemoryAllocation(), (MemoryAllocation()) / (Length() ? Length() : 1),
|
||||
key_size / (Length() ? Length() : 1), log2_buckets, remaps, remap_end);
|
||||
#pragma GCC diagnostic pop
|
||||
if ( Length() > 0 )
|
||||
{
|
||||
for ( int i = 0; i < DICT_NUM_DISTANCES - 1; i++ )
|
||||
printf("[%d]%2d%% ", i, 100 * distances[i] / Length());
|
||||
printf("[%d+]%2d%% ", DICT_NUM_DISTANCES-1, 100*distances[DICT_NUM_DISTANCES-1]/Length());
|
||||
printf("[%d+]%2d%% ", DICT_NUM_DISTANCES - 1,
|
||||
100 * distances[DICT_NUM_DISTANCES - 1] / Length());
|
||||
}
|
||||
else
|
||||
printf("\n");
|
||||
|
@ -923,14 +932,16 @@ void Dictionary::Dump(int level) const
|
|||
printf("\n");
|
||||
if ( level >= 1 )
|
||||
{
|
||||
printf("%-10s %1s %-10s %-4s %-4s %-10s %-18s %-2s\n", "Index", "*","Bucket", "Dist", "Off", "Hash", "FibHash", "KeySize");
|
||||
printf("%-10s %1s %-10s %-4s %-4s %-10s %-18s %-2s\n", "Index", "*", "Bucket", "Dist",
|
||||
"Off", "Hash", "FibHash", "KeySize");
|
||||
for ( int i = 0; i < Capacity(); i++ )
|
||||
if ( table[i].Empty() )
|
||||
printf("%'10d \n", i);
|
||||
else
|
||||
printf("%'10d %1s %'10d %4d %4d 0x%08x 0x%016" PRIx64 "(%3d) %2d\n",
|
||||
i, (i<=remap_end? "*": ""), BucketByPosition(i), (int)table[i].distance, OffsetInClusterByPosition(i),
|
||||
uint(table[i].hash), FibHash(table[i].hash), (int)FibHash(table[i].hash)&0xFF, (int)table[i].key_size);
|
||||
printf("%'10d %1s %'10d %4d %4d 0x%08x 0x%016" PRIx64 "(%3d) %2d\n", i,
|
||||
(i <= remap_end ? "*" : ""), BucketByPosition(i), (int)table[i].distance,
|
||||
OffsetInClusterByPosition(i), uint(table[i].hash), FibHash(table[i].hash),
|
||||
(int)FibHash(table[i].hash) & 0xFF, (int)table[i].key_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1049,8 @@ int Dictionary::LinearLookupIndex(const void* key, int key_size, detail::hash_t
|
|||
|
||||
// Lookup position for all possible table_sizes caused by remapping. Remap it immediately
|
||||
// if not in the middle of iteration.
|
||||
int Dictionary::LookupIndex(const void* key, int key_size, detail::hash_t hash, int* insert_position, int* insert_distance)
|
||||
int Dictionary::LookupIndex(const void* key, int key_size, detail::hash_t hash,
|
||||
int* insert_position, int* insert_distance)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
if ( ! table )
|
||||
|
@ -1048,7 +1060,8 @@ int Dictionary::LookupIndex(const void* key, int key_size, detail::hash_t hash,
|
|||
#ifdef DEBUG
|
||||
int linear_position = LinearLookupIndex(key, key_size, hash);
|
||||
#endif // DEBUG
|
||||
int position = LookupIndex(key, key_size, hash, bucket, Capacity(), insert_position, insert_distance);
|
||||
int position =
|
||||
LookupIndex(key, key_size, hash, bucket, Capacity(), insert_position, insert_distance);
|
||||
if ( position >= 0 )
|
||||
{
|
||||
ASSERT(position == linear_position); // same as linearLookup
|
||||
|
@ -1121,7 +1134,8 @@ int Dictionary::LookupIndex(const void* key, int key_size, detail::hash_t hash,
|
|||
// Insert
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* Dictionary::Insert(void* key, int key_size, detail::hash_t hash, void* val, bool copy_key, bool* iterators_invalidated)
|
||||
void* Dictionary::Insert(void* key, int key_size, detail::hash_t hash, void* val, bool copy_key,
|
||||
bool* iterators_invalidated)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
|
||||
|
@ -1185,7 +1199,8 @@ void* Dictionary::Insert(void* key, int key_size, detail::hash_t hash, void* val
|
|||
if ( iterators_invalidated )
|
||||
*iterators_invalidated = true;
|
||||
else
|
||||
reporter->InternalWarning("Dictionary::Insert() possibly caused iterator invalidation");
|
||||
reporter->InternalWarning(
|
||||
"Dictionary::Insert() possibly caused iterator invalidation");
|
||||
}
|
||||
|
||||
// Allocate memory for key if necesary. Key is updated to reflect internal key if necessary.
|
||||
|
@ -1203,8 +1218,8 @@ void* Dictionary::Insert(void* key, int key_size, detail::hash_t hash, void* val
|
|||
}
|
||||
|
||||
// Remap after insert can adjust asap to shorten period of mixed table.
|
||||
// TODO: however, if remap happens right after size up, then it consumes more cpu for this cycle,
|
||||
// a possible hiccup point.
|
||||
// TODO: however, if remap happens right after size up, then it consumes more cpu for this
|
||||
// cycle, a possible hiccup point.
|
||||
if ( Remapping() )
|
||||
Remap();
|
||||
ASSERT_VALID(this);
|
||||
|
@ -1223,7 +1238,8 @@ void Dictionary::InsertRelocateAndAdjust(detail::DictEntry& entry, int insert_po
|
|||
// If remapping in progress, adjust the remap_end to step back a little to cover the new
|
||||
// range if the changed range straddles over remap_end.
|
||||
if ( Remapping() && insert_position <= remap_end && remap_end < last_affected_position )
|
||||
{//[i,j] range changed. if map_end in between. then possibly old entry pushed down across map_end.
|
||||
{ //[i,j] range changed. if map_end in between. then possibly old entry pushed down across
|
||||
//map_end.
|
||||
remap_end = last_affected_position; // adjust to j on the conservative side.
|
||||
}
|
||||
|
||||
|
@ -1239,14 +1255,16 @@ void Dictionary::InsertRelocateAndAdjust(detail::DictEntry& entry, int insert_po
|
|||
}
|
||||
|
||||
/// insert entry into position, relocate other entries when necessary.
|
||||
void Dictionary::InsertAndRelocate(detail::DictEntry& entry, int insert_position, int* last_affected_position)
|
||||
void Dictionary::InsertAndRelocate(detail::DictEntry& entry, int insert_position,
|
||||
int* last_affected_position)
|
||||
{ /// take out the head of cluster and append to the end of the cluster.
|
||||
while ( true )
|
||||
{
|
||||
if ( insert_position >= Capacity() )
|
||||
{
|
||||
ASSERT(insert_position == Capacity());
|
||||
SizeUp(); //copied all the items to new table. as it's just copying without remapping, insert_position is now empty.
|
||||
SizeUp(); // copied all the items to new table. as it's just copying without remapping,
|
||||
// insert_position is now empty.
|
||||
table[insert_position] = entry;
|
||||
if ( last_affected_position )
|
||||
*last_affected_position = insert_position;
|
||||
|
@ -1276,7 +1294,8 @@ void Dictionary::InsertAndRelocate(detail::DictEntry& entry, int insert_position
|
|||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
/// Adjust Cookies on Insert.
|
||||
void Dictionary::AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, int insert_position, int last_affected_position)
|
||||
void Dictionary::AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, int insert_position,
|
||||
int last_affected_position)
|
||||
{
|
||||
ASSERT(c);
|
||||
ASSERT_VALID(c);
|
||||
|
@ -1322,18 +1341,22 @@ void Dictionary::SizeUp()
|
|||
|
||||
// another remap starts.
|
||||
remaps++; // used in Lookup() to cover SizeUp with incomplete remaps.
|
||||
ASSERT(remaps <= log2_buckets);//because we only sizeUp, one direction. we know the previous log2_buckets.
|
||||
ASSERT(
|
||||
remaps <=
|
||||
log2_buckets); // because we only sizeUp, one direction. we know the previous log2_buckets.
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* Dictionary::Remove(const void* key, int key_size, detail::hash_t hash, bool dont_delete, bool* iterators_invalidated)
|
||||
void* Dictionary::Remove(const void* key, int key_size, detail::hash_t hash, bool dont_delete,
|
||||
bool* iterators_invalidated)
|
||||
{ // cookie adjustment: maintain inserts here. maintain next in lower level version.
|
||||
ASSERT_VALID(this);
|
||||
|
||||
ASSERT(! dont_delete); //this is a poorly designed flag. if on, the internal has nowhere to return and memory is lost.
|
||||
ASSERT(! dont_delete); // this is a poorly designed flag. if on, the internal has nowhere to
|
||||
// return and memory is lost.
|
||||
|
||||
int position = LookupIndex(key, key_size, hash);
|
||||
if ( position < 0 )
|
||||
|
@ -1393,9 +1416,11 @@ detail::DictEntry Dictionary::RemoveAndRelocate(int position, int* last_affected
|
|||
detail::DictEntry entry = table[position];
|
||||
while ( true )
|
||||
{
|
||||
if ( position == Capacity() - 1 || table[position+1].Empty() || table[position+1].distance == 0 )
|
||||
if ( position == Capacity() - 1 || table[position + 1].Empty() ||
|
||||
table[position + 1].distance == 0 )
|
||||
{
|
||||
//no next cluster to fill, or next position is empty or next position is already in perfect bucket.
|
||||
// no next cluster to fill, or next position is empty or next position is already in
|
||||
// perfect bucket.
|
||||
table[position].SetEmpty();
|
||||
if ( last_affected_position )
|
||||
*last_affected_position = position;
|
||||
|
@ -1413,10 +1438,12 @@ detail::DictEntry Dictionary::RemoveAndRelocate(int position, int* last_affected
|
|||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
void Dictionary::AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, int position, int last_affected_position)
|
||||
void Dictionary::AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, int position,
|
||||
int last_affected_position)
|
||||
{
|
||||
ASSERT_VALID(c);
|
||||
c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry), c->inserted->end());
|
||||
c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry),
|
||||
c->inserted->end());
|
||||
if ( position < c->next && c->next <= last_affected_position )
|
||||
{
|
||||
int moved = HeadOfClusterByPosition(c->next - 1);
|
||||
|
@ -1432,10 +1459,11 @@ void Dictionary::AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, i
|
|||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void Dictionary::AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& entry,
|
||||
int position, int last_affected_position)
|
||||
void Dictionary::AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& entry, int position,
|
||||
int last_affected_position)
|
||||
{
|
||||
c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry), c->inserted->end());
|
||||
c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry),
|
||||
c->inserted->end());
|
||||
if ( position < c->next && c->next <= last_affected_position )
|
||||
{
|
||||
int moved = HeadOfClusterByPosition(c->next - 1);
|
||||
|
@ -1458,7 +1486,8 @@ void Dictionary::Remap()
|
|||
/// since remap should be very fast. take more at a time.
|
||||
/// delay Remap when cookie is there. hard to handle cookie iteration while size changes.
|
||||
/// remap from bottom up.
|
||||
///remap creates two parts of the dict: [0,remap_end] (remap_end, ...]. the former is mixed with old/new entries; the latter contains all new entries.
|
||||
/// remap creates two parts of the dict: [0,remap_end] (remap_end, ...]. the former is mixed
|
||||
/// with old/new entries; the latter contains all new entries.
|
||||
///
|
||||
if ( num_iterators > 0 )
|
||||
return;
|
||||
|
@ -1468,7 +1497,8 @@ void Dictionary::Remap()
|
|||
{
|
||||
if ( ! table[remap_end].Empty() && Remap(remap_end) )
|
||||
left--;
|
||||
else//< successful Remap may increase remap_end in the case of SizeUp due to insert. if so, remap_end need to be worked on again.
|
||||
else //< successful Remap may increase remap_end in the case of SizeUp due to insert. if so,
|
||||
//remap_end need to be worked on again.
|
||||
remap_end--;
|
||||
}
|
||||
if ( remap_end < 0 )
|
||||
|
@ -1478,14 +1508,18 @@ void Dictionary::Remap()
|
|||
bool Dictionary::Remap(int position, int* new_position)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
///Remap changes item positions by remove() and insert(). to avoid excessive operation. avoid it when safe iteration is in progress.
|
||||
/// Remap changes item positions by remove() and insert(). to avoid excessive operation. avoid
|
||||
/// it when safe iteration is in progress.
|
||||
ASSERT((! cookies || cookies->empty()) && (! iterators || iterators->empty()));
|
||||
int current = BucketByPosition(position); // current bucket
|
||||
int expected = BucketByHash(table[position].hash, log2_buckets); //expected bucket in new table.
|
||||
//equal because 1: it's a new item, 2: it's an old item, but new bucket is the same as old. 50% of old items act this way due to fibhash.
|
||||
int expected = BucketByHash(table[position].hash, log2_buckets); // expected bucket in new
|
||||
// table.
|
||||
// equal because 1: it's a new item, 2: it's an old item, but new bucket is the same as old. 50%
|
||||
// of old items act this way due to fibhash.
|
||||
if ( current == expected )
|
||||
return false;
|
||||
detail::DictEntry entry = RemoveAndRelocate(position); // no iteration cookies to adjust, no need for last_affected_position.
|
||||
detail::DictEntry entry = RemoveAndRelocate(
|
||||
position); // no iteration cookies to adjust, no need for last_affected_position.
|
||||
#ifdef DEBUG
|
||||
entry.bucket = expected;
|
||||
#endif // DEBUG
|
||||
|
@ -1495,7 +1529,9 @@ bool Dictionary::Remap(int position, int* new_position)
|
|||
if ( new_position )
|
||||
*new_position = insert_position;
|
||||
entry.distance = insert_position - expected;
|
||||
InsertAndRelocate(entry, insert_position);// no iteration cookies to adjust, no need for last_affected_position.
|
||||
InsertAndRelocate(
|
||||
entry,
|
||||
insert_position); // no iteration cookies to adjust, no need for last_affected_position.
|
||||
ASSERT_VALID(this);
|
||||
return true;
|
||||
}
|
||||
|
@ -1598,7 +1634,8 @@ void* Dictionary::NextEntryNonConst(detail::HashKey*& h, IterCookie*& c, bool re
|
|||
ASSERT(! table[c->next].Empty());
|
||||
void* v = table[c->next].value;
|
||||
if ( return_hash )
|
||||
h = new detail::HashKey(table[c->next].GetKey(), table[c->next].key_size, table[c->next].hash);
|
||||
h = new detail::HashKey(table[c->next].GetKey(), table[c->next].key_size,
|
||||
table[c->next].hash);
|
||||
|
||||
// prepare for next time.
|
||||
c->next = Next(c->next);
|
||||
|
@ -1637,9 +1674,10 @@ DictIterator::DictIterator(const Dictionary* d, detail::DictEntry* begin, detail
|
|||
while ( curr != end && curr->Empty() )
|
||||
++curr;
|
||||
|
||||
// Cast away the constness so that the number of iterators can be modified in the dictionary. This does
|
||||
// violate the constness guarantees of const-begin()/end() and cbegin()/cend(), but we're not modifying the
|
||||
// actual data in the collection, just a counter in the wrapper of the collection.
|
||||
// Cast away the constness so that the number of iterators can be modified in the dictionary.
|
||||
// This does violate the constness guarantees of const-begin()/end() and cbegin()/cend(), but
|
||||
// we're not modifying the actual data in the collection, just a counter in the wrapper of the
|
||||
// collection.
|
||||
dict = const_cast<Dictionary*>(d);
|
||||
dict->IncrIters();
|
||||
}
|
||||
|
@ -1657,10 +1695,10 @@ DictIterator& DictIterator::operator++()
|
|||
{
|
||||
// The non-robust case is easy. Just advanced the current position forward until you find
|
||||
// one isn't empty and isn't the end.
|
||||
do {
|
||||
do
|
||||
{
|
||||
++curr;
|
||||
}
|
||||
while ( curr != end && curr->Empty() );
|
||||
} while ( curr != end && curr->Empty() );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -1739,9 +1777,6 @@ DictIterator& DictIterator::operator=(DictIterator&& that)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
RobustDictIterator Dictionary::MakeRobustIterator()
|
||||
{
|
||||
if ( ! iterators )
|
||||
|
@ -1827,7 +1862,8 @@ RobustDictIterator::RobustDictIterator(const RobustDictIterator& other) : curr(n
|
|||
visited = new std::vector<detail::DictEntry>();
|
||||
|
||||
if ( other.inserted )
|
||||
std::copy(other.inserted->begin(), other.inserted->end(), std::back_inserter(*inserted));
|
||||
std::copy(other.inserted->begin(), other.inserted->end(),
|
||||
std::back_inserter(*inserted));
|
||||
|
||||
if ( other.visited )
|
||||
std::copy(other.visited->begin(), other.visited->end(), std::back_inserter(*visited));
|
||||
|
@ -1852,7 +1888,8 @@ RobustDictIterator::RobustDictIterator(RobustDictIterator&& other) : curr(nullpt
|
|||
|
||||
dict = other.dict;
|
||||
dict->iterators->push_back(this);
|
||||
dict->iterators->erase(std::remove(dict->iterators->begin(), dict->iterators->end(), &other),
|
||||
dict->iterators->erase(
|
||||
std::remove(dict->iterators->begin(), dict->iterators->end(), &other),
|
||||
dict->iterators->end());
|
||||
other.dict = nullptr;
|
||||
|
||||
|
|
192
src/Dict.h
192
src/Dict.h
|
@ -3,25 +3,31 @@
|
|||
#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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
bool operator==(const DictEntry& r) const
|
||||
{
|
||||
return Equal(r.GetKey(), r.key_size, r.hash);
|
||||
}
|
||||
bool operator!=(const DictEntry& r) const
|
||||
{
|
||||
return ! Equal(r.GetKey(), r.key_size, r.hash);
|
||||
return (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); }
|
||||
};
|
||||
|
||||
} // 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); }
|
||||
|
||||
private:
|
||||
|
||||
friend class Dictionary;
|
||||
|
||||
DictIterator(const Dictionary* d, detail::DictEntry* begin, detail::DictEntry* end);
|
||||
|
@ -187,7 +191,8 @@ private:
|
|||
detail::DictEntry* end = nullptr;
|
||||
};
|
||||
|
||||
class RobustDictIterator {
|
||||
class RobustDictIterator
|
||||
{
|
||||
public:
|
||||
using value_type = detail::DictEntry;
|
||||
using reference = detail::DictEntry&;
|
||||
|
@ -205,7 +210,12 @@ public:
|
|||
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); }
|
||||
|
@ -239,9 +249,11 @@ 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
|
||||
|
@ -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,20 +286,20 @@ 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; }
|
||||
|
@ -316,12 +331,15 @@ 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; }
|
||||
|
||||
|
@ -331,14 +349,16 @@ 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;
|
||||
|
@ -419,17 +439,20 @@ 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
|
||||
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);
|
||||
|
||||
|
@ -437,13 +460,16 @@ private:
|
|||
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.
|
||||
detail::DictEntry RemoveRelocateAndAdjust(int position);
|
||||
|
@ -452,10 +478,12 @@ private:
|
|||
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);
|
||||
[[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.
|
||||
|
||||
|
@ -471,7 +499,9 @@ 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();
|
||||
|
@ -512,34 +542,36 @@ private:
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
[[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
|
||||
|
@ -547,8 +579,8 @@ public:
|
|||
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"
|
||||
|
@ -556,9 +588,13 @@ public:
|
|||
#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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -74,9 +71,8 @@ bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caple
|
|||
|
||||
bool is_tcp = (proto == IPPROTO_TCP);
|
||||
bool is_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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
25
src/Event.cc
25
src/Event.cc
|
@ -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));
|
||||
|
|
26
src/Event.h
26
src/Event.h
|
@ -5,18 +5,20 @@
|
|||
#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,
|
||||
|
@ -47,7 +49,8 @@ protected:
|
|||
Event* next_event;
|
||||
};
|
||||
|
||||
class EventMgr final : public Obj, public iosource::IOSource {
|
||||
class EventMgr final : public Obj, public iosource::IOSource
|
||||
{
|
||||
public:
|
||||
EventMgr();
|
||||
~EventMgr() override;
|
||||
|
@ -72,11 +75,11 @@ 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);
|
||||
|
||||
|
@ -92,8 +95,7 @@ public:
|
|||
// non-analyzer event.
|
||||
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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -2,40 +2,35 @@
|
|||
|
||||
#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 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);
|
||||
|
||||
|
@ -72,18 +67,24 @@ private:
|
|||
};
|
||||
|
||||
// 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; }
|
||||
|
||||
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; }
|
||||
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
#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"
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#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 "event.bif.func_h"
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
618
src/Expr.cc
618
src/Expr.cc
File diff suppressed because it is too large
Load diff
370
src/Expr.h
370
src/Expr.h
|
@ -3,25 +3,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "zeek/ZeekList.h"
|
||||
#include "zeek/EventHandler.h"
|
||||
#include "zeek/IntrusivePtr.h"
|
||||
#include "zeek/StmtBase.h"
|
||||
#include "zeek/Timer.h"
|
||||
#include "zeek/Type.h"
|
||||
#include "zeek/EventHandler.h"
|
||||
#include "zeek/TraverseTypes.h"
|
||||
#include "zeek/Type.h"
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/ZeekArgs.h"
|
||||
#include "zeek/ZeekList.h"
|
||||
|
||||
namespace zeek {
|
||||
namespace zeek
|
||||
{
|
||||
template <class T> class IntrusivePtr;
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class Frame;
|
||||
class Scope;
|
||||
|
@ -29,23 +31,42 @@ struct function_ingredients;
|
|||
using IDPtr = IntrusivePtr<ID>;
|
||||
using ScopePtr = IntrusivePtr<Scope>;
|
||||
|
||||
enum BroExprTag : int {
|
||||
enum BroExprTag : int
|
||||
{
|
||||
EXPR_ANY = -1,
|
||||
EXPR_NAME, EXPR_CONST,
|
||||
EXPR_NAME,
|
||||
EXPR_CONST,
|
||||
EXPR_CLONE,
|
||||
EXPR_INCR, EXPR_DECR,
|
||||
EXPR_NOT, EXPR_COMPLEMENT,
|
||||
EXPR_POSITIVE, EXPR_NEGATE,
|
||||
EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
|
||||
EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
|
||||
EXPR_AND, EXPR_OR, EXPR_XOR,
|
||||
EXPR_AND_AND, EXPR_OR_OR,
|
||||
EXPR_LT, EXPR_LE, EXPR_EQ, EXPR_NE, EXPR_GE, EXPR_GT,
|
||||
EXPR_INCR,
|
||||
EXPR_DECR,
|
||||
EXPR_NOT,
|
||||
EXPR_COMPLEMENT,
|
||||
EXPR_POSITIVE,
|
||||
EXPR_NEGATE,
|
||||
EXPR_ADD,
|
||||
EXPR_SUB,
|
||||
EXPR_ADD_TO,
|
||||
EXPR_REMOVE_FROM,
|
||||
EXPR_TIMES,
|
||||
EXPR_DIVIDE,
|
||||
EXPR_MOD,
|
||||
EXPR_AND,
|
||||
EXPR_OR,
|
||||
EXPR_XOR,
|
||||
EXPR_AND_AND,
|
||||
EXPR_OR_OR,
|
||||
EXPR_LT,
|
||||
EXPR_LE,
|
||||
EXPR_EQ,
|
||||
EXPR_NE,
|
||||
EXPR_GE,
|
||||
EXPR_GT,
|
||||
EXPR_COND,
|
||||
EXPR_REF,
|
||||
EXPR_ASSIGN,
|
||||
EXPR_INDEX,
|
||||
EXPR_FIELD, EXPR_HAS_FIELD,
|
||||
EXPR_FIELD,
|
||||
EXPR_HAS_FIELD,
|
||||
EXPR_RECORD_CONSTRUCTOR,
|
||||
EXPR_TABLE_CONSTRUCTOR,
|
||||
EXPR_SET_CONSTRUCTOR,
|
||||
|
@ -70,9 +91,12 @@ enum BroExprTag : int {
|
|||
// The following types of expressions are only created for
|
||||
// ASTs transformed to reduced form; they aren't germane for
|
||||
// ASTs produced by parsing .zeek script files.
|
||||
EXPR_INDEX_ASSIGN, EXPR_FIELD_LHS_ASSIGN,
|
||||
EXPR_INDEX_ASSIGN,
|
||||
EXPR_FIELD_LHS_ASSIGN,
|
||||
EXPR_APPEND_TO,
|
||||
EXPR_TO_ANY_COERCE, EXPR_FROM_ANY_COERCE, EXPR_FROM_ANY_VEC_COERCE,
|
||||
EXPR_TO_ANY_COERCE,
|
||||
EXPR_FROM_ANY_COERCE,
|
||||
EXPR_FROM_ANY_VEC_COERCE,
|
||||
EXPR_ANY_INDEX,
|
||||
|
||||
EXPR_NOP,
|
||||
|
@ -119,18 +143,20 @@ using StmtPtr = IntrusivePtr<Stmt>;
|
|||
|
||||
class ExprOptInfo;
|
||||
|
||||
class Expr : public Obj {
|
||||
class Expr : public Obj
|
||||
{
|
||||
public:
|
||||
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); }
|
||||
|
||||
BroExprTag Tag() const { return tag; }
|
||||
|
||||
Expr* Ref() { zeek::Ref(this); return this; }
|
||||
Expr* Ref()
|
||||
{
|
||||
zeek::Ref(this);
|
||||
return this;
|
||||
}
|
||||
ExprPtr ThisPtr() { return {NewRef{}, this}; }
|
||||
|
||||
// Evaluates the expression and returns a corresponding Val*,
|
||||
|
@ -270,9 +296,7 @@ public:
|
|||
bool HasConstantOps() const
|
||||
{
|
||||
return GetOp1() && GetOp1()->IsConst() &&
|
||||
(! GetOp2() ||
|
||||
(GetOp2()->IsConst() &&
|
||||
(! GetOp3() || GetOp3()->IsConst())));
|
||||
(! GetOp2() || (GetOp2()->IsConst() && (! GetOp3() || GetOp3()->IsConst())));
|
||||
}
|
||||
|
||||
// True if the expression is reduced to a form that can be
|
||||
|
@ -294,8 +318,7 @@ public:
|
|||
virtual bool WillTransform(Reducer* c) const { return false; }
|
||||
|
||||
// The same, but for the expression when used in a conditional context.
|
||||
virtual bool WillTransformInConditional(Reducer* c) const
|
||||
{ return false; }
|
||||
virtual bool WillTransformInConditional(Reducer* c) const { return false; }
|
||||
|
||||
// Returns the current expression transformed into "new_me".
|
||||
ExprPtr TransformMe(ExprPtr new_me, Reducer* c, StmtPtr& red_stmt);
|
||||
|
@ -308,8 +331,7 @@ public:
|
|||
// for assignment statements; thus, its form is not guarantee
|
||||
// suitable for use as an operand.
|
||||
virtual ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt);
|
||||
virtual ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt)
|
||||
{ return Reduce(c, red_stmt); }
|
||||
virtual ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { return Reduce(c, red_stmt); }
|
||||
|
||||
// Reduces the expression to one whose operands are singletons.
|
||||
// Returns a predecessor statement (which might be a StmtList), if any.
|
||||
|
@ -331,7 +353,9 @@ public:
|
|||
ExprPtr AssignToTemporary(ExprPtr e, Reducer* c, StmtPtr& red_stmt);
|
||||
// Same but for this expression.
|
||||
ExprPtr AssignToTemporary(Reducer* c, StmtPtr& red_stmt)
|
||||
{ return AssignToTemporary(ThisPtr(), c, red_stmt); }
|
||||
{
|
||||
return AssignToTemporary(ThisPtr(), c, red_stmt);
|
||||
}
|
||||
|
||||
// If the expression always evaluates to the same value, returns
|
||||
// that value. Otherwise, returns nullptr.
|
||||
|
@ -358,8 +382,7 @@ public:
|
|||
// Access to the original expression from which this one is derived,
|
||||
// or this one if we don't have an original. Returns a bare pointer
|
||||
// rather than an ExprPtr to emphasize that the access is read-only.
|
||||
const Expr* Original() const
|
||||
{ return original ? original->Original() : this; }
|
||||
const Expr* Original() const { return original ? original->Original() : this; }
|
||||
|
||||
// Designate the given Expr node as the original for this one.
|
||||
void SetOriginal(ExprPtr _orig)
|
||||
|
@ -432,7 +455,8 @@ protected:
|
|||
ExprOptInfo* opt_info;
|
||||
};
|
||||
|
||||
class NameExpr final : public Expr {
|
||||
class NameExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
explicit NameExpr(IDPtr id, bool const_init = false);
|
||||
|
||||
|
@ -466,7 +490,8 @@ protected:
|
|||
bool in_const_init;
|
||||
};
|
||||
|
||||
class ConstExpr final : public Expr {
|
||||
class ConstExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
explicit ConstExpr(ValPtr val);
|
||||
|
||||
|
@ -486,7 +511,8 @@ protected:
|
|||
ValPtr val;
|
||||
};
|
||||
|
||||
class UnaryExpr : public Expr {
|
||||
class UnaryExpr : public Expr
|
||||
{
|
||||
public:
|
||||
Expr* Op() const { return op.get(); }
|
||||
|
||||
|
@ -521,7 +547,8 @@ protected:
|
|||
ExprPtr op;
|
||||
};
|
||||
|
||||
class BinaryExpr : public Expr {
|
||||
class BinaryExpr : public Expr
|
||||
{
|
||||
public:
|
||||
Expr* Op1() const { return op1.get(); }
|
||||
Expr* Op2() const { return op2.get(); }
|
||||
|
@ -550,8 +577,7 @@ public:
|
|||
void SetOp2(ExprPtr _op) override final { op2 = std::move(_op); }
|
||||
|
||||
protected:
|
||||
BinaryExpr(BroExprTag arg_tag,
|
||||
ExprPtr arg_op1, ExprPtr arg_op2)
|
||||
BinaryExpr(BroExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2)
|
||||
: Expr(arg_tag), op1(std::move(arg_op1)), op2(std::move(arg_op2))
|
||||
{
|
||||
if ( ! (op1 && op2) )
|
||||
|
@ -599,7 +625,8 @@ protected:
|
|||
ExprPtr op2;
|
||||
};
|
||||
|
||||
class CloneExpr final : public UnaryExpr {
|
||||
class CloneExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit CloneExpr(ExprPtr op);
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
@ -611,7 +638,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class IncrExpr final : public UnaryExpr {
|
||||
class IncrExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
IncrExpr(BroExprTag tag, ExprPtr op);
|
||||
|
||||
|
@ -629,7 +657,8 @@ public:
|
|||
ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override;
|
||||
};
|
||||
|
||||
class ComplementExpr final : public UnaryExpr {
|
||||
class ComplementExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit ComplementExpr(ExprPtr op);
|
||||
|
||||
|
@ -642,7 +671,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class NotExpr final : public UnaryExpr {
|
||||
class NotExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit NotExpr(ExprPtr op);
|
||||
|
||||
|
@ -655,7 +685,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class PosExpr final : public UnaryExpr {
|
||||
class PosExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit PosExpr(ExprPtr op);
|
||||
|
||||
|
@ -668,7 +699,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class NegExpr final : public UnaryExpr {
|
||||
class NegExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit NegExpr(ExprPtr op);
|
||||
|
||||
|
@ -681,7 +713,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class SizeExpr final : public UnaryExpr {
|
||||
class SizeExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit SizeExpr(ExprPtr op);
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
@ -693,7 +726,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class AddExpr final : public BinaryExpr {
|
||||
class AddExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
AddExpr(ExprPtr op1, ExprPtr op2);
|
||||
void Canonicize() override;
|
||||
|
@ -707,7 +741,8 @@ protected:
|
|||
ExprPtr BuildSub(const ExprPtr& op1, const ExprPtr& op2);
|
||||
};
|
||||
|
||||
class AddToExpr final : public BinaryExpr {
|
||||
class AddToExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
AddToExpr(ExprPtr op1, ExprPtr op2);
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
@ -718,7 +753,8 @@ public:
|
|||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||
};
|
||||
|
||||
class RemoveFromExpr final : public BinaryExpr {
|
||||
class RemoveFromExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
RemoveFromExpr(ExprPtr op1, ExprPtr op2);
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
@ -729,7 +765,8 @@ public:
|
|||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||
};
|
||||
|
||||
class SubExpr final : public BinaryExpr {
|
||||
class SubExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
SubExpr(ExprPtr op1, ExprPtr op2);
|
||||
|
||||
|
@ -739,7 +776,8 @@ public:
|
|||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||
};
|
||||
|
||||
class TimesExpr final : public BinaryExpr {
|
||||
class TimesExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
TimesExpr(ExprPtr op1, ExprPtr op2);
|
||||
void Canonicize() override;
|
||||
|
@ -750,7 +788,8 @@ public:
|
|||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||
};
|
||||
|
||||
class DivideExpr final : public BinaryExpr {
|
||||
class DivideExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
DivideExpr(ExprPtr op1, ExprPtr op2);
|
||||
|
||||
|
@ -763,7 +802,8 @@ protected:
|
|||
ValPtr AddrFold(Val* v1, Val* v2) const override;
|
||||
};
|
||||
|
||||
class ModExpr final : public BinaryExpr {
|
||||
class ModExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
ModExpr(ExprPtr op1, ExprPtr op2);
|
||||
|
||||
|
@ -771,7 +811,8 @@ public:
|
|||
ExprPtr Duplicate() override;
|
||||
};
|
||||
|
||||
class BoolExpr final : public BinaryExpr {
|
||||
class BoolExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
BoolExpr(BroExprTag tag, ExprPtr op1, ExprPtr op2);
|
||||
|
||||
|
@ -789,7 +830,8 @@ protected:
|
|||
bool IsFalse(const ExprPtr& e) const;
|
||||
};
|
||||
|
||||
class BitExpr final : public BinaryExpr {
|
||||
class BitExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
BitExpr(BroExprTag tag, ExprPtr op1, ExprPtr op2);
|
||||
|
||||
|
@ -799,7 +841,8 @@ public:
|
|||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||
};
|
||||
|
||||
class EqExpr final : public BinaryExpr {
|
||||
class EqExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
EqExpr(BroExprTag tag, ExprPtr op1, ExprPtr op2);
|
||||
void Canonicize() override;
|
||||
|
@ -814,7 +857,8 @@ protected:
|
|||
ValPtr Fold(Val* v1, Val* v2) const override;
|
||||
};
|
||||
|
||||
class RelExpr final : public BinaryExpr {
|
||||
class RelExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
RelExpr(BroExprTag tag, ExprPtr op1, ExprPtr op2);
|
||||
void Canonicize() override;
|
||||
|
@ -826,7 +870,8 @@ public:
|
|||
bool InvertSense() override;
|
||||
};
|
||||
|
||||
class CondExpr final : public Expr {
|
||||
class CondExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
CondExpr(ExprPtr op1, ExprPtr op2, ExprPtr op3);
|
||||
|
||||
|
@ -865,7 +910,8 @@ protected:
|
|||
ExprPtr op3;
|
||||
};
|
||||
|
||||
class RefExpr final : public UnaryExpr {
|
||||
class RefExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit RefExpr(ExprPtr op);
|
||||
|
||||
|
@ -884,14 +930,13 @@ public:
|
|||
StmtPtr ReduceToLHS(Reducer* c);
|
||||
};
|
||||
|
||||
class AssignExpr : public BinaryExpr {
|
||||
class AssignExpr : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
// If val is given, evaluating this expression will always yield the val
|
||||
// yet still perform the assignment. Used for triggers.
|
||||
AssignExpr(ExprPtr op1, ExprPtr op2, bool is_init,
|
||||
ValPtr val = nullptr,
|
||||
const AttributesPtr& attrs = nullptr,
|
||||
bool type_check = true);
|
||||
AssignExpr(ExprPtr op1, ExprPtr op2, bool is_init, ValPtr val = nullptr,
|
||||
const AttributesPtr& attrs = nullptr, bool type_check = true);
|
||||
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
void EvalIntoAggregate(const zeek::Type* t, Val* aggr, Frame* f) const override;
|
||||
|
@ -922,23 +967,22 @@ protected:
|
|||
bool is_temp = false; // Optimization related
|
||||
|
||||
ValPtr val; // optional
|
||||
|
||||
};
|
||||
|
||||
class IndexSliceAssignExpr final : public AssignExpr {
|
||||
class IndexSliceAssignExpr final : public AssignExpr
|
||||
{
|
||||
public:
|
||||
IndexSliceAssignExpr(ExprPtr op1,
|
||||
ExprPtr op2, bool is_init);
|
||||
IndexSliceAssignExpr(ExprPtr op1, ExprPtr op2, bool is_init);
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
||||
// Optimization-related:
|
||||
ExprPtr Duplicate() override;
|
||||
};
|
||||
|
||||
class IndexExpr : public BinaryExpr {
|
||||
class IndexExpr : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
IndexExpr(ExprPtr op1,
|
||||
ListExprPtr op2, bool is_slice = false);
|
||||
IndexExpr(ExprPtr op1, ListExprPtr op2, bool is_slice = false);
|
||||
|
||||
bool CanAdd() const override;
|
||||
bool CanDel() const override;
|
||||
|
@ -986,24 +1030,21 @@ extern VectorValPtr index_slice(VectorVal* vect, int first, int last);
|
|||
extern StringValPtr index_string(const String* s, const ListVal* lv);
|
||||
|
||||
// Returns a vector indexed by a boolean vector.
|
||||
extern VectorValPtr vector_bool_select(VectorTypePtr vt, const VectorVal* v1,
|
||||
const VectorVal* v2);
|
||||
extern VectorValPtr vector_bool_select(VectorTypePtr vt, const VectorVal* v1, const VectorVal* v2);
|
||||
|
||||
// Returns a vector indexed by a numeric vector (which specifies the
|
||||
// indices to select).
|
||||
extern VectorValPtr vector_int_select(VectorTypePtr vt, const VectorVal* v1,
|
||||
const VectorVal* v2);
|
||||
extern VectorValPtr vector_int_select(VectorTypePtr vt, const VectorVal* v1, const VectorVal* v2);
|
||||
|
||||
class IndexExprWhen final : public IndexExpr {
|
||||
class IndexExprWhen final : public IndexExpr
|
||||
{
|
||||
public:
|
||||
static inline std::vector<ValPtr> results = {};
|
||||
static inline int evaluating = 0;
|
||||
|
||||
static void StartEval()
|
||||
{ ++evaluating; }
|
||||
static void StartEval() { ++evaluating; }
|
||||
|
||||
static void EndEval()
|
||||
{ --evaluating; }
|
||||
static void EndEval() { --evaluating; }
|
||||
|
||||
static std::vector<ValPtr> TakeAllResults()
|
||||
{
|
||||
|
@ -1014,7 +1055,8 @@ public:
|
|||
|
||||
IndexExprWhen(ExprPtr op1, ListExprPtr op2, bool is_slice = false)
|
||||
: IndexExpr(std::move(op1), std::move(op2), is_slice)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
ValPtr Eval(Frame* f) const override
|
||||
{
|
||||
|
@ -1030,7 +1072,8 @@ public:
|
|||
ExprPtr Duplicate() override;
|
||||
};
|
||||
|
||||
class FieldExpr final : public UnaryExpr {
|
||||
class FieldExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
FieldExpr(ExprPtr op, const char* field_name);
|
||||
~FieldExpr() override;
|
||||
|
@ -1060,7 +1103,8 @@ protected:
|
|||
|
||||
// "rec?$fieldname" is true if the value of $fieldname in rec is not nil.
|
||||
// "rec?$$attrname" is true if the attribute attrname is not nil.
|
||||
class HasFieldExpr final : public UnaryExpr {
|
||||
class HasFieldExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
HasFieldExpr(ExprPtr op, const char* field_name);
|
||||
~HasFieldExpr() override;
|
||||
|
@ -1080,13 +1124,13 @@ protected:
|
|||
int field;
|
||||
};
|
||||
|
||||
class RecordConstructorExpr final : public Expr {
|
||||
class RecordConstructorExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
explicit RecordConstructorExpr(ListExprPtr constructor_list);
|
||||
|
||||
// This form is used to construct records of a known (ultimate) type.
|
||||
explicit RecordConstructorExpr(RecordTypePtr known_rt,
|
||||
ListExprPtr constructor_list);
|
||||
explicit RecordConstructorExpr(RecordTypePtr known_rt, ListExprPtr constructor_list);
|
||||
|
||||
ListExprPtr Op() const { return op; }
|
||||
const auto& Map() const { return map; }
|
||||
|
@ -1113,15 +1157,13 @@ protected:
|
|||
std::optional<std::vector<int>> map;
|
||||
};
|
||||
|
||||
class TableConstructorExpr final : public UnaryExpr {
|
||||
class TableConstructorExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
TableConstructorExpr(ListExprPtr constructor_list,
|
||||
std::unique_ptr<std::vector<AttrPtr>> attrs,
|
||||
TypePtr arg_type = nullptr,
|
||||
AttributesPtr arg_attrs = nullptr);
|
||||
TableConstructorExpr(ListExprPtr constructor_list, std::unique_ptr<std::vector<AttrPtr>> attrs,
|
||||
TypePtr arg_type = nullptr, AttributesPtr arg_attrs = nullptr);
|
||||
|
||||
const AttributesPtr& GetAttrs() const
|
||||
{ return attrs; }
|
||||
const AttributesPtr& GetAttrs() const { return attrs; }
|
||||
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
||||
|
@ -1140,15 +1182,13 @@ protected:
|
|||
AttributesPtr attrs;
|
||||
};
|
||||
|
||||
class SetConstructorExpr final : public UnaryExpr {
|
||||
class SetConstructorExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
SetConstructorExpr(ListExprPtr constructor_list,
|
||||
std::unique_ptr<std::vector<AttrPtr>> attrs,
|
||||
TypePtr arg_type = nullptr,
|
||||
AttributesPtr arg_attrs = nullptr);
|
||||
SetConstructorExpr(ListExprPtr constructor_list, std::unique_ptr<std::vector<AttrPtr>> attrs,
|
||||
TypePtr arg_type = nullptr, AttributesPtr arg_attrs = nullptr);
|
||||
|
||||
const AttributesPtr& GetAttrs() const
|
||||
{ return attrs; }
|
||||
const AttributesPtr& GetAttrs() const { return attrs; }
|
||||
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
||||
|
@ -1167,10 +1207,10 @@ protected:
|
|||
AttributesPtr attrs;
|
||||
};
|
||||
|
||||
class VectorConstructorExpr final : public UnaryExpr {
|
||||
class VectorConstructorExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
explicit VectorConstructorExpr(ListExprPtr constructor_list,
|
||||
TypePtr arg_type = nullptr);
|
||||
explicit VectorConstructorExpr(ListExprPtr constructor_list, TypePtr arg_type = nullptr);
|
||||
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
||||
|
@ -1185,7 +1225,8 @@ protected:
|
|||
void ExprDescribe(ODesc* d) const override;
|
||||
};
|
||||
|
||||
class FieldAssignExpr final : public UnaryExpr {
|
||||
class FieldAssignExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
FieldAssignExpr(const char* field_name, ExprPtr value);
|
||||
|
||||
|
@ -1214,7 +1255,8 @@ protected:
|
|||
std::string field_name;
|
||||
};
|
||||
|
||||
class ArithCoerceExpr final : public UnaryExpr {
|
||||
class ArithCoerceExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
ArithCoerceExpr(ExprPtr op, TypeTag t);
|
||||
|
||||
|
@ -1229,7 +1271,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class RecordCoerceExpr final : public UnaryExpr {
|
||||
class RecordCoerceExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
RecordCoerceExpr(ExprPtr op, RecordTypePtr r);
|
||||
|
||||
|
@ -1247,10 +1290,10 @@ protected:
|
|||
std::vector<int> map;
|
||||
};
|
||||
|
||||
extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v,
|
||||
const std::vector<int>& map);
|
||||
extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector<int>& map);
|
||||
|
||||
class TableCoerceExpr final : public UnaryExpr {
|
||||
class TableCoerceExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
TableCoerceExpr(ExprPtr op, TableTypePtr r);
|
||||
~TableCoerceExpr() override;
|
||||
|
@ -1262,7 +1305,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class VectorCoerceExpr final : public UnaryExpr {
|
||||
class VectorCoerceExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
VectorCoerceExpr(ExprPtr op, VectorTypePtr v);
|
||||
~VectorCoerceExpr() override;
|
||||
|
@ -1274,7 +1318,8 @@ protected:
|
|||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
class ScheduleTimer final : public Timer {
|
||||
class ScheduleTimer final : public Timer
|
||||
{
|
||||
public:
|
||||
ScheduleTimer(const EventHandlerPtr& event, zeek::Args args, double t);
|
||||
~ScheduleTimer() override;
|
||||
|
@ -1286,7 +1331,8 @@ protected:
|
|||
zeek::Args args;
|
||||
};
|
||||
|
||||
class ScheduleExpr final : public Expr {
|
||||
class ScheduleExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
ScheduleExpr(ExprPtr when, EventExprPtr event);
|
||||
|
||||
|
@ -1320,7 +1366,8 @@ protected:
|
|||
EventExprPtr event;
|
||||
};
|
||||
|
||||
class InExpr final : public BinaryExpr {
|
||||
class InExpr final : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
InExpr(ExprPtr op1, ExprPtr op2);
|
||||
|
||||
|
@ -1331,13 +1378,12 @@ public:
|
|||
|
||||
protected:
|
||||
ValPtr Fold(Val* v1, Val* v2) const override;
|
||||
|
||||
};
|
||||
|
||||
class CallExpr final : public Expr {
|
||||
class CallExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
CallExpr(ExprPtr func, ListExprPtr args,
|
||||
bool in_hook = false);
|
||||
CallExpr(ExprPtr func, ListExprPtr args, bool in_hook = false);
|
||||
|
||||
Expr* Func() const { return func.get(); }
|
||||
ListExpr* Args() const { return args.get(); }
|
||||
|
@ -1365,16 +1411,15 @@ protected:
|
|||
ListExprPtr args;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class that represents an anonymous function expression in Zeek.
|
||||
* On evaluation, captures the frame that it is evaluated in. This becomes
|
||||
* the closure for the instance of the function that it creates.
|
||||
*/
|
||||
class LambdaExpr final : public Expr {
|
||||
class LambdaExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
||||
IDPList outer_ids);
|
||||
LambdaExpr(std::unique_ptr<function_ingredients> ingredients, IDPList outer_ids);
|
||||
|
||||
const std::string& Name() const { return my_name; }
|
||||
const IDPList& OuterIDs() const { return outer_ids; }
|
||||
|
@ -1407,7 +1452,8 @@ private:
|
|||
|
||||
// This comes before EventExpr so that EventExpr::GetOp1 can return its
|
||||
// arguments as convertible to ExprPtr.
|
||||
class ListExpr : public Expr {
|
||||
class ListExpr : public Expr
|
||||
{
|
||||
public:
|
||||
ListExpr();
|
||||
explicit ListExpr(ExprPtr e);
|
||||
|
@ -1447,7 +1493,8 @@ protected:
|
|||
ExprPList exprs;
|
||||
};
|
||||
|
||||
class EventExpr final : public Expr {
|
||||
class EventExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
EventExpr(const char* name, ListExprPtr args);
|
||||
|
||||
|
@ -1468,8 +1515,7 @@ public:
|
|||
StmtPtr ReduceToSingletons(Reducer* c) override;
|
||||
|
||||
ExprPtr GetOp1() const override final { return args; }
|
||||
void SetOp1(ExprPtr _op) override final
|
||||
{ args = {NewRef{}, _op->AsListExpr()}; }
|
||||
void SetOp1(ExprPtr _op) override final { args = {NewRef{}, _op->AsListExpr()}; }
|
||||
|
||||
protected:
|
||||
void ExprDescribe(ODesc* d) const override;
|
||||
|
@ -1479,13 +1525,14 @@ protected:
|
|||
ListExprPtr args;
|
||||
};
|
||||
|
||||
|
||||
class RecordAssignExpr final : public ListExpr {
|
||||
class RecordAssignExpr final : public ListExpr
|
||||
{
|
||||
public:
|
||||
RecordAssignExpr(const ExprPtr& record, const ExprPtr& init_list, bool is_init);
|
||||
};
|
||||
|
||||
class CastExpr final : public UnaryExpr {
|
||||
class CastExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
CastExpr(ExprPtr op, TypePtr t);
|
||||
|
||||
|
@ -1501,7 +1548,8 @@ protected:
|
|||
// and populates "error" with an error message.
|
||||
extern ValPtr cast_value(ValPtr v, const TypePtr& t, std::string& error);
|
||||
|
||||
class IsExpr final : public UnaryExpr {
|
||||
class IsExpr final : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
IsExpr(ExprPtr op, TypePtr t);
|
||||
|
||||
|
@ -1518,11 +1566,11 @@ private:
|
|||
TypePtr t;
|
||||
};
|
||||
|
||||
|
||||
class InlineExpr : public Expr {
|
||||
class InlineExpr : public Expr
|
||||
{
|
||||
public:
|
||||
InlineExpr(ListExprPtr arg_args, std::vector<IDPtr> params, StmtPtr body,
|
||||
int frame_offset, TypePtr ret_type);
|
||||
InlineExpr(ListExprPtr arg_args, std::vector<IDPtr> params, StmtPtr body, int frame_offset,
|
||||
TypePtr ret_type);
|
||||
|
||||
bool IsPure() const override;
|
||||
|
||||
|
@ -1551,7 +1599,8 @@ protected:
|
|||
|
||||
// A companion to AddToExpr that's for vector-append, instantiated during
|
||||
// the reduction process.
|
||||
class AppendToExpr : public BinaryExpr {
|
||||
class AppendToExpr : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
AppendToExpr(ExprPtr op1, ExprPtr op2);
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
@ -1563,7 +1612,8 @@ public:
|
|||
};
|
||||
|
||||
// An internal class for reduced form.
|
||||
class IndexAssignExpr : public BinaryExpr {
|
||||
class IndexAssignExpr : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
// "op1[op2] = op3", all reduced.
|
||||
IndexAssignExpr(ExprPtr op1, ExprPtr op2, ExprPtr op3);
|
||||
|
@ -1589,12 +1639,12 @@ protected:
|
|||
};
|
||||
|
||||
// An internal class for reduced form.
|
||||
class FieldLHSAssignExpr : public BinaryExpr {
|
||||
class FieldLHSAssignExpr : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
// "op1$field = RHS", where RHS is reduced with respect to
|
||||
// ReduceToFieldAssignment().
|
||||
FieldLHSAssignExpr(ExprPtr op1, ExprPtr op2, const char* field_name,
|
||||
int field);
|
||||
FieldLHSAssignExpr(ExprPtr op1, ExprPtr op2, const char* field_name, int field);
|
||||
|
||||
const char* FieldName() const { return field_name; }
|
||||
int Field() const { return field; }
|
||||
|
@ -1617,7 +1667,8 @@ protected:
|
|||
|
||||
// Expression to explicitly capture conversion to an "any" type, rather
|
||||
// than it occurring implicitly during script interpretation.
|
||||
class CoerceToAnyExpr : public UnaryExpr {
|
||||
class CoerceToAnyExpr : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
CoerceToAnyExpr(ExprPtr op);
|
||||
|
||||
|
@ -1628,7 +1679,8 @@ protected:
|
|||
};
|
||||
|
||||
// Same, but for conversion from an "any" type.
|
||||
class CoerceFromAnyExpr : public UnaryExpr {
|
||||
class CoerceFromAnyExpr : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
CoerceFromAnyExpr(ExprPtr op, TypePtr to_type);
|
||||
|
||||
|
@ -1639,7 +1691,8 @@ protected:
|
|||
};
|
||||
|
||||
// ... and for conversion from a "vector of any" type.
|
||||
class CoerceFromAnyVecExpr : public UnaryExpr {
|
||||
class CoerceFromAnyVecExpr : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
// to_type is yield type, not VectorType.
|
||||
CoerceFromAnyVecExpr(ExprPtr op, TypePtr to_type);
|
||||
|
@ -1653,7 +1706,8 @@ protected:
|
|||
};
|
||||
|
||||
// Expression used to explicitly capture [a, b, c, ...] = x assignments.
|
||||
class AnyIndexExpr : public UnaryExpr {
|
||||
class AnyIndexExpr : public UnaryExpr
|
||||
{
|
||||
public:
|
||||
AnyIndexExpr(ExprPtr op, int index);
|
||||
|
||||
|
@ -1671,7 +1725,8 @@ protected:
|
|||
};
|
||||
|
||||
// Used internally for optimization, when a placeholder is needed.
|
||||
class NopExpr : public Expr {
|
||||
class NopExpr : public Expr
|
||||
{
|
||||
public:
|
||||
explicit NopExpr() : Expr(EXPR_NOP) { }
|
||||
|
||||
|
@ -1685,12 +1740,9 @@ protected:
|
|||
void ExprDescribe(ODesc* d) const override;
|
||||
};
|
||||
|
||||
|
||||
// Assigns v1[v2] = v3. Returns an error message, or nullptr on success.
|
||||
// Factored out so that compiled code can call it as well as the interpreter.
|
||||
extern const char* assign_to_index(ValPtr v1, ValPtr v2, ValPtr v3,
|
||||
bool& iterators_invalidated);
|
||||
|
||||
extern const char* assign_to_index(ValPtr v1, ValPtr v2, ValPtr v3, bool& iterators_invalidated);
|
||||
|
||||
inline Val* Expr::ExprVal() const
|
||||
{
|
||||
|
@ -1700,9 +1752,7 @@ inline Val* Expr::ExprVal() const
|
|||
}
|
||||
|
||||
// Decides whether to return an AssignExpr or a RecordAssignExpr.
|
||||
ExprPtr get_assign_expr(
|
||||
ExprPtr op1,
|
||||
ExprPtr op2, bool is_init);
|
||||
ExprPtr get_assign_expr(ExprPtr op1, ExprPtr op2, bool is_init);
|
||||
|
||||
/**
|
||||
* Type-check the given expression(s) against the given type(s). Complain
|
||||
|
@ -1731,8 +1781,14 @@ std::optional<std::vector<ValPtr>> eval_list(Frame* f, const ListExpr* l);
|
|||
extern bool expr_greater(const Expr* e1, const Expr* e2);
|
||||
|
||||
// True if the given Expr* has a vector type
|
||||
inline bool is_vector(Expr* e) { return e->GetType()->Tag() == TYPE_VECTOR; }
|
||||
inline bool is_vector(const ExprPtr& e) { return is_vector(e.get()); }
|
||||
inline bool is_vector(Expr* e)
|
||||
{
|
||||
return e->GetType()->Tag() == TYPE_VECTOR;
|
||||
}
|
||||
inline bool is_vector(const ExprPtr& e)
|
||||
{
|
||||
return is_vector(e.get());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace zeek
|
||||
|
|
17
src/File.cc
17
src/File.cc
|
@ -1,9 +1,10 @@
|
|||
// 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>
|
||||
|
@ -14,24 +15,24 @@
|
|||
#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;
|
||||
|
||||
|
|
14
src/File.h
14
src/File.h
|
@ -3,7 +3,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
@ -15,9 +14,11 @@
|
|||
#include "zeek/Val.h"
|
||||
#include "zeek/util.h"
|
||||
|
||||
namespace zeek {
|
||||
namespace zeek
|
||||
{
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class PrintStmt;
|
||||
class Attributes;
|
||||
|
@ -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);
|
||||
|
@ -51,8 +53,7 @@ public:
|
|||
|
||||
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
|
||||
|
@ -84,7 +85,6 @@ public:
|
|||
bool IsRawOutput() const { return raw_output; }
|
||||
|
||||
protected:
|
||||
|
||||
friend void detail::do_print_stmt(const std::vector<ValPtr>& vals);
|
||||
|
||||
File() { Init(); }
|
||||
|
|
12
src/Flare.cc
12
src/Flare.cc
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
23
src/Frag.cc
23
src/Frag.cc
|
@ -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;
|
||||
|
@ -73,8 +73,7 @@ FragReassembler::~FragReassembler()
|
|||
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();
|
||||
|
||||
|
@ -90,8 +89,7 @@ void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
|
|||
}
|
||||
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?
|
||||
}
|
||||
|
@ -310,8 +308,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
|
|||
|
||||
else
|
||||
{
|
||||
reporter->InternalWarning("bad IP version in fragment reassembly: %d",
|
||||
version);
|
||||
reporter->InternalWarning("bad IP version in fragment reassembly: %d", version);
|
||||
delete[] pkt_start;
|
||||
}
|
||||
}
|
||||
|
|
50
src/Frag.h
50
src/Frag.h
|
@ -5,28 +5,34 @@
|
|||
#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);
|
||||
|
@ -54,11 +60,10 @@ protected:
|
|||
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;
|
||||
|
@ -70,24 +75,23 @@ 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;
|
||||
[[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;
|
||||
|
@ -95,14 +99,12 @@ private:
|
|||
|
||||
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;
|
||||
|
|
38
src/Frame.cc
38
src/Frame.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.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 )
|
||||
|
|
61
src/Frame.h
61
src/Frame.h
|
@ -2,33 +2,35 @@
|
|||
|
||||
#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>;
|
||||
|
@ -38,7 +40,8 @@ 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.
|
||||
|
@ -148,14 +149,11 @@ public:
|
|||
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; }
|
||||
void BreakOnReturn(bool should_break) { break_on_return = should_break; }
|
||||
bool BreakOnReturn() const { return break_on_return; }
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -279,10 +277,10 @@ 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.
|
||||
|
@ -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;
|
||||
|
|
166
src/Func.cc
166
src/Func.cc
|
@ -1,11 +1,12 @@
|
|||
|
||||
// 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>
|
||||
|
@ -16,45 +17,43 @@
|
|||
#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.
|
||||
// clang-format off
|
||||
#include "zeek.bif.func_h"
|
||||
#include "stats.bif.func_h"
|
||||
#include "reporter.bif.func_h"
|
||||
|
@ -72,17 +71,20 @@
|
|||
#include "supervisor.bif.func_def"
|
||||
#include "packet_analysis.bif.func_def"
|
||||
#include "CPP-load.bif.func_def"
|
||||
// clang-format on
|
||||
|
||||
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 {
|
||||
namespace zeek
|
||||
{
|
||||
|
||||
std::string render_call_stack()
|
||||
{
|
||||
|
@ -145,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");
|
||||
}
|
||||
|
@ -238,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.
|
||||
|
@ -247,14 +248,16 @@ 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 ) {
|
||||
switch ( flavor )
|
||||
{
|
||||
case FUNC_FLAVOR_EVENT:
|
||||
if ( hook_result )
|
||||
reporter->InternalError("plugin returned non-void result for event %s",
|
||||
|
@ -264,8 +267,7 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
|
|||
|
||||
case FUNC_FLAVOR_HOOK:
|
||||
if ( hook_result->GetType()->Tag() != TYPE_BOOL )
|
||||
reporter->InternalError("plugin returned non-bool for hook %s",
|
||||
this->Name());
|
||||
reporter->InternalError("plugin returned non-bool for hook %s", this->Name());
|
||||
|
||||
break;
|
||||
|
||||
|
@ -276,13 +278,15 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
|
|||
if ( (! yt) || yt->Tag() == TYPE_VOID )
|
||||
{
|
||||
if ( hook_result )
|
||||
reporter->InternalError("plugin returned non-void result for void method %s",
|
||||
this->Name());
|
||||
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 )
|
||||
else if ( hook_result && hook_result->GetType()->Tag() != yt->Tag() &&
|
||||
yt->Tag() != TYPE_ANY )
|
||||
{
|
||||
reporter->InternalError("plugin returned wrong type (got %d, expecting %d) for %s",
|
||||
reporter->InternalError(
|
||||
"plugin returned wrong type (got %d, expecting %d) for %s",
|
||||
hook_result->GetType()->Tag(), yt->Tag(), this->Name());
|
||||
}
|
||||
|
||||
|
@ -291,10 +295,10 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result,
|
|||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
ScriptFunc::ScriptFunc(const IDPtr& arg_id, StmtPtr arg_body,
|
||||
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)
|
||||
{
|
||||
|
@ -312,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();
|
||||
|
@ -351,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
|
||||
|
@ -364,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());
|
||||
|
||||
|
@ -401,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;
|
||||
|
@ -482,8 +488,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
|
|||
(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());
|
||||
reporter->Warning("non-void function returning without a value: %s", Name());
|
||||
|
||||
if ( result && g_trace_state.DoTrace() )
|
||||
{
|
||||
|
@ -548,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 )
|
||||
|
@ -630,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
|
||||
|
@ -677,7 +680,6 @@ ASSERT(result.first);
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
FuncPtr ScriptFunc::DoClone()
|
||||
{
|
||||
// ScriptFunc could hold a closure. In this case a clone of it must
|
||||
|
@ -722,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;
|
||||
|
@ -736,8 +736,7 @@ StmtPtr ScriptFunc::AddInits(
|
|||
return stmt_series;
|
||||
}
|
||||
|
||||
BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
|
||||
bool arg_is_pure)
|
||||
BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, bool arg_is_pure)
|
||||
: Func(BUILTIN_FUNC)
|
||||
{
|
||||
func = arg_func;
|
||||
|
@ -755,9 +754,7 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
|
|||
id->SetConst();
|
||||
}
|
||||
|
||||
BuiltinFunc::~BuiltinFunc()
|
||||
{
|
||||
}
|
||||
BuiltinFunc::~BuiltinFunc() { }
|
||||
|
||||
bool BuiltinFunc::IsPure() const
|
||||
{
|
||||
|
@ -774,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);
|
||||
|
||||
|
@ -858,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;
|
||||
}
|
||||
}
|
||||
|
@ -929,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);
|
||||
|
@ -957,7 +953,6 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
if ( call_stack.empty() )
|
||||
{
|
||||
// Shouldn't happen unless someone (mistakenly) calls builtin_error()
|
||||
|
@ -976,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("::");
|
||||
|
@ -1051,14 +1048,14 @@ 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;
|
||||
|
@ -1066,7 +1063,6 @@ void init_primary_bifs()
|
|||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
void emit_builtin_error(const char* msg)
|
||||
{
|
||||
zeek::detail::emit_builtin_error_common(msg, nullptr, false);
|
||||
|
|
108
src/Func.h
108
src/Func.h
|
@ -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;
|
||||
|
@ -51,12 +55,16 @@ class ScriptFunc;
|
|||
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);
|
||||
|
||||
|
@ -65,11 +73,14 @@ public:
|
|||
virtual bool IsPure() const = 0;
|
||||
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; }
|
||||
|
@ -81,15 +92,13 @@ 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>,
|
||||
std::enable_if_t<std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>, ValPtr>,
|
||||
ValPtr>
|
||||
Invoke(Args&&... args) const
|
||||
{
|
||||
|
@ -98,15 +107,13 @@ 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; }
|
||||
|
||||
const FuncTypePtr& GetType() const
|
||||
{ return type; }
|
||||
const FuncTypePtr& GetType() const { return type; }
|
||||
|
||||
Kind GetKind() const { return kind; }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -143,17 +151,18 @@ protected:
|
|||
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;
|
||||
|
||||
|
@ -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,8 +252,7 @@ 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; }
|
||||
|
@ -266,17 +272,14 @@ public:
|
|||
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) { }
|
||||
|
||||
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.
|
||||
|
@ -327,7 +330,8 @@ private:
|
|||
|
||||
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;
|
||||
|
@ -339,7 +343,11 @@ public:
|
|||
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;
|
||||
|
@ -347,7 +355,8 @@ protected:
|
|||
|
||||
extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
|
||||
|
||||
struct CallInfo {
|
||||
struct CallInfo
|
||||
{
|
||||
const CallExpr* call;
|
||||
const Func* func;
|
||||
const zeek::Args& args;
|
||||
|
@ -355,7 +364,8 @@ struct CallInfo {
|
|||
|
||||
// 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.
|
||||
|
|
64
src/Hash.cc
64
src/Hash.cc
|
@ -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,7 +58,8 @@ 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)
|
||||
|
@ -57,29 +69,34 @@ hash64_t KeyedHash::Hash64(const void* bytes, uint64_t 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()
|
||||
|
@ -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;
|
||||
|
|
52
src/Hash.h
52
src/Hash.h
|
@ -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 {
|
||||
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);
|
||||
|
@ -261,10 +274,15 @@ public:
|
|||
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;
|
||||
|
||||
|
|
60
src/ID.cc
60
src/ID.cc
|
@ -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,8 +67,7 @@ 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",
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,8 +184,7 @@ void ID::SetVal(ValPtr v, InitClass c)
|
|||
return;
|
||||
}
|
||||
|
||||
if ( type->Tag() != TYPE_TABLE &&
|
||||
(type->Tag() != TYPE_PATTERN || 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 )
|
||||
|
@ -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,7 +445,8 @@ void ID::DescribeReSTShort(ODesc* d) const
|
|||
{
|
||||
TypeTag t = type->Tag();
|
||||
|
||||
switch ( t ) {
|
||||
switch ( t )
|
||||
{
|
||||
case TYPE_TABLE:
|
||||
d->Add(type->IsSet() ? "set" : type_name(t));
|
||||
break;
|
||||
|
@ -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,9 +565,7 @@ 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.
|
||||
|
@ -579,12 +574,12 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
|
|||
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() ) {
|
||||
switch ( type->Tag() )
|
||||
{
|
||||
case TYPE_TABLE:
|
||||
if ( iv->AsTable()->Length() == 0 )
|
||||
{
|
||||
|
@ -675,7 +670,6 @@ std::vector<Func*> ID::GetOptionHandlers() const
|
|||
return v;
|
||||
}
|
||||
|
||||
|
||||
void IDOptInfo::AddInitExpr(ExprPtr init_expr)
|
||||
{
|
||||
init_exprs.emplace_back(std::move(init_expr));
|
||||
|
|
79
src/ID.h
79
src/ID.h
|
@ -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;
|
||||
|
@ -31,21 +32,34 @@ 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;
|
||||
|
||||
|
@ -65,15 +79,11 @@ public:
|
|||
|
||||
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; }
|
||||
|
||||
|
@ -84,8 +94,7 @@ public:
|
|||
|
||||
bool HasVal() const { return val != nullptr; }
|
||||
|
||||
const ValPtr& GetVal() const
|
||||
{ return val; }
|
||||
const ValPtr& GetVal() const { return val; }
|
||||
|
||||
void ClearVal();
|
||||
|
||||
|
@ -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,15 +136,12 @@ 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;
|
||||
|
@ -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::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,7 +265,8 @@ extern TableTypePtr count_set;
|
|||
extern VectorTypePtr string_vec;
|
||||
extern VectorTypePtr index_vec;
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
void init_types();
|
||||
|
||||
|
|
82
src/IP.cc
82
src/IP.cc
|
@ -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)
|
||||
{
|
||||
|
@ -54,7 +55,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
{
|
||||
RecordValPtr rv;
|
||||
|
||||
switch ( type ) {
|
||||
switch ( type )
|
||||
{
|
||||
case IPPROTO_IPV6:
|
||||
{
|
||||
static auto ip6_hdr_type = id::find_type<RecordType>("ip6_hdr");
|
||||
|
@ -68,8 +70,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
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"));
|
||||
chain =
|
||||
make_intrusive<VectorVal>(id::find_type<VectorType>("ip6_ext_hdr_chain"));
|
||||
rv->Assign(7, std::move(chain));
|
||||
}
|
||||
break;
|
||||
|
@ -83,7 +85,6 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
rv->Assign(1, hbh->ip6h_len);
|
||||
uint16_t off = 2 * sizeof(uint8_t);
|
||||
rv->Assign(2, BuildOptionsVal(data + off, Length() - off));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -184,7 +185,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
static auto ip6_mob_back_type = id::find_type<RecordType>("ip6_mobility_back");
|
||||
static auto ip6_mob_be_type = id::find_type<RecordType>("ip6_mobility_be");
|
||||
|
||||
switch ( mob->ip6mob_type ) {
|
||||
switch ( mob->ip6mob_type )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
auto m = make_intrusive<RecordVal>(ip6_mob_brr_type);
|
||||
|
@ -222,7 +224,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
auto m = make_intrusive<RecordVal>(ip6_mob_hot_type);
|
||||
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)))));
|
||||
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));
|
||||
|
@ -234,7 +237,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
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)))));
|
||||
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));
|
||||
|
@ -245,10 +249,18 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
{
|
||||
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(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));
|
||||
|
@ -260,7 +272,8 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
{
|
||||
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(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);
|
||||
|
@ -298,7 +311,9 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const
|
|||
}
|
||||
|
||||
RecordValPtr IPv6_Hdr::ToVal() const
|
||||
{ return ToVal(nullptr); }
|
||||
{
|
||||
return ToVal(nullptr);
|
||||
}
|
||||
|
||||
IPAddr IP_Hdr::IPHeaderSrcAddr() const
|
||||
{
|
||||
|
@ -366,7 +381,8 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
|
|||
const u_char* data = Payload();
|
||||
|
||||
int proto = NextProto();
|
||||
switch ( proto ) {
|
||||
switch ( proto )
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
{
|
||||
const struct tcphdr* tp = (const struct tcphdr*)data;
|
||||
|
@ -436,7 +452,8 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const
|
|||
|
||||
static inline bool isIPv6ExtHeader(uint8_t type)
|
||||
{
|
||||
switch (type) {
|
||||
switch ( type )
|
||||
{
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_ROUTING:
|
||||
case IPPROTO_DSTOPTS:
|
||||
|
@ -452,13 +469,13 @@ static inline bool isIPv6ExtHeader(uint8_t type)
|
|||
|
||||
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;
|
||||
|
@ -511,10 +528,8 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_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
|
||||
|
@ -567,7 +582,8 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16_t le
|
|||
// Last 16 bytes of header (for all known types) is the address we want.
|
||||
const in6_addr* addr = (const in6_addr*)(((const u_char*)r) + len - 16);
|
||||
|
||||
switch ( r->ip6r_type ) {
|
||||
switch ( r->ip6r_type )
|
||||
{
|
||||
case 0: // Defined by RFC 2460, deprecated by RFC 5095
|
||||
{
|
||||
if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 )
|
||||
|
@ -617,7 +633,8 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
|
|||
while ( len > 0 )
|
||||
{
|
||||
const struct ip6_opt* opt = (const struct ip6_opt*)data;
|
||||
switch ( opt->ip6o_type ) {
|
||||
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.
|
||||
|
@ -637,14 +654,16 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
|
|||
break;
|
||||
}
|
||||
|
||||
if ( opt->ip6o_type == 201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
|
||||
if ( opt->ip6o_type ==
|
||||
201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
|
||||
{
|
||||
if ( opt->ip6o_len == sizeof(struct in6_addr) )
|
||||
{
|
||||
if ( homeAddr )
|
||||
reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts");
|
||||
else
|
||||
homeAddr = new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt))));
|
||||
homeAddr =
|
||||
new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt))));
|
||||
}
|
||||
else
|
||||
reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len");
|
||||
|
@ -677,7 +696,8 @@ VectorValPtr IPv6_Hdr_Chain::ToVal() const
|
|||
uint8_t type = chain[i]->Type();
|
||||
ext_hdr->Assign(0, type);
|
||||
|
||||
switch (type) {
|
||||
switch ( type )
|
||||
{
|
||||
case IPPROTO_HOPOPTS:
|
||||
ext_hdr->Assign(1, std::move(v));
|
||||
break;
|
||||
|
|
99
src/IP.h
99
src/IP.h
|
@ -2,12 +2,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#include <sys/types.h> // for u_char
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IP6_H
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
|
@ -16,7 +16,8 @@
|
|||
|
||||
#include "zeek/IntrusivePtr.h"
|
||||
|
||||
namespace zeek {
|
||||
namespace zeek
|
||||
{
|
||||
|
||||
class IPAddr;
|
||||
class RecordVal;
|
||||
|
@ -24,13 +25,17 @@ 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;
|
||||
|
@ -41,7 +46,8 @@ struct ip6_mobility {
|
|||
/**
|
||||
* Base class for IPv6 header/extensions.
|
||||
*/
|
||||
class IPv6_Hdr {
|
||||
class IPv6_Hdr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct an IPv6 header or extension header from assigned type number.
|
||||
|
@ -53,7 +59,8 @@ public:
|
|||
*/
|
||||
void ChangeNext(uint8_t next_type)
|
||||
{
|
||||
switch ( type ) {
|
||||
switch ( type )
|
||||
{
|
||||
case IPPROTO_IPV6:
|
||||
((ip6_hdr*)data)->ip6_nxt = next_type;
|
||||
break;
|
||||
|
@ -79,7 +86,8 @@ public:
|
|||
*/
|
||||
uint8_t NextHdr() const
|
||||
{
|
||||
switch ( type ) {
|
||||
switch ( type )
|
||||
{
|
||||
case IPPROTO_IPV6:
|
||||
return ((ip6_hdr*)data)->ip6_nxt;
|
||||
case IPPROTO_HOPOPTS:
|
||||
|
@ -100,7 +108,8 @@ public:
|
|||
*/
|
||||
uint16_t Length() const
|
||||
{
|
||||
switch ( type ) {
|
||||
switch ( type )
|
||||
{
|
||||
case IPPROTO_IPV6:
|
||||
return 40;
|
||||
case IPPROTO_HOPOPTS:
|
||||
|
@ -140,13 +149,13 @@ protected:
|
|||
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
|
||||
|
@ -281,7 +290,8 @@ protected:
|
|||
* 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
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
// 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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -96,8 +96,7 @@ void IPAddr::Mask(int top_bits_to_keep)
|
|||
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;
|
||||
|
@ -206,8 +205,7 @@ std::string IPAddr::AsHexString() const
|
|||
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]),
|
||||
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]));
|
||||
}
|
||||
|
||||
|
@ -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) )
|
||||
{
|
||||
|
@ -323,7 +318,8 @@ std::string IPPrefix::AsString() const
|
|||
|
||||
std::unique_ptr<detail::HashKey> IPPrefix::MakeHashKey() const
|
||||
{
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
in6_addr ip;
|
||||
uint32_t len;
|
||||
} key;
|
||||
|
|
124
src/IPAddr.h
124
src/IPAddr.h
|
@ -2,34 +2,37 @@
|
|||
|
||||
#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; }
|
||||
|
||||
|
@ -50,7 +53,8 @@ using ConnIDKey [[deprecated("Remove in v5.1. Use zeek::detail::ConnKey.")]] = C
|
|||
/**
|
||||
* 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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,9 +444,7 @@ 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)
|
||||
|
@ -490,21 +482,20 @@ 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);
|
||||
|
@ -526,7 +517,6 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
|
|||
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
|
||||
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,30 +152,15 @@ 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;
|
||||
|
@ -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,32 +196,32 @@ IntrusivePtr<T> cast_intrusive(IntrusivePtr<U> p) noexcept
|
|||
/**
|
||||
* @relates IntrusivePtr
|
||||
*/
|
||||
template <class T>
|
||||
bool operator==(const zeek::IntrusivePtr<T>& x, std::nullptr_t) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
template <class T> bool operator!=(std::nullptr_t, const zeek::IntrusivePtr<T>& x)
|
||||
{
|
||||
return static_cast<bool>(x);
|
||||
}
|
||||
|
||||
|
@ -255,32 +230,32 @@ bool operator!=(std::nullptr_t, const zeek::IntrusivePtr<T>& x) {
|
|||
/**
|
||||
* @relates IntrusivePtr
|
||||
*/
|
||||
template <class T>
|
||||
bool operator==(const zeek::IntrusivePtr<T>& x, const T* 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) {
|
||||
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) {
|
||||
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) {
|
||||
template <class T> bool operator!=(const T* x, const zeek::IntrusivePtr<T>& y)
|
||||
{
|
||||
return x != y.get();
|
||||
}
|
||||
|
||||
|
@ -313,10 +288,14 @@ auto operator!=(const zeek::IntrusivePtr<T>& x, const zeek::IntrusivePtr<U>& y)
|
|||
|
||||
// -- 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());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "zeek/List.h"
|
||||
|
||||
#include "zeek/3rdparty/doctest.h"
|
||||
|
||||
TEST_CASE("list construction")
|
||||
|
|
36
src/List.h
36
src/List.h
|
@ -20,20 +20,25 @@
|
|||
// 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;
|
||||
|
||||
|
@ -124,10 +129,7 @@ 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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,10 +332,8 @@ 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>;
|
||||
|
|
11
src/NFA.cc
11
src/NFA.cc
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
|
33
src/NFA.h
33
src/NFA.h
|
@ -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,7 +30,8 @@ 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);
|
||||
|
@ -62,8 +65,9 @@ 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
|
||||
|
@ -80,12 +84,14 @@ protected:
|
|||
NFA_State* mark;
|
||||
};
|
||||
|
||||
class EpsilonState : public NFA_State {
|
||||
class EpsilonState : public NFA_State
|
||||
{
|
||||
public:
|
||||
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;
|
||||
|
@ -97,7 +103,11 @@ public:
|
|||
|
||||
void AddAccept(int accept_val);
|
||||
|
||||
void MakeClosure() { MakePositiveClosure(); MakeOptional(); }
|
||||
void MakeClosure()
|
||||
{
|
||||
MakePositiveClosure();
|
||||
MakeOptional();
|
||||
}
|
||||
void MakeOptional();
|
||||
void MakePositiveClosure();
|
||||
|
||||
|
@ -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"
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -104,8 +105,8 @@ extern void init_builtin_types();
|
|||
} // 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"
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
@ -35,7 +37,8 @@ public:
|
|||
};
|
||||
|
||||
/** Singleton class tracking all notification requests globally. */
|
||||
class Registry {
|
||||
class Registry
|
||||
{
|
||||
public:
|
||||
~Registry();
|
||||
|
||||
|
@ -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
|
||||
|
|
26
src/Obj.cc
26
src/Obj.cc
|
@ -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,8 +46,7 @@ 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;
|
||||
|
@ -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();
|
||||
|
||||
|
|
57
src/Obj.h
57
src/Obj.h
|
@ -2,31 +2,33 @@
|
|||
|
||||
#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;
|
||||
|
@ -58,7 +60,8 @@ inline void set_location(const Location start, const Location end)
|
|||
|
||||
} // namespace detail
|
||||
|
||||
class Obj {
|
||||
class Obj
|
||||
{
|
||||
public:
|
||||
Obj()
|
||||
{
|
||||
|
@ -89,14 +92,13 @@ public:
|
|||
// 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;
|
||||
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 ) \
|
||||
|
@ -112,10 +114,11 @@ public:
|
|||
|
||||
// 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);
|
||||
|
@ -131,7 +134,8 @@ public:
|
|||
|
||||
// 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; }
|
||||
|
@ -145,10 +149,9 @@ protected:
|
|||
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);
|
||||
|
|
157
src/OpaqueVal.cc
157
src/OpaqueVal.cc
|
@ -2,21 +2,21 @@
|
|||
|
||||
#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.
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -291,16 +286,14 @@ broker::expected<broker::data> MD5Val::DoSerialize() const
|
|||
|
||||
MD5_CTX* md = (MD5_CTX*)EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
broker::vector d = {
|
||||
true,
|
||||
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)
|
||||
};
|
||||
static_cast<uint64_t>(md->num)};
|
||||
|
||||
for ( int i = 0; i < MD5_LBLOCK; ++i )
|
||||
d.emplace_back(static_cast<uint64_t>(md->data[i]));
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -411,8 +402,7 @@ broker::expected<broker::data> SHA1Val::DoSerialize() const
|
|||
|
||||
SHA_CTX* md = (SHA_CTX*)EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
broker::vector d = {
|
||||
true,
|
||||
broker::vector d = {true,
|
||||
static_cast<uint64_t>(md->h0),
|
||||
static_cast<uint64_t>(md->h1),
|
||||
static_cast<uint64_t>(md->h2),
|
||||
|
@ -420,8 +410,7 @@ broker::expected<broker::data> SHA1Val::DoSerialize() const
|
|||
static_cast<uint64_t>(md->h4),
|
||||
static_cast<uint64_t>(md->Nl),
|
||||
static_cast<uint64_t>(md->Nh),
|
||||
static_cast<uint64_t>(md->num)
|
||||
};
|
||||
static_cast<uint64_t>(md->num)};
|
||||
|
||||
for ( int i = 0; i < SHA_LBLOCK; ++i )
|
||||
d.emplace_back(static_cast<uint64_t>(md->data[i]));
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -534,13 +521,8 @@ broker::expected<broker::data> SHA256Val::DoSerialize() const
|
|||
|
||||
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]));
|
||||
|
@ -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,22 +595,14 @@ 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);
|
||||
|
@ -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,8 +916,7 @@ 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);
|
||||
}
|
||||
|
@ -1017,9 +984,10 @@ 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 )
|
||||
{
|
||||
|
@ -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,51 +1011,37 @@ 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::DblCounter) :OpaqueVal(dbl_counter_metric_type)
|
||||
{
|
||||
}
|
||||
TelemetryVal::TelemetryVal(telemetry::DblCounter) : OpaqueVal(dbl_counter_metric_type) { }
|
||||
|
||||
TelemetryVal::TelemetryVal(telemetry::DblCounterFamily) : OpaqueVal(dbl_counter_metric_family_type)
|
||||
{
|
||||
}
|
||||
|
||||
TelemetryVal::TelemetryVal(telemetry::IntGauge) :OpaqueVal(int_gauge_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::IntGaugeFamily) :OpaqueVal(int_gauge_metric_family_type)
|
||||
{
|
||||
}
|
||||
TelemetryVal::TelemetryVal(telemetry::DblHistogram) : OpaqueVal(dbl_histogram_metric_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)
|
||||
TelemetryVal::TelemetryVal(telemetry::DblHistogramFamily)
|
||||
: OpaqueVal(dbl_histogram_metric_family_type)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
116
src/OpaqueVal.h
116
src/OpaqueVal.h
|
@ -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>;
|
||||
|
@ -31,7 +41,8 @@ using BloomFilterValPtr = IntrusivePtr<BloomFilterVal>;
|
|||
* Singleton that registers all available all available types of opaque
|
||||
* values. This faciliates their serialization into Broker values.
|
||||
*/
|
||||
class OpaqueMgr {
|
||||
class OpaqueMgr
|
||||
{
|
||||
public:
|
||||
using Factory = OpaqueValPtr();
|
||||
|
||||
|
@ -66,11 +77,10 @@ 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:
|
||||
|
@ -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;
|
||||
|
@ -166,7 +177,8 @@ protected:
|
|||
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)
|
||||
|
@ -199,15 +211,16 @@ private:
|
|||
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);
|
||||
|
@ -235,11 +248,13 @@ 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();
|
||||
|
@ -258,11 +273,13 @@ 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();
|
||||
|
@ -281,13 +298,13 @@ 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;
|
||||
|
@ -297,15 +314,15 @@ 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;
|
||||
|
@ -333,8 +349,8 @@ private:
|
|||
probabilistic::BloomFilter* bloom_filter;
|
||||
};
|
||||
|
||||
|
||||
class CardinalityVal : public OpaqueVal {
|
||||
class CardinalityVal : public OpaqueVal
|
||||
{
|
||||
public:
|
||||
explicit CardinalityVal(probabilistic::detail::CardinalityCounter*);
|
||||
~CardinalityVal() override;
|
||||
|
@ -343,8 +359,7 @@ public:
|
|||
|
||||
void Add(const Val* val);
|
||||
|
||||
const TypePtr& Type() const
|
||||
{ return type; }
|
||||
const TypePtr& Type() const { return type; }
|
||||
|
||||
bool Typify(TypePtr type);
|
||||
|
||||
|
@ -360,7 +375,8 @@ private:
|
|||
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);
|
||||
|
@ -379,7 +395,8 @@ private:
|
|||
/**
|
||||
* 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);
|
||||
|
@ -398,28 +415,19 @@ protected:
|
|||
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;
|
||||
|
|
105
src/Options.cc
105
src/Options.cc
|
@ -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);
|
||||
}
|
||||
|
@ -286,7 +317,8 @@ Options parse_cmdline(int argc, char** argv)
|
|||
{
|
||||
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;
|
||||
|
@ -385,8 +417,10 @@ 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 ) {
|
||||
while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) !=
|
||||
EOF )
|
||||
switch ( op )
|
||||
{
|
||||
case 'a':
|
||||
rval.parse_only = true;
|
||||
break;
|
||||
|
@ -605,8 +639,7 @@ 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "zeek/PacketFilter.h"
|
||||
|
||||
#include "zeek/IP.h"
|
||||
|
||||
namespace zeek::detail {
|
||||
namespace zeek::detail
|
||||
{
|
||||
|
||||
void PacketFilter::DeleteFilter(void* data)
|
||||
{
|
||||
|
@ -93,8 +95,7 @@ bool PacketFilter::Match(const std::unique_ptr<IP_Hdr>& ip, int len, int 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 )
|
||||
{
|
||||
|
|
|
@ -7,14 +7,17 @@
|
|||
#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() { }
|
||||
|
@ -38,7 +41,8 @@ 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;
|
||||
};
|
||||
|
|
10
src/Pipe.cc
10
src/Pipe.cc
|
@ -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 )
|
||||
{
|
||||
|
|
43
src/Pipe.h
43
src/Pipe.h
|
@ -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,8 +18,8 @@ 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.
|
||||
|
@ -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
|
||||
|
@ -69,9 +68,9 @@ private:
|
|||
/**
|
||||
* 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,51 +86,43 @@ 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;
|
||||
};
|
||||
|
|
|
@ -1,25 +1,33 @@
|
|||
#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;
|
||||
|
@ -29,7 +37,8 @@ struct PolicyFile {
|
|||
typedef map<string, PolicyFile*> PolicyFileMap;
|
||||
static PolicyFileMap policy_files;
|
||||
|
||||
namespace zeek::detail {
|
||||
namespace zeek::detail
|
||||
{
|
||||
|
||||
int how_many_lines_in(const char* policy_filename)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -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,18 +49,17 @@ 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() ) {
|
||||
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);
|
||||
return Insert(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6(), data);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -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,18 +107,17 @@ 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() ) {
|
||||
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);
|
||||
return Lookup(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6(), exact);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -145,18 +145,17 @@ 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() ) {
|
||||
switch ( value->GetType()->Tag() )
|
||||
{
|
||||
case TYPE_ADDR:
|
||||
return Remove(value->AsAddr(), 128);
|
||||
break;
|
||||
|
||||
case TYPE_SUBNET:
|
||||
return Remove(value->AsSubNet().Prefix(),
|
||||
value->AsSubNet().LengthIPv6());
|
||||
return Remove(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue