Merge remote-tracking branch 'origin/master' into topic/johanna/table-changes

* origin/master: (172 commits)
  GH-985: Fix descriptions of double_to_interval() return values
  Decrease number of CPUs/memory for Cirrus CI tasks
  Change CI script to compile from build/Makefile
  Add missing include in util.cc
  Remove Analyzer.h from bro-bif.h
  Remove IPAddr.h from Reporter.h
  Remove the inclusion of Func.h from NetVar.h, which reduces the inclusion of Func.h overall.
  Update submodule(s)
  Update submodule(s)
  Integrate review feedback
  Update submodule(s)
  Fix crash on using some deprecated environment variables
  Update NEWS
  Update test baselines for new Broker connection status/error strings
  Switch Broker Val converter visitor to return IntrusivePtr
  Change BroFunc ctor to take const-ref IntrusivePtr<ID>
  Add version of Frame::SetElement() taking IntrusivePtr<ID>
  Change Scope/Func inits from id_list* to vector<IntrusivePtr<ID>>
  Change Scope::GenerateTemporary() to return IntrusivePtr
  Deprecate Scope::ReturnType(), replace with GetReturnType()
  ...
This commit is contained in:
Johanna Amann 2020-06-03 16:09:42 -07:00
commit d9de6c4522
359 changed files with 10146 additions and 6696 deletions

View file

@ -1,7 +1,7 @@
cpus: &CPUS 8
btest_jobs: &BTEST_JOBS 8
cpus: &CPUS 4
btest_jobs: &BTEST_JOBS 4
btest_retries: &BTEST_RETRIES 2
memory: &MEMORY 6GB
memory: &MEMORY 4GB
config: &CONFIG --build-type=release --enable-cpp-tests --disable-broker-tests
memcheck_config: &MEMCHECK_CONFIG --build-type=debug --enable-cpp-tests --disable-broker-tests --sanitizers=address --enable-fuzzers
@ -129,9 +129,9 @@ memcheck_task:
container:
# Just uses a recent/common distro to run memory error/leak checks.
dockerfile: ci/ubuntu-18.04/Dockerfile
cpu: 8
cpu: 4
# AddressSanitizer uses a lot more memory than a typical config.
memory: 16GB
memory: 12GB
<< : *CI_TEMPLATE
test_fuzzers_script: ./ci/test-fuzzers.sh
env:

518
CHANGES
View file

@ -1,4 +1,522 @@
3.2.0-dev.738 | 2020-06-02 18:13:50 -0700
* GH-985: Fix descriptions of double_to_interval() return values (Jon Siwek, Corelight)
The BIF was not returning an IntervalVal which has an overriden
ValDescribe() method that allows for prettier printing like "6.0 secs"
instead of just "6.0".
3.2.0-dev.736 | 2020-06-02 12:37:56 -0700
* Decrease number of CPUs/memory for Cirrus CI tasks (Jon Siwek, Corelight)
3.2.0-dev.735 | 2020-06-02 10:55:43 -0700
* Change CI script to compile from build/Makefile (Jon Siwek, Corelight)
3.2.0-dev.734 | 2020-06-01 20:44:29 -0700
* Add missing include in util.cc (Jon Siwek, Corelight)
3.2.0-dev.733 | 2020-06-01 19:25:37 -0700
* Remove Analyzer.h from bro-bif.h (Tim Wojtulewicz, Corelight)
* Remove IPAddr.h from Reporter.h (Tim Wojtulewicz, Corelight)
* Remove the inclusion of Func.h from NetVar.h (Tim Wojtulewicz, Corelight)
3.2.0-dev.727 | 2020-06-01 10:57:16 -0700
* Integrate review feedback
* Add deprecation for MIME_Entity::ContentType(), use GetContentType()
* Add deprecation for MIME_Entity::ContentSubType(), use GetContentSubType()
* Add deprecation for MIME_Message::BuildHeaderVal(), use ToHeaderVal()
* Add deprecation for MIME_Message::BuildHeaderTable(), use ToHeaderTable()
* Add deprecation for mime::new_string_val(), use mime::to_stringval()
* Add deprecation for ARP_Analyzer::ConstructAddrVal(), use ToAddrVal()
* Add deprecation for ARP_Analyzer::EthAddrToStr(), use ToEthAddrStr()
* Change the Func::Call() replacement to be named Func::Invoke() (Jon Siwek, Corelight)
* Switch Broker Val converter visitor to return IntrusivePtr (Jon Siwek, Corelight)
* Change BroFunc ctor to take const-ref IntrusivePtr<ID> (Jon Siwek, Corelight)
* Add version of Frame::SetElement() taking IntrusivePtr<ID>
Expect the version using raw ID* could go away eventually, but this is
convenience for the meantime. (Jon Siwek, Corelight)
* Change Scope/Func inits from id_list* to vector<IntrusivePtr<ID>> (Jon Siwek, Corelight)
* Change Scope::GenerateTemporary() to return IntrusivePtr (Jon Siwek, Corelight)
* Deprecate Scope::ReturnType(), replace with GetReturnType() (Jon Siwek, Corelight)
* Deprecate Scope::ScopeID(), replace with GetID() (Jon Siwek, Corelight)
* Switch parsing to use vector<IntrusivePtr<Attr>> from attr_list
This allows improved passing/storing of Attr references to Exprs,
TypeDecl, Scope, etc. (Jon Siwek, Corelight)
* Deprecate TableVal::FindAttr(), replace with GetAttr() (Jon Siwek, Corelight)
* Deprecate TypeDecl::FindAttr(), replace with GetAttr() (Jon Siwek, Corelight)
* Deprecate ID::FindAttr(), replace with GetAttr() (Jon Siwek, Corelight)
* Deprecate Attributes::FindAttr(), replace with Find() (Jon Siwek, Corelight)
* Deprecate Attributes::AddAttrs(Attributes*)
Replaced with version taking an IntrusivePtr parameter (Jon Siwek, Corelight)
* Add Attributes ctor that takes IntrusivePtrs (Jon Siwek, Corelight)
* Change Attributes to store std:vector<IntrusivePtr<Attr>>
This also changes the return type of Attributes::Attrs() from attr_list* (Jon Siwek, Corelight)
* Change Attr::SetAttrExpr() to non-template (Jon Siwek, Corelight)
* Deprecate Attr::AttrExpr(), replace with GetExpr() (Jon Siwek, Corelight)
* Deprecate ID::Attrs(), replace with GetAttrs() (Jon Siwek, Corelight)
* Remove weak_ref param from ID::SetVal()
It was not used anywhere. (Jon Siwek, Corelight)
* Store weak ref boolean along with Frame element Vals (Jon Siwek, Corelight)
* Deprecate Frame::GetElement(ID*), replace with GetElementByID() (Jon Siwek, Corelight)
* Deprecate Frame::NthElement(), replace with GetElement() (Jon Siwek, Corelight)
* Switch Frame::SetElement() to use IntrusivePtr (Jon Siwek, Corelight)
* Store IntrusivePtrs in Frame (Jon Siwek, Corelight)
* Deprecate Plugin::HookCallFunction(), replace with HookFunctionCall()
This also changes the argument type of Func::operator() to zeek::Args*
to allow plugins to be able to alter function arguments in place as
was previously documented. (Jon Siwek, Corelight)
* Switch plugin::Manager::HookCallFunction() to return IntrusivePtr
The plugin::Plugin side of things is not (yet) changed. (Jon Siwek, Corelight)
* Port remaining file analysis API to use IntrusivePtr (Jon Siwek, Corelight)
* Deprecate file analyzer construction methods taking raw RecordVal*
Replaced with versions that instead take IntrusivePtr (Jon Siwek, Corelight)
* Deprecate file_analysis::Analyzer::Args(), replace with GetArgs() (Jon Siwek, Corelight)
* Deprecate file_analysis::File::GetVal(), replace with ToVal() (Jon Siwek, Corelight)
* Change file_analysis::File::GetID() to return const-ref (Jon Siwek, Corelight)
* Fix build: some don't like IntrusivePtr default arg w/ incomplete type (Jon Siwek, Corelight)
* Change bro_broker::DataVal::ScriptDataType() to IntrusivePtr (Jon Siwek, Corelight)
* Change find_nested_record_types() to take IntrusivePtr (Jon Siwek, Corelight)
* Deprecate TypeType::Type(), replace with GetType() (Jon Siwek, Corelight)
* Add is_assignable() overload taking TypeTag (Jon Siwek, Corelight)
* Add is_atomic_type() overloads for IntrusivePtr (Jon Siwek, Corelight)
* Add same_type() overloads for IntrusivePtr args (Jon Siwek, Corelight)
* Change merge_types() to take IntrusivePtrs (Jon Siwek, Corelight)
* Deprecate IndexType::Indices(), replace with GetIndices() (Jon Siwek, Corelight)
* Add is_vector() methods taking const-ref IntrusivePtr (Jon Siwek, Corelight)
* Factor static-local nil IntrusivePtrs to global locations
Minor optimization to remove any run-time impact. (Jon Siwek, Corelight)
* Deprecate VectorVal::Lookup(), replace with At() (Jon Siwek, Corelight)
* Switch VectorVal BroValUnion to store std::vector<IntrusivePtr<Val>>
This changes the return type of AsVector() from std::vector<Val*>* (Jon Siwek, Corelight)
* Deprecate VectorVal::Insert() taking raw Val*, use IntrusivePtr (Jon Siwek, Corelight)
* Deprecate VectorVal::Assign methods taking raw Val*
And adapt usages to pass in to alternate method taking IntrusivePtr (Jon Siwek, Corelight)
* Merge remote-tracking branch 'origin/master' into topic/jsiwek/gh-893-intrusive-ptr-migration (Jon Siwek, Corelight)
* Change EventHandler to store IntrusivePtr<Func>
Also deprecates the LocalHandler() and SetLocalHandler() methods,
replaced with GetFunc() and SetFunc(). (Jon Siwek, Corelight)
* Add Val::AsFuncPtr() convenience method
Since it's not trivial to store IntrusivePtr in BroValUnion and also
not satisfying to store IntrusivePtr*. (Jon Siwek, Corelight)
* Deprecate StringVal::Substitute(), replace with Replace() (Jon Siwek, Corelight)
* Switch a TableVal::CallChangeFunc param to IntrusivePtr (Jon Siwek, Corelight)
* Fix ambiguous ODesc::Add() call (Jon Siwek, Corelight)
* Minor TableVal::Assign() ref-counting optimization (Jon Siwek, Corelight)
* Improve TableVal HashKey management
* Deprecated ComputeHash() methods and replaced with MakeHashKey()
which returns std::unique_ptr<HashKey>
* Deprecated RecoverIndex() and replaced with RecreateIndex()
which takes HashKey& and returns IntrusivePtr.
* Updated the new TableVal Assign()/Remove() methods to take either
std::unique_ptr<HashKey> or HashKey& as appropriate for clarity of
ownership expectations. (Jon Siwek, Corelight)
* Add back in a deprecated TableVal ctor taking raw pointers (Jon Siwek, Corelight)
* Deprecate TableVal::Attrs(), replace with GetAttrs() (Jon Siwek, Corelight)
* Deprecate TableVal::Delete(), replace with Remove() (Jon Siwek, Corelight)
* Switch Func::Call(val_list*) back to returning Val*
And renamed the method returning IntrusivePtr to operator().
This corrects the deprecation process for Func::Call(val_list*). (Jon Siwek, Corelight)
* Deprecate TableVal::Lookup(), replace with Find()/FindOrDefault() (Jon Siwek, Corelight)
* Deprecate TableVal IsSubsetOf and EqualTo taking Val*, use Val& (Jon Siwek, Corelight)
* Deprecate ComputeHash(Val*) methods, replace with ComputeHash(Val&) (Jon Siwek, Corelight)
* Deprecate TableVal::Intersect(), replace with Intersection() (Jon Siwek, Corelight)
* Deprecate TableVal::Assign methods with Val*, add IntrusivePtr overloads (Jon Siwek, Corelight)
* Deprecate RecordVal::Lookup(const char*, bool)
Replace with GetField(const char*) and GetFieldOrDefault(const char*). (Jon Siwek, Corelight)
* Deprecate RecordVal::LookupWithDefault() replace with GetFieldOrDefault()
(The former was previously changed during this release cycle to return
Intrusive pointer, but this just changes it back to return Val* and
deprecates it). (Jon Siwek, Corelight)
* Deprecate RecordVal::Lookup(int), replace with GetField(int) (Jon Siwek, Corelight)
* Change BroValUnion to use IntrusivePtr for record field storage
This also changes the AsRecord() and AsNonConstRecord() accessors
to return std::vector<IntrusivePtr<Val>>* instead of val_list* (Jon Siwek, Corelight)
* Switch ASN1 Val conversion functions to return IntrusivePtr (Jon Siwek, Corelight)
* Deprecate RecordVal::Assign(int, Val*)
And adapt all usages to the existing overload taking IntrusivePtr. (Jon Siwek, Corelight)
* Switch RPC analyzers to use IntrusivePtr (Jon Siwek, Corelight)
* Switch RecordVal::CoerceTo() to use IntrusivePtr (Jon Siwek, Corelight)
* Deprecate TableEntryVal::Value(), replace with GetVal() (Jon Siwek, Corelight)
* Switch OpaqueVal::SerializeType() to IntrusivePtr (Jon Siwek, Corelight)
* Switch BlommFilterVal/CardinalityVal to use IntrusivePtr<BroType> (Jon Siwek, Corelight)
* Switch some TopkVal methods to use IntrusivePtr (Jon Siwek, Corelight)
* Switch TopkVal to store IntrusivePtr<BroType> (Jon Siwek, Corelight)
* Switch OpaqueVal::UnserializeType() to return IntrusivePtr (Jon Siwek, Corelight)
* Deprecate FuncType::ArgTypes(), replace with ParamList() (Jon Siwek, Corelight)
* Deprecate FuncType::Args(), replace with Params() (Jon Siwek, Corelight)
* Deprecate EventHandler::FType(), replace with GetType() (Jon Siwek, Corelight)
* Deprecate BroFile::FType(), replace with GetType() (Jon Siwek, Corelight)
* Deprecate Func::FType(), replace with Func::GetType() (Jon Siwek, Corelight)
* Change {Get,Set}ContentsFile() to use IntrusivePtr (Jon Siwek, Corelight)
* Deprecate BroFile::GetFile(), replace with BroFile::Get() (Jon Siwek, Corelight)
* Deprecate Val(BroFile*) ctor, replace with one using IntrusivePtr (Jon Siwek, Corelight)
* Deprecate Val(Func*) ctor, replace with one using IntrusivePtr (Jon Siwek, Corelight)
* Deprecate OpaqueVal/HashVal ctors that take OpaqueType*
Replaced with ones that take IntrusivePtr (Jon Siwek, Corelight)
* fixup! Deprecate Scope::Lookup(), replace with Scope::Find() (Jon Siwek, Corelight)
* Switch EnumType::GetVal() to return const-ref (Jon Siwek, Corelight)
* Change protected EnumVal ctor to use IntrusivePtr (Jon Siwek, Corelight)
* Deprecate RecordVal(RecordType*) ctor
Replaced with one that takes IntrusivePtr (Jon Siwek, Corelight)
* Switch zeek::id::lookup to zeek::id::find
For parity with Scope since it now uses Find instead of Lookup (Jon Siwek, Corelight)
* Use zeek::BifEvent:: for enqueue_ functions instead of BifEvent:: (Jon Siwek, Corelight)
* Replace deprecated usage of BifFunc:: with zeek::BifFunc::
Names of functions also changed slightly, like bro_fmt -> fmt_bif.
Should generally be unusual/unexpected to see somone calling these
directly from C++ in their plugin, but since technically possible in
previous versions, I also removed the "private" restriction on accessing
the BifReturnVal member. (Jon Siwek, Corelight)
* Deprecate names in BifConst, replace with zeek::BifConst
Some Val* types are also replaced with IntrusivePtr at the new location (Jon Siwek, Corelight)
* Deprecate all BroType* in BifType:: namespace
Replaced with equivalently named IntrusivePtr in zeek::BifType:: (Jon Siwek, Corelight)
* Change EventRegistry/EventHandler methods to use std::string{_view} (Jon Siwek, Corelight)
* Deprecate internal_handler(), replace with EventRegistry::Register()
Added a couple explicit event declarations that were missing: "net_done"
and "dns_mapping_name_changed". (Jon Siwek, Corelight)
* Deprecate remaining "opt_internal" functions in Var.h (Jon Siwek, Corelight)
* Remove signal_val declaration from Var.h (Jon Siwek, Corelight)
* Change zeek::id::lookup functions to use std::string_view (Jon Siwek, Corelight)
* Change Scope::Find() and Scope::Remove() to use std::string_view (Jon Siwek, Corelight)
* Change lookup_ID() to return a const-reference (Jon Siwek, Corelight)
* Deprecate Scope::Lookup(), replace with Scope::Find() (Jon Siwek, Corelight)
* Move various elements into ID.h and zeek::id namespace
* A handful of generic/useful/common global type pointers that used
to be in NetVar.h
* Lookup functions that used to be Var.h (Jon Siwek, Corelight)
* Trim the list of "global type pointers" from NetVar.h further
Most of them are deprecated now, with usage sites now doing the lookup
themselves. (Jon Siwek, Corelight)
* Deprecate global Val pointers in NetVar.h
All of these have fairly niche uses, so better maintained as
lookup/static closer to the usage site. (Jon Siwek, Corelight)
* Deprecate global type pointers in NetVar.h
There's analogous IntrusivePtrs in zeek::vars (Jon Siwek, Corelight)
* Add RecordVal ctor that takes IntrusivePtr (Jon Siwek, Corelight)
* Remove unused FlattenExpr (Jon Siwek, Corelight)
* Add missing "vector_coerce" to expr_name() (Jon Siwek, Corelight)
* Deprecate Expr::Type(), replace with GetType() (Jon Siwek, Corelight)
* Deprecate Val::Type(), replace with GetType() (Jon Siwek, Corelight)
* Change Val to store IntrusivePtr (Jon Siwek, Corelight)
* Remove VectorVal::vector_type member (Jon Siwek, Corelight)
* Deprecate VectorVal(VectorType*) ctora
Adds a new one taking an IntrusivePtr. (Jon Siwek, Corelight)
* Deprecate internal_list_val() (Jon Siwek, Corelight)
* Deprecate opt_internal_val() (Jon Siwek, Corelight)
* Deprecate internal_func(), replace with zeek::lookup_func() (Jon Siwek, Corelight)
* Deprecate internal_val() and internal_const_val()
Replaced with zeek::lookup_val() and zeek::lookup_const() (Jon Siwek, Corelight)
* Deprecate internal_type(), replace with zeek::lookup_type() (Jon Siwek, Corelight)
* Deprecate ID::ID_Val(), replace with ID::GetVal() (Jon Siwek, Corelight)
* Use std::move in some zeekygen::Manager methods (Jon Siwek, Corelight)
* Add Val TypeType constructor taking an IntrusivePtr (Jon Siwek, Corelight)
* Deprecate ID::Type(), replace with GetType() (Jon Siwek, Corelight)
* Deprecate ID::AsType(), add ID::IsType() and ID::GetType() (Jon Siwek, Corelight)
* Deprecate BroType::YieldType(), replace with Yield() (Jon Siwek, Corelight)
* Change base_type() to return const-ref, deprecate base_type_no_ref() (Jon Siwek, Corelight)
* Deprecate BroType::GetField() and BroType::HasField() (Jon Siwek, Corelight)
* Deprecate RecordType::FieldType(), replace with GetFieldType() (Jon Siwek, Corelight)
* Migrate TypeList to store IntrusivePtrs
This changes return types of TypeList::Types() and
IndexType::IndexTypes() to return std::vector instead of type_list* (Jon Siwek, Corelight)
* Deprecate TypeList::PureType(), replace with TypeList::GetPureType() (Jon Siwek, Corelight)
* Deprecate SetType::SetElements(), replace with SetType::Elements() (Jon Siwek, Corelight)
* Remove unused TableType::ExpandRecordIndex() (Jon Siwek, Corelight)
* Add cast_intrusive() and make use of it in two spots (Jon Siwek, Corelight)
* Give make_intrusive() access to protected EnumVal ctor (Jon Siwek, Corelight)
* Remove two superfluous IntrusivePtr NewRefs in Type.cc (Jon Siwek, Corelight)
* Change BroType::ShallowClone() to return IntrusivePtr (Jon Siwek, Corelight)
* Migrate IP.cc to use IntrusivePtr (Jon Siwek, Corelight)
* Migrate SMB analyzer to use IntrusivePtr
Deprecates the utf16_bytestring_to_utf8_val() function with replacement
being utf16_to_utf8_val(). (Jon Siwek, Corelight)
* Migrate ARP analyzer to use IntrusivePtr (Jon Siwek, Corelight)
* Migrate HTTP/MIME analyzers to use IntrusivePtr (Jon Siwek, Corelight)
* Migrate ICMP analyzer to use IntrusivePtr (Jon Siwek, Corelight)
* Migrate DNS analyzer to use IntrusivePtr (Jon Siwek, Corelight)
* Migrate Tag classes to use IntrusivePtr
Deprecates various methods that previously took raw pointers (Jon Siwek, Corelight)
* Deprecate TableVal::ConvertToList() and TableVal::ConvertToPureList()
Replaced with ToListVal() and ToPureListVal() that return IntrusivePtr (Jon Siwek, Corelight)
* Switch ListVal to store IntrusivePtrs
* Deprecates ListVal::Index() methods and replaces with ListVal::Idx()
* Replaces ListVal::Vals() method with one that returns
std::vector<IntrusivePtr<Val>> rather than val_list (Jon Siwek, Corelight)
* Deprecant ListVal::Append(Val*) and add IntrusivePtr version (Jon Siwek, Corelight)
* Deprecate ListVal::ConvertToSet(), add ListVal::ToSetVal() (Jon Siwek, Corelight)
* Deprecate TunnelEncapsulation BuildRecordVal/BuildVectorVal methods
Replaced with ToVal methods that return IntrusivePtr (Jon Siwek, Corelight)
* Deprecate various IP/packet header Val-building methods
And supply new alternatives that use IntrusivePtr (Jon Siwek, Corelight)
* Update submodule(s)
[nomail] (Jon Siwek, Corelight)
3.2.0-dev.573 | 2020-05-29 17:13:36 -0700
* Add "Known::service_udp_requires_response" option (Jon Siwek, Corelight)
Determines whether to require UDP server response before considering
an active service to log in known_services.log.
* Update known-services.zeek logic for "active" TCP services (Jon Siwek, Corelight)
To better check for only endpoints that either have observed a TCP handshake
or else assumed to have done one in the past (partial connections, missed
the handshake, but now see data/acks from server)
* Log services with unknown protocol names (Michael Dopheide)
* GH-989: Fix crash on using some deprecated environment variables (Jon Siwek, Corelight)
3.2.0-dev.570 | 2020-05-28 14:49:10 -0700
* Add negotiation flags parameter to some RDP events (Anthony Kasza, Corelight)
Namely rdp_connect_request, rdp_negotiation_response, and rdp_negotiation_failure
* Update test baselines for new Broker connection status/error strings (Jon Siwek, Corelight)
3.2.0-dev.565 | 2020-05-26 21:55:54 +0000
* Add DCE-RPC constants from BZAR project (V)
3.2.0-dev.562 | 2020-05-26 11:06:34 -0700
* GH-979: Update libkqueue to fix use on CentOS 6 (Jon Siwek, Corelight)
3.2.0-dev.561 | 2020-05-21 13:05:39 -0700
* GH-983: Fix opaque Broker types lacking a Type after (de)serialization (Jon Siwek, Corelight)
3.2.0-dev.559 | 2020-05-21 13:04:19 -0700
* Make SendEvent callable from all threads
This commit refactors the SendEvent call and moves it from the Input
ReaderBackend to to MsgThread. This allows all other types of threads
to access this functionality.
This necessitated a few more changes. Most importantly, one of the
ValueToVal methods was moved over to SerialTypes. Whereit arguably
belongs - there was nothing that was input-framework specific in
that method - and the functionality could come in useful in a number
of cases. (Johanna Amann, Corelight)
3.2.0-dev.557 | 2020-05-21 11:41:12 -0700
* Speed up FuzzBuffer ChunkCount validity check (Justin Azoff, Corelight)

117
NEWS
View file

@ -41,6 +41,16 @@ New Functionality
- Add file signature to identify Python bytecode (application/x-python-bytecode)
- Events and hooks are now allowed to have multiple, alternate prototype
declarations. This allows for extending event/hook parameters in a way that
won't break an existing user's handlers and also allows users to define their
own custom event/hook prototypes that consume a subset of the parameters
(convenience of typing/memory/etc). This feature is documented in detail
here: https://docs.zeek.org/en/current/script-reference/types.html#type-event
- Add ``flags`` parameters to ``rdp_connect_request``,
``rdp_negotiation_response``, and ``rdp_negotiation_failure`` events.
Changed Functionality
---------------------
@ -86,6 +96,17 @@ Changed Functionality
- The DCE/RPC operation string of "NetrLogonSamLogonWithFlags" has been
corrected from "NetrLogonSameLogonWithFlags".
- ``TypeList::Types()`` and ``IndexType::IndexTypes()`` now return an
``std::vector`` instead of ``type_list*``
- ``AsRecord()`` and ``AsNonConstRecord()`` have changed to return
``std::vector<IntrusivePtr<Val>>*``.
- ``AsVector()`` has changed to return ``std::vector<IntrusivePtr<Val>>*``.
- ``Attributes::Attrs()`` now returns ``const std::vector<IntrusivePtr<Attr>>&``
instead of ``attr_list*``
Removed Functionality
---------------------
@ -98,10 +119,15 @@ Removed Functionality
Deprecated Functionality
------------------------
- The ``Func::Call(val_list*, ...)`` method is now deprecated. The alternate
overload taking a ``zeek::Args`` (``std::vector<IntrusivePtr<Val>>``) should
be used instead. There's also now a variadic template that forwards all
arguments.
- The ``plugin::Plugin::HookCallFunction()`` method is deprecated. Note
that compilers will not emit a deprecation warning, but the replacement
method to now use is called ``HookFunctionCall`` and uses ``IntrusivePtr``
arguments and return value.
- The ``Func::Call(val_list*, ...)`` method is now deprecated. Use ``Invoke()``
instead which takes a ``zeek::Args`` (``std::vector<IntrusivePtr<Val>>``).
There's also a variadic template for ``Invoke()`` that forwards all arguments
into a ``zeek::Args`` for you.
- The ``EventMgr::QueueEvent()`` and EventMgr::QueueEventFast()`` methods
are now deprecated, use ``EventMgr::Enqueue()`` instead.
@ -125,7 +151,7 @@ Deprecated Functionality
- ``Analyzer::BuildConnVal()`` is deprecated, use ``Analyzer::ConnVal()``.
- ``BifEvent::generate_`` functions are deprecated, use ``BifEvent::enqueue_``.
- ``BifEvent::generate_`` functions are deprecated, use ``zeek::BifEvent::enqueue_``.
- ``binpac::bytestring_to_val()`` is deprecated, use ``binpac::to_stringval()``.
@ -133,6 +159,87 @@ Deprecated Functionality
- Returning ``Val*`` from BIFs is deprecated, return ``IntrusivePtr`` instead.
- Various methods of converting protocol structures, like IP or packet headers,
to associated ``Val`` type are now deprecated, the deprecation warning
message will advise what new method to use instead.
- Various methods of ``Tag`` classes are deprecated with the warning
message advising what new method to use instead.
- The ``utf16_bytestring_to_utf8_val()`` function is deprecated, use
``utf16_to_utf8_val()`` instead.
- ``RecordType::FieldType()`` is deprecated, use ``RecordType::GetFieldType()``
- ``BroType::HasField()`` and ``BroType::FieldType()`` are deprecated, use
the methods of ``RecordType`` directly.
- ``BroType::YieldType()`` is deprecated, use ``BroType::Yield()``.
- ``ID::AsType()`` is deprecated, use ``ID::IsType()`` and ``ID::GetType()``.
- ``ID::Type()`` is deprecated, use ``ID::GetType()``.
- ``ID::ID_Val()`` is deprecated, use ``ID::GetVal()``.
- ``internal_type()`` is deprecated, use ``zeek::id::find_type()``.
- ``internal_val()`` and ``internal_const_val()`` are deprecated, use
``zeek::id::find_val()`` or ``zeek::id::find_const()``.
- ``internal_func()`` is deprecated, use ``zeek::id::find_func()``.
- ``opt_internal_val()`` is deprecated, use ``lookup_ID()`` or
``zeek::id::find_val()``.
- ``Val::Type()`` is deprecated, use ``Val::GetType``.
- Most global type/value pointers in NetVar.h are deprecated, but one can
still always perform the lookup themselves.
- ``Scope::Lookup()`` is deprecated, use ``Scope::Find()``.
- All generated ``BroType*`` names in the ``BifType::`` namespaces are
deprecated, but there's an equivalent name in ``zeek::BifType::`` of
``IntrusivePtr`` type to use instead.
- All generated ``BifConst::`` names are deprecated, but there's an
equivalent name now in ``zeek::BifCont::``, and changed to ``IntrusivePtr``
if the old name was some ``Val*`` type.
- Constructors for ``Val`` types that take a ``BroType*`` are all generally
deprecated, with alternatives that instead take an ``IntrusivePtr`` argument.
- ``FuncType::Args()`` is deprecated, use ``FuncType::Params()``.
- ``FuncType::ArgTypes()`` is deprecated, use ``FuncType::ParamList()``.
- ``RecordVal::Assign(int, Val*)`` is deprecated, use the overload taking
``IntrusivePtr``.
- ``RecordVal::Lookup(int)`` is deprecated, use ``RecordVal::GetField(int)``.
- ``RecordVal::LookupWithDefault(int)`` is deprecated, use
``RecordVal::GetFieldOrDefault(int)``.
- ``RecordVal::Lookup(const char*, bool)`` is deprecated, use either
``RecordVal::GetField()`` or ``RecordVal::GetFieldOrDefault()``.
- ``TableVal::Assign`` methods taking raw ``Val*`` are deprecated, use the
overloads taking ``IntrusivePtr``.
- ``TableVal::Lookup()`` is deprecated, use ``TableVal::Find()`` or
``TableVal::FindOrDefault()``.
- ``VectorVal::Assign`` and ``Insert`` methods taking raw ``Val*`` are
deprecated, use the methods that take ``IntrusivePtr``.
- ``VectorVal::Lookup()`` is deprecated, use ``VectorVal::At()``.
- The file analysis/analyzer API has deprecated methods taking raw
``RecordVal*`` for analyzer arguments and replaced those with methods
taking ``IntrusivePtr``.
Zeek 3.1.0
==========

View file

@ -1 +1 @@
3.2.0-dev.557
3.2.0-dev.738

@ -1 +1 @@
Subproject commit 95fece382d34bca72572cc863e1182b31a1b9945
Subproject commit db2b7cb50926cd8d87b5a1820073a6387385b40c

@ -1 +1 @@
Subproject commit 60f3c7ffb2a2fb77c196f3066c4bc4c2577eb895
Subproject commit 5c676e0fd42ecd5e36cbff19cca5b79a8f3b5a3d

@ -1 +1 @@
Subproject commit 4c22e8b4a9dbb417d4e4c5c8a15dd80bec913bef
Subproject commit 7636475614b583180229a528c470a45f68285e46

View file

@ -4,4 +4,5 @@ set -e
set -x
./configure ${ZEEK_CI_CONFIGURE_FLAGS}
cd build
make -j ${ZEEK_CI_CPUS}

2
doc

@ -1 +1 @@
Subproject commit ddc898c4a7ccea56f7ed74504a00e905639d7ddf
Subproject commit 23dbe360d105d1ffadc231b1d9fb06dea437b110

View file

@ -1870,9 +1870,6 @@ type gtp_delete_pdp_ctx_response_elements: record {
@load base/frameworks/supervisor/api
@load base/bif/supervisor.bif
global done_with_network = F;
event net_done(t: time) { done_with_network = T; }
## Internal function.
function add_interface(iold: string, inew: string): string
{
@ -5272,3 +5269,6 @@ const bits_per_uid: count = 96 &redef;
## to generate installation-unique file IDs (the *id* field of :zeek:see:`fa_file`).
const digest_salt = "Please change this value." &redef;
global done_with_network = F;
event net_done(t: time)
{ done_with_network = T; }

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,10 @@
##! This script logs and tracks services. In the case of this script, a service
##! is defined as an IP address and port which has responded to and fully
##! completed a TCP handshake with another host. If a protocol is detected
##! during the session, the protocol will also be logged.
##! This script logs and tracks active services. For this script, an active
##! service is defined as an IP address and port of a server for which
##! a TCP handshake (SYN+ACK) is observed, assumed to have been done in the
##! past (started seeing packets mid-connection, but the server is actively
##! sending data), or sent at least one UDP packet.
##! If a protocol name is found/known for service, that will be logged,
##! but services whose names can't be determined are also still logged.
@load base/utils/directions-and-hosts
@load base/frameworks/cluster
@ -33,6 +36,9 @@ export {
## operation.
const use_service_store = T &redef;
## Require UDP server to respond before considering it an "active service".
option service_udp_requires_response = T;
## The hosts whose services should be tracked and logged.
## See :zeek:type:`Host` for possible choices.
option service_tracking = LOCAL_HOSTS;
@ -206,10 +212,37 @@ event service_info_commit(info: ServicesInfo)
event known_service_add(info);
}
function has_active_service(c: connection): bool
{
local proto = get_port_transport_proto(c$id$resp_p);
switch ( proto ) {
case tcp:
# Not a service unless the TCP server did a handshake (SYN+ACK).
if ( c$resp$state == TCP_ESTABLISHED ||
c$resp$state == TCP_CLOSED ||
c$resp$state == TCP_PARTIAL ||
/h/ in c$history )
return T;
return F;
case udp:
# Not a service unless UDP server has sent something (or the option
# to not care about that is set).
if ( Known::service_udp_requires_response )
return c$resp$state == UDP_ACTIVE;
return T;
case icmp:
# ICMP is not considered a service.
return F;
default:
# Unknown/other transport not considered a service for now.
return F;
}
}
function known_services_done(c: connection)
{
local id = c$id;
c$known_services_done = T;
if ( ! addr_matches_host(id$resp_h, service_tracking) )
return;
@ -225,6 +258,15 @@ function known_services_done(c: connection)
return;
}
if ( ! has_active_service(c) )
# If we're here during a protocol_confirmation, it's still premature
# to declare there's an actual service, so wait for the connection
# removal to check again (to get more timely reporting we'd have
# schedule some recurring event to poll for handshake/activity).
return;
c$known_services_done = T;
# Drop services starting with "-" (confirmed-but-then-violated protocol)
local tempservs: set[string];
for (s in c$service)
@ -239,7 +281,11 @@ function known_services_done(c: connection)
# If no protocol was detected, wait a short time before attempting to log
# in case a protocol is detected on another connection.
if ( |c$service| == 0 )
{
# Add an empty service so the service loops will work later
add info$service[""];
schedule 5min { service_info_commit(info) };
}
else
event service_info_commit(info);
}
@ -255,12 +301,6 @@ event successful_connection_remove(c: connection) &priority=-5
if ( c$known_services_done )
return;
if ( c$resp$state != TCP_ESTABLISHED && c$resp$state != UDP_ACTIVE )
return;
if ( |c$service| == 0 )
return;
known_services_done(c);
}

View file

@ -10,7 +10,9 @@
#include "Val.h"
#include "NetVar.h"
#include "Reporter.h"
#include "Scope.h"
#include "ID.h"
#include "IPAddr.h"
AnonymizeIPAddr* ip_anonymizer[NUM_ADDR_ANONYMIZATION_METHODS] = {nullptr};
@ -354,6 +356,10 @@ AnonymizeIPAddr_A50::Node* AnonymizeIPAddr_A50::find_node(ipaddr32_t a)
return nullptr;
}
static IntrusivePtr<TableVal> anon_preserve_orig_addr;
static IntrusivePtr<TableVal> anon_preserve_resp_addr;
static IntrusivePtr<TableVal> anon_preserve_other_addr;
void init_ip_addr_anonymizers()
{
ip_anonymizer[KEEP_ORIG_ADDR] = nullptr;
@ -361,35 +367,50 @@ void init_ip_addr_anonymizers()
ip_anonymizer[RANDOM_MD5] = new AnonymizeIPAddr_RandomMD5();
ip_anonymizer[PREFIX_PRESERVING_A50] = new AnonymizeIPAddr_A50();
ip_anonymizer[PREFIX_PRESERVING_MD5] = new AnonymizeIPAddr_PrefixMD5();
auto id = global_scope()->Find("preserve_orig_addr");
if ( id )
anon_preserve_orig_addr = cast_intrusive<TableVal>(id->GetVal());
id = global_scope()->Find("preserve_resp_addr");
if ( id )
anon_preserve_resp_addr = cast_intrusive<TableVal>(id->GetVal());
id = global_scope()->Find("preserve_other_addr");
if ( id )
anon_preserve_other_addr = cast_intrusive<TableVal>(id->GetVal());
}
ipaddr32_t anonymize_ip(ipaddr32_t ip, enum ip_addr_anonymization_class_t cl)
{
TableVal* preserve_addr = nullptr;
AddrVal addr(ip);
auto addr = make_intrusive<AddrVal>(ip);
int method = -1;
switch ( cl ) {
case ORIG_ADDR: // client address
preserve_addr = preserve_orig_addr;
preserve_addr = anon_preserve_orig_addr.get();
method = orig_addr_anonymization;
break;
case RESP_ADDR: // server address
preserve_addr = preserve_resp_addr;
preserve_addr = anon_preserve_resp_addr.get();
method = resp_addr_anonymization;
break;
default:
preserve_addr = preserve_other_addr;
preserve_addr = anon_preserve_other_addr.get();
method = other_addr_anonymization;
break;
}
ipaddr32_t new_ip = 0;
if ( preserve_addr && preserve_addr->Lookup(&addr) )
if ( preserve_addr && preserve_addr->FindOrDefault(addr) )
new_ip = ip;
else if ( method >= 0 && method < NUM_ADDR_ANONYMIZATION_METHODS )

View file

@ -38,6 +38,9 @@ Attr::Attr(attr_tag t)
Attr::~Attr() = default;
void Attr::SetAttrExpr(IntrusivePtr<Expr> e)
{ expr = std::move(e); }
void Attr::Describe(ODesc* d) const
{
AddTag(d);
@ -95,10 +98,10 @@ void Attr::DescribeReST(ODesc* d, bool shorten) const
d->Add("`");
}
else if ( expr->Type()->Tag() == TYPE_FUNC )
else if ( expr->GetType()->Tag() == TYPE_FUNC )
{
d->Add(":zeek:type:`");
d->Add(expr->Type()->AsFuncType()->FlavorString());
d->Add(expr->GetType()->AsFuncType()->FlavorString());
d->Add("`");
}
@ -135,9 +138,8 @@ void Attr::AddTag(ODesc* d) const
}
Attributes::Attributes(attr_list* a, IntrusivePtr<BroType> t, bool arg_in_record, bool is_global)
: type(std::move(t))
{
attrs = new attr_list(a->length());
attrs.reserve(a->length());
in_record = arg_in_record;
global_var = is_global;
@ -153,22 +155,36 @@ Attributes::Attributes(attr_list* a, IntrusivePtr<BroType> t, bool arg_in_record
delete a;
}
Attributes::~Attributes()
{
for ( const auto& attr : *attrs )
Unref(attr);
Attributes::Attributes(IntrusivePtr<BroType> t,
bool arg_in_record, bool is_global)
: Attributes(std::vector<IntrusivePtr<Attr>>{}, std::move(t),
arg_in_record, is_global)
{}
delete attrs;
Attributes::Attributes(std::vector<IntrusivePtr<Attr>> a,
IntrusivePtr<BroType> t,
bool arg_in_record, bool is_global)
: type(std::move(t))
{
attrs.reserve(a.size());
in_record = arg_in_record;
global_var = is_global;
SetLocationInfo(&start_location, &end_location);
// We loop through 'a' and add each attribute individually,
// rather than just taking over 'a' for ourselves, so that
// the necessary checking gets done.
for ( auto& attr : a )
AddAttr(std::move(attr));
}
void Attributes::AddAttr(IntrusivePtr<Attr> attr)
{
if ( ! attrs )
attrs = new attr_list(1);
// We overwrite old attributes by deleting them first.
RemoveAttr(attr->Tag());
attrs->push_back(IntrusivePtr{attr}.release());
attrs.emplace_back(attr);
// We only check the attribute after we've added it, to facilitate
// generating error messages via Attributes::Describe.
@ -177,72 +193,85 @@ void Attributes::AddAttr(IntrusivePtr<Attr> attr)
// 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) &&
! FindAttr(ATTR_REDEF) )
attrs->push_back(new Attr(ATTR_REDEF));
! Find(ATTR_REDEF) )
attrs.emplace_back(make_intrusive<Attr>(ATTR_REDEF));
// For DEFAULT, add an implicit OPTIONAL if it's not a global.
if ( ! global_var && attr->Tag() == ATTR_DEFAULT &&
! FindAttr(ATTR_OPTIONAL) )
attrs->push_back(new Attr(ATTR_OPTIONAL));
! Find(ATTR_OPTIONAL) )
attrs.emplace_back(make_intrusive<Attr>(ATTR_OPTIONAL));
}
void Attributes::AddAttrs(const IntrusivePtr<Attributes>& a)
{
for ( const auto& attr : a->Attrs() )
AddAttr(attr);
}
void Attributes::AddAttrs(Attributes* a)
{
attr_list* as = a->Attrs();
for ( const auto& attr : *as )
AddAttr({NewRef{}, attr});
for ( const auto& attr : a->Attrs() )
AddAttr(attr);
Unref(a);
}
Attr* Attributes::FindAttr(attr_tag t) const
{
if ( ! attrs )
return nullptr;
for ( const auto& a : *attrs )
{
for ( const auto& a : attrs )
if ( a->Tag() == t )
return a;
return a.get();
return nullptr;
}
return nullptr;
const IntrusivePtr<Attr>& Attributes::Find(attr_tag t) const
{
for ( const auto& a : attrs )
if ( a->Tag() == t )
return a;
return Attr::nil;
}
void Attributes::RemoveAttr(attr_tag t)
{
for ( int i = 0; i < attrs->length(); i++ )
if ( (*attrs)[i]->Tag() == t )
attrs->remove_nth(i--);
for ( auto it = attrs.begin(); it != attrs.end(); )
{
if ( (*it)->Tag() == t )
it = attrs.erase(it);
else
++it;
}
}
void Attributes::Describe(ODesc* d) const
{
if ( ! attrs )
if ( attrs.empty() )
{
d->AddCount(0);
return;
}
d->AddCount(attrs->length());
d->AddCount(static_cast<uint64_t>(attrs.size()));
loop_over_list(*attrs, i)
for ( size_t i = 0; i < attrs.size(); ++i )
{
if ( (d->IsReadable() || d->IsPortable()) && i > 0 )
d->Add(", ");
(*attrs)[i]->Describe(d);
attrs[i]->Describe(d);
}
}
void Attributes::DescribeReST(ODesc* d, bool shorten) const
{
loop_over_list(*attrs, i)
for ( size_t i = 0; i < attrs.size(); ++i )
{
if ( i > 0 )
d->Add(" ");
(*attrs)[i]->DescribeReST(d, shorten);
attrs[i]->DescribeReST(d, shorten);
}
}
@ -263,10 +292,10 @@ void Attributes::CheckAttr(Attr* a)
{
bool is_add = a->Tag() == ATTR_ADD_FUNC;
BroType* at = a->AttrExpr()->Type();
const auto& at = a->GetExpr()->GetType();
if ( at->Tag() != TYPE_FUNC )
{
a->AttrExpr()->Error(
a->GetExpr()->Error(
is_add ?
"&add_func must be a function" :
"&delete_func must be a function");
@ -274,9 +303,9 @@ void Attributes::CheckAttr(Attr* a)
}
FuncType* aft = at->AsFuncType();
if ( ! same_type(aft->YieldType(), type.get()) )
if ( ! same_type(aft->Yield(), type) )
{
a->AttrExpr()->Error(
a->GetExpr()->Error(
is_add ?
"&add_func function must yield same type as variable" :
"&delete_func function must yield same type as variable");
@ -295,11 +324,11 @@ void Attributes::CheckAttr(Attr* a)
break;
}
BroType* atype = a->AttrExpr()->Type();
const auto& atype = a->GetExpr()->GetType();
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) )
{
if ( same_type(atype, type.get()) )
if ( same_type(atype, type) )
// Ok.
break;
@ -315,7 +344,7 @@ void Attributes::CheckAttr(Attr* a)
// Ok.
break;
auto e = check_and_promote_expr(a->AttrExpr(), type.get());
auto e = check_and_promote_expr(a->GetExpr().get(), type.get());
if ( e )
{
@ -324,12 +353,12 @@ void Attributes::CheckAttr(Attr* a)
break;
}
a->AttrExpr()->Error("&default value has inconsistent type", type.get());
a->GetExpr()->Error("&default value has inconsistent type", type.get());
return;
}
TableType* tt = type->AsTableType();
BroType* ytype = tt->YieldType();
const auto& ytype = tt->Yield();
if ( ! in_record )
{
@ -341,7 +370,7 @@ void Attributes::CheckAttr(Attr* a)
{
FuncType* f = atype->AsFuncType();
if ( ! f->CheckArgs(tt->IndexTypes()) ||
! same_type(f->YieldType(), ytype) )
! same_type(f->Yield(), ytype) )
Error("&default function type clash");
// Ok.
@ -355,7 +384,7 @@ void Attributes::CheckAttr(Attr* a)
// Ok.
break;
auto e = check_and_promote_expr(a->AttrExpr(), ytype);
auto e = check_and_promote_expr(a->GetExpr().get(), ytype.get());
if ( e )
{
@ -375,13 +404,13 @@ void Attributes::CheckAttr(Attr* a)
{
// &default applies to record field.
if ( same_type(atype, type.get()) )
if ( same_type(atype, type) )
// Ok.
break;
if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) )
{
auto e = check_and_promote_expr(a->AttrExpr(), type.get());
auto e = check_and_promote_expr(a->GetExpr().get(), type.get());
if ( e )
{
@ -413,16 +442,14 @@ void Attributes::CheckAttr(Attr* a)
}
int num_expires = 0;
if ( attrs )
{
for ( const auto& a : *attrs )
for ( const auto& a : attrs )
{
if ( a->Tag() == ATTR_EXPIRE_READ ||
a->Tag() == ATTR_EXPIRE_WRITE ||
a->Tag() == ATTR_EXPIRE_CREATE )
num_expires++;
}
}
if ( num_expires > 1 )
{
@ -447,14 +474,14 @@ void Attributes::CheckAttr(Attr* a)
break;
}
const Expr* expire_func = a->AttrExpr();
const auto& expire_func = a->GetExpr();
if ( expire_func->Type()->Tag() != TYPE_FUNC )
if ( expire_func->GetType()->Tag() != TYPE_FUNC )
Error("&expire_func attribute is not a function");
const FuncType* e_ft = expire_func->Type()->AsFuncType();
const FuncType* e_ft = expire_func->GetType()->AsFuncType();
if ( e_ft->YieldType()->Tag() != TYPE_INTERVAL )
if ( e_ft->Yield()->Tag() != TYPE_INTERVAL )
{
Error("&expire_func must yield a value of type interval");
break;
@ -465,20 +492,21 @@ void Attributes::CheckAttr(Attr* a)
if (the_table->IsUnspecifiedTable())
break;
const type_list* func_index_types = e_ft->ArgTypes()->Types();
const auto& func_index_types = e_ft->ParamList()->Types();
// Keep backwards compatibility with idx: any idiom.
if ( func_index_types->length() == 2 )
if ( func_index_types.size() == 2 )
{
if ((*func_index_types)[1]->Tag() == TYPE_ANY)
if (func_index_types[1]->Tag() == TYPE_ANY)
break;
}
const type_list* table_index_types = the_table->IndexTypes();
const auto& table_index_types = the_table->IndexTypes();
type_list expected_args;
type_list expected_args(1 + static_cast<int>(table_index_types.size()));
expected_args.push_back(type->AsTableType());
for (const auto& t : *table_index_types)
expected_args.push_back(t);
for ( const auto& t : table_index_types )
expected_args.push_back(t.get());
if ( ! e_ft->CheckArgs(&expected_args) )
Error("&expire_func argument type clash");
@ -493,14 +521,14 @@ void Attributes::CheckAttr(Attr* a)
break;
}
const Expr* change_func = a->AttrExpr();
const auto& change_func = a->GetExpr();
if ( change_func->Type()->Tag() != TYPE_FUNC || change_func->Type()->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->Type()->AsFuncType();
const FuncType* c_ft = change_func->GetType()->AsFuncType();
if ( c_ft->YieldType()->Tag() != TYPE_VOID )
if ( c_ft->Yield()->Tag() != TYPE_VOID )
{
Error("&on_change must not return a value");
break;
@ -511,30 +539,30 @@ void Attributes::CheckAttr(Attr* a)
if ( the_table->IsUnspecifiedTable() )
break;
const type_list* args = c_ft->ArgTypes()->Types();
const type_list* t_indexes = the_table->IndexTypes();
if ( args->length() != ( type->IsSet() ? 2 : 3 ) + t_indexes->length() )
const auto& args = c_ft->ParamList()->Types();
const auto& t_indexes = the_table->IndexTypes();
if ( args.size() != ( type->IsSet() ? 2 : 3 ) + t_indexes.size() )
{
Error("&on_change function has incorrect number of arguments");
break;
}
if ( ! same_type((*args)[0], the_table->AsTableType()) )
if ( ! same_type(args[0], the_table->AsTableType()) )
{
Error("&on_change: first argument must be of same type as table");
break;
}
// can't check exact type here yet - the data structures don't exist yet.
if ( (*args)[1]->Tag() != TYPE_ENUM )
if ( args[1]->Tag() != TYPE_ENUM )
{
Error("&on_change: second argument must be a TableChange enum");
break;
}
for ( int i = 0; i < t_indexes->length(); i++ )
for ( size_t i = 0; i < t_indexes.size(); i++ )
{
if ( ! same_type((*args)[2+i], (*t_indexes)[i]) )
if ( ! same_type(args[2+i], t_indexes[i]) )
{
Error("&on_change: index types do not match table");
break;
@ -542,7 +570,7 @@ void Attributes::CheckAttr(Attr* a)
}
if ( ! type->IsSet() )
if ( ! same_type((*args)[2+t_indexes->length()], the_table->YieldType()) )
if ( ! same_type(args[2+t_indexes.size()], the_table->Yield()) )
{
Error("&on_change: value type does not match table");
break;
@ -610,7 +638,7 @@ void Attributes::CheckAttr(Attr* a)
break;
}
BroType* atype = a->AttrExpr()->Type();
const auto& atype = a->GetExpr()->GetType();
if ( atype->Tag() != TYPE_STRING ) {
Error("type column needs to have a string argument");
@ -628,15 +656,15 @@ void Attributes::CheckAttr(Attr* a)
bool Attributes::operator==(const Attributes& other) const
{
if ( ! attrs )
return other.attrs;
if ( attrs.empty() )
return other.attrs.empty();
if ( ! other.attrs )
if ( other.attrs.empty() )
return false;
for ( const auto& a : *attrs )
for ( const auto& a : attrs )
{
Attr* o = other.FindAttr(a->Tag());
const auto& o = other.Find(a->Tag());
if ( ! o )
return false;
@ -645,9 +673,9 @@ bool Attributes::operator==(const Attributes& other) const
return false;
}
for ( const auto& o : *other.attrs )
for ( const auto& o : other.attrs )
{
Attr* a = FindAttr(o->Tag());
const auto& a = Find(o->Tag());
if ( ! a )
return false;

View file

@ -2,6 +2,8 @@
#pragma once
#include <vector>
#include "Obj.h"
#include "BroList.h"
#include "IntrusivePtr.h"
@ -37,15 +39,21 @@ typedef enum {
class Attr final : public BroObj {
public:
static inline const IntrusivePtr<Attr> nil;
Attr(attr_tag t, IntrusivePtr<Expr> e);
explicit Attr(attr_tag t);
~Attr() override;
attr_tag Tag() const { return tag; }
[[deprecated("Remove in v4.1. Use GetExpr().")]]
Expr* AttrExpr() const { return expr.get(); }
template<typename E>
void SetAttrExpr(E&& e) { expr = std::forward<E>(e); }
const IntrusivePtr<Expr>& GetExpr() const
{ return expr; }
void SetAttrExpr(IntrusivePtr<Expr> e);
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool shorten = false) const;
@ -74,20 +82,32 @@ protected:
// Manages a collection of attributes.
class Attributes final : public BroObj {
public:
[[deprecated("Remove in v4.1. Construct using IntrusivePtrs instead.")]]
Attributes(attr_list* a, IntrusivePtr<BroType> t, bool in_record, bool is_global);
~Attributes() override;
Attributes(std::vector<IntrusivePtr<Attr>> a, IntrusivePtr<BroType> t,
bool in_record, bool is_global);
Attributes(IntrusivePtr<BroType> t, bool in_record, bool is_global);
void AddAttr(IntrusivePtr<Attr> a);
void AddAttrs(const IntrusivePtr<Attributes>& a);
[[deprecated("Remove in v4.1. Pass IntrusivePtr instead.")]]
void AddAttrs(Attributes* a); // Unref's 'a' when done
[[deprecated("Remove in v4.1. Use Find().")]]
Attr* FindAttr(attr_tag t) const;
const IntrusivePtr<Attr>& Find(attr_tag t) const;
void RemoveAttr(attr_tag t);
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool shorten = false) const;
attr_list* Attrs() { return attrs; }
const std::vector<IntrusivePtr<Attr>>& Attrs() const
{ return attrs; }
bool operator==(const Attributes& other) const;
@ -95,7 +115,7 @@ protected:
void CheckAttr(Attr* attr);
IntrusivePtr<BroType> type;
attr_list* attrs;
std::vector<IntrusivePtr<Attr>> attrs;
bool in_record;
bool global_var;
};

View file

@ -8,7 +8,7 @@
#include <ctype.h>
#include "Val.h"
#include "Var.h"
#include "ID.h"
#include "Reporter.h"
#include "util.h"
@ -340,20 +340,17 @@ BroString::Vec* BroString::Split(const BroString::IdxVec& indices) const
VectorVal* BroString:: VecToPolicy(Vec* vec)
{
VectorVal* result =
new VectorVal(internal_type("string_vec")->AsVectorType());
if ( ! result )
return nullptr;
auto result = make_intrusive<VectorVal>(zeek::id::string_vec);
for ( unsigned int i = 0; i < vec->size(); ++i )
{
BroString* string = (*vec)[i];
StringVal* val = new StringVal(string->Len(),
auto val = make_intrusive<StringVal>(string->Len(),
(const char*) string->Bytes());
result->Assign(i+1, val);
result->Assign(i+1, std::move(val));
}
return result;
return result.release();
}
BroString::Vec* BroString::VecFromPolicy(VectorVal* vec)
@ -363,7 +360,7 @@ BroString::Vec* BroString::VecFromPolicy(VectorVal* vec)
// VectorVals start at index 1!
for ( unsigned int i = 1; i <= vec->Size(); ++i )
{
Val* v = vec->Lookup(i); // get the RecordVal
const auto& v = vec->At(i); // get the RecordVal
if ( ! v )
continue;

View file

@ -205,6 +205,9 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
set_source_files_properties(nb_dns.c PROPERTIES COMPILE_FLAGS
-fno-strict-aliasing)
set_source_files_properties(legacy-netvar-init.cc PROPERTIES COMPILE_FLAGS
-Wno-deprecated-declarations)
set(MAIN_SRCS
digest.cc
net_util.cc
@ -286,6 +289,7 @@ set(MAIN_SRCS
Var.cc
WeirdState.cc
ZeekArgs.cc
legacy-netvar-init.cc
bsd-getopt-long.c
bro_inet_ntop.c
patricia.c

View file

@ -2,6 +2,9 @@
#include "zeek-config.h"
#include <vector>
#include <map>
#include "CompHash.h"
#include "BroString.h"
#include "Dict.h"
@ -9,9 +12,7 @@
#include "RE.h"
#include "Reporter.h"
#include "Func.h"
#include <vector>
#include <map>
#include "IPAddr.h"
CompositeHash::CompositeHash(IntrusivePtr<TypeList> composite_type)
: type(std::move(composite_type))
@ -21,9 +22,9 @@ CompositeHash::CompositeHash(IntrusivePtr<TypeList> composite_type)
// If the only element is a record, don't treat it as a
// singleton, since it needs to be evaluated specially.
if ( type->Types()->length() == 1 )
if ( type->Types().size() == 1 )
{
if ( (*type->Types())[0]->Tag() == TYPE_RECORD )
if ( type->Types()[0]->Tag() == TYPE_RECORD )
{
is_complex_type = true;
is_singleton = false;
@ -45,7 +46,7 @@ CompositeHash::CompositeHash(IntrusivePtr<TypeList> composite_type)
{
// Don't do any further key computations - we'll do them
// via the singleton later.
singleton_tag = (*type->Types())[0]->InternalType();
singleton_tag = type->Types()[0]->InternalType();
size = 0;
key = nullptr;
}
@ -88,7 +89,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
if ( type_check )
{
InternalTypeTag vt = v->Type()->InternalType();
InternalTypeTag vt = v->GetType()->InternalType();
if ( vt != t )
return nullptr;
}
@ -138,7 +139,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
case TYPE_INTERNAL_VOID:
case TYPE_INTERNAL_OTHER:
{
switch ( v->Type()->Tag() ) {
switch ( v->GetType()->Tag() ) {
case TYPE_FUNC:
{
uint32_t* kp = AlignAndPadType<uint32_t>(kp0);
@ -180,16 +181,16 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
for ( int i = 0; i < num_fields; ++i )
{
auto rv_i = rv->Lookup(i);
auto rv_i = rv->GetField(i).get();
Attributes* a = rt->FieldDecl(i)->attrs.get();
bool optional = (a && a->FindAttr(ATTR_OPTIONAL));
bool optional = (a && a->Find(ATTR_OPTIONAL));
if ( ! (rv_i || optional) )
return nullptr;
if ( ! (kp = SingleValHash(type_check, kp,
rt->FieldType(i),
rt->GetFieldType(i).get(),
rv_i, optional)) )
return nullptr;
}
@ -229,7 +230,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
while ( tbl->NextEntry(k, it) )
{
hashkeys[k] = idx++;
lv->Append(tv->RecoverIndex(k).release());
lv->Append(tv->RecreateIndex(*k));
}
for ( auto& kv : hashkeys )
@ -238,17 +239,17 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
for ( auto& kv : hashkeys )
{
auto idx = kv.second;
Val* key = lv->Index(idx);
const auto& key = lv->Idx(idx);
if ( ! (kp1 = SingleValHash(type_check, kp1, key->Type(), key,
false)) )
if ( ! (kp1 = SingleValHash(type_check, kp1, key->GetType().get(),
key.get(), false)) )
return nullptr;
if ( ! v->Type()->IsSet() )
if ( ! v->GetType()->IsSet() )
{
auto val = tv->Lookup(key);
auto val = tv->FindOrDefault(key);
if ( ! (kp1 = SingleValHash(type_check, kp1, val->Type(),
if ( ! (kp1 = SingleValHash(type_check, kp1, val->GetType().get(),
val.get(), false)) )
return nullptr;
}
@ -261,12 +262,12 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
{
unsigned int* kp = AlignAndPadType<unsigned int>(kp0);
VectorVal* vv = v->AsVectorVal();
VectorType* vt = v->Type()->AsVectorType();
VectorType* vt = v->GetType()->AsVectorType();
*kp = vv->Size();
kp1 = reinterpret_cast<char*>(kp+1);
for ( unsigned int i = 0; i < vv->Size(); ++i )
{
Val* val = vv->Lookup(i);
const auto& val = vv->At(i);
unsigned int* kp = AlignAndPadType<unsigned int>(kp1);
*kp = i;
kp1 = reinterpret_cast<char*>(kp+1);
@ -277,7 +278,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
if ( val )
{
if ( ! (kp1 = SingleValHash(type_check, kp1,
vt->YieldType(), val, false)) )
vt->Yield().get(), val.get(),
false)) )
return nullptr;
}
}
@ -292,8 +294,8 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
kp1 = reinterpret_cast<char*>(kp+1);
for ( int i = 0; i < lv->Length(); ++i )
{
Val* v = lv->Index(i);
if ( ! (kp1 = SingleValHash(type_check, kp1, v->Type(), v,
Val* v = lv->Idx(i).get();
if ( ! (kp1 = SingleValHash(type_check, kp1, v->GetType().get(), v,
false)) )
return nullptr;
}
@ -333,15 +335,14 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
}
HashKey* CompositeHash::ComputeHash(const Val* v, bool type_check) const
std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_check) const
{
if ( ! v )
reporter->InternalError("null value given to CompositeHash::ComputeHash");
auto v = &argv;
if ( is_singleton )
return ComputeSingletonHash(v, type_check);
if ( is_complex_type && v->Type()->Tag() != TYPE_LIST )
if ( is_complex_type && v->GetType()->Tag() != TYPE_LIST )
{
ListVal lv(TYPE_ANY);
@ -349,10 +350,8 @@ HashKey* CompositeHash::ComputeHash(const Val* v, bool type_check) const
// re-introduce const on the recursive call, it should
// be okay; the only thing is that the ListVal unref's it.
Val* ncv = (Val*) v;
ncv->Ref();
lv.Append(ncv);
HashKey* hk = ComputeHash(&lv, type_check);
return hk;
lv.Append({NewRef{}, ncv});
return MakeHashKey(lv, type_check);
}
char* k = key;
@ -367,60 +366,62 @@ HashKey* CompositeHash::ComputeHash(const Val* v, bool type_check) const
type_check = false; // no need to type-check again.
}
const type_list* tl = type->Types();
const auto& tl = type->Types();
if ( type_check && v->Type()->Tag() != TYPE_LIST )
if ( type_check && v->GetType()->Tag() != TYPE_LIST )
return nullptr;
const val_list* vl = v->AsListVal()->Vals();
if ( type_check && vl->length() != tl->length() )
auto lv = v->AsListVal();
if ( type_check && lv->Length() != static_cast<int>(tl.size()) )
return nullptr;
char* kp = k;
loop_over_list(*tl, i)
for ( auto i = 0u; i < tl.size(); ++i )
{
kp = SingleValHash(type_check, kp, (*tl)[i], (*vl)[i], false);
kp = SingleValHash(type_check, kp, tl[i].get(), lv->Idx(i).get(), false);
if ( ! kp )
return nullptr;
}
return new HashKey((k == key), (void*) k, kp - k);
return std::make_unique<HashKey>((k == key), (void*) k, kp - k);
}
HashKey* CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) const
std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) const
{
if ( v->Type()->Tag() == TYPE_LIST )
if ( v->GetType()->Tag() == TYPE_LIST )
{
const val_list* vl = v->AsListVal()->Vals();
if ( type_check && vl->length() != 1 )
auto lv = v->AsListVal();
if ( type_check && lv->Length() != 1 )
return nullptr;
v = (*vl)[0];
v = lv->Idx(0).get();
}
if ( type_check && v->Type()->InternalType() != singleton_tag )
if ( type_check && v->GetType()->InternalType() != singleton_tag )
return nullptr;
switch ( singleton_tag ) {
case TYPE_INTERNAL_INT:
case TYPE_INTERNAL_UNSIGNED:
return new HashKey(v->ForceAsInt());
return std::make_unique<HashKey>(v->ForceAsInt());
case TYPE_INTERNAL_ADDR:
return v->AsAddr().GetHashKey();
return v->AsAddr().MakeHashKey();
case TYPE_INTERNAL_SUBNET:
return v->AsSubNet().GetHashKey();
return v->AsSubNet().MakeHashKey();
case TYPE_INTERNAL_DOUBLE:
return new HashKey(v->InternalDouble());
return std::make_unique<HashKey>(v->InternalDouble());
case TYPE_INTERNAL_VOID:
case TYPE_INTERNAL_OTHER:
if ( v->Type()->Tag() == TYPE_FUNC )
return new HashKey(v->AsFunc()->GetUniqueFuncID());
if ( v->GetType()->Tag() == TYPE_FUNC )
return std::make_unique<HashKey>(v->AsFunc()->GetUniqueFuncID());
if ( v->Type()->Tag() == TYPE_PATTERN )
if ( v->GetType()->Tag() == TYPE_PATTERN )
{
const char* texts[2] = {
v->AsPattern()->PatternText(),
@ -430,14 +431,14 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) cons
char* key = new char[n];
std::memcpy(key, texts[0], strlen(texts[0]) + 1);
std::memcpy(key + strlen(texts[0]) + 1, texts[1], strlen(texts[1]) + 1);
return new HashKey(false, key, n);
return std::make_unique<HashKey>(false, key, n);
}
reporter->InternalError("bad index type in CompositeHash::ComputeSingletonHash");
return nullptr;
case TYPE_INTERNAL_STRING:
return new HashKey(v->AsString());
return std::make_unique<HashKey>(v->AsString());
case TYPE_INTERNAL_ERROR:
return nullptr;
@ -459,7 +460,7 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
if ( type_check && v )
{
InternalTypeTag vt = v->Type()->InternalType();
InternalTypeTag vt = v->GetType()->InternalType();
if ( vt != t )
return 0;
}
@ -514,10 +515,10 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
for ( int i = 0; i < num_fields; ++i )
{
Attributes* a = rt->FieldDecl(i)->attrs.get();
bool optional = (a && a->FindAttr(ATTR_OPTIONAL));
bool optional = (a && a->Find(ATTR_OPTIONAL));
sz = SingleTypeKeySize(rt->FieldType(i),
rv ? rv->Lookup(i) : nullptr,
sz = SingleTypeKeySize(rt->GetFieldType(i).get(),
rv ? rv->GetField(i).get() : nullptr,
type_check, sz, optional,
calc_static_size);
if ( ! sz )
@ -534,32 +535,24 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
sz = SizeAlign(sz, sizeof(int));
TableVal* tv = const_cast<TableVal*>(v->AsTableVal());
ListVal* lv = tv->ConvertToList();
auto lv = tv->ToListVal();
for ( int i = 0; i < tv->Size(); ++i )
{
Val* key = lv->Index(i);
sz = SingleTypeKeySize(key->Type(), key, type_check, sz, false,
const auto& key = lv->Idx(i);
sz = SingleTypeKeySize(key->GetType().get(), key.get(), type_check, sz, false,
calc_static_size);
if ( ! sz )
{
Unref(lv);
return 0;
}
if ( ! bt->IsSet() )
{
auto val = tv->Lookup(key);
sz = SingleTypeKeySize(val->Type(), val.get(), type_check, sz,
auto val = tv->FindOrDefault(key);
sz = SingleTypeKeySize(val->GetType().get(), val.get(), type_check, sz,
false, calc_static_size);
if ( ! sz )
{
Unref(lv);
return 0;
}
}
}
Unref(lv);
break;
}
@ -573,12 +566,12 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
VectorVal* vv = const_cast<VectorVal*>(v->AsVectorVal());
for ( unsigned int i = 0; i < vv->Size(); ++i )
{
Val* val = vv->Lookup(i);
const auto& val = vv->At(i);
sz = SizeAlign(sz, sizeof(unsigned int));
sz = SizeAlign(sz, sizeof(unsigned int));
if ( val )
sz = SingleTypeKeySize(bt->AsVectorType()->YieldType(),
val, type_check, sz, false,
sz = SingleTypeKeySize(bt->AsVectorType()->Yield().get(),
val.get(), type_check, sz, false,
calc_static_size);
if ( ! sz ) return 0;
}
@ -595,7 +588,7 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
ListVal* lv = const_cast<ListVal*>(v->AsListVal());
for ( int i = 0; i < lv->Length(); ++i )
{
sz = SingleTypeKeySize(lv->Index(i)->Type(), lv->Index(i),
sz = SingleTypeKeySize(lv->Idx(i)->GetType().get(), lv->Idx(i).get(),
type_check, sz, false, calc_static_size);
if ( ! sz) return 0;
}
@ -631,22 +624,23 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
int CompositeHash::ComputeKeySize(const Val* v, bool type_check, bool calc_static_size) const
{
const type_list* tl = type->Types();
const val_list* vl = nullptr;
const auto& tl = type->Types();
if ( v )
{
if ( type_check && v->Type()->Tag() != TYPE_LIST )
if ( type_check && v->GetType()->Tag() != TYPE_LIST )
return 0;
vl = v->AsListVal()->Vals();
if ( type_check && vl->length() != tl->length() )
auto lv = v->AsListVal();
if ( type_check && lv->Length() != static_cast<int>(tl.size()) )
return 0;
}
int sz = 0;
loop_over_list(*tl, i)
for ( auto i = 0u; i < tl.size(); ++i )
{
sz = SingleTypeKeySize((*tl)[i], v ? v->AsListVal()->Index(i) : nullptr,
sz = SingleTypeKeySize(tl[i].get(), v ? v->AsListVal()->Idx(i).get() : nullptr,
type_check, sz, false, calc_static_size);
if ( ! sz )
return 0;
@ -714,19 +708,19 @@ int CompositeHash::SizeAlign(int offset, unsigned int size) const
return offset;
}
IntrusivePtr<ListVal> CompositeHash::RecoverVals(const HashKey* k) const
IntrusivePtr<ListVal> CompositeHash::RecoverVals(const HashKey& k) const
{
auto l = make_intrusive<ListVal>(TYPE_ANY);
const type_list* tl = type->Types();
const char* kp = (const char*) k->Key();
const char* const k_end = kp + k->Size();
const auto& tl = type->Types();
const char* kp = (const char*) k.Key();
const char* const k_end = kp + k.Size();
for ( const auto& type : *tl )
for ( const auto& type : tl )
{
IntrusivePtr<Val> v;
kp = RecoverOneVal(k, kp, k_end, type, &v, false);
kp = RecoverOneVal(k, kp, k_end, type.get(), &v, false);
ASSERT(v);
l->Append(v.release());
l->Append(std::move(v));
}
if ( kp != k_end )
@ -735,12 +729,12 @@ IntrusivePtr<ListVal> CompositeHash::RecoverVals(const HashKey* k) const
return l;
}
const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
const char* CompositeHash::RecoverOneVal(const HashKey& k, const char* kp0,
const char* const k_end, BroType* t,
IntrusivePtr<Val>* pval, bool optional) const
{
// k->Size() == 0 for a single empty string.
if ( kp0 >= k_end && k->Size() > 0 )
if ( kp0 >= k_end && k.Size() > 0 )
reporter->InternalError("over-ran key in CompositeHash::RecoverVals");
TypeTag tag = t->Tag();
@ -851,13 +845,13 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
const uint32_t* const kp = AlignType<uint32_t>(kp0);
kp1 = reinterpret_cast<const char*>(kp+1);
Func* f = Func::GetFuncPtrByID(*kp);
const auto& f = Func::GetFuncPtrByID(*kp);
if ( ! f )
reporter->InternalError("failed to look up unique function id %" PRIu32 " in CompositeHash::RecoverOneVal()", *kp);
*pval = make_intrusive<Val>(f);
auto pvt = (*pval)->Type();
const auto& pvt = (*pval)->GetType();
if ( ! pvt )
reporter->InternalError("bad aggregate Val in CompositeHash::RecoverOneVal()");
@ -881,7 +875,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
kp1 = kp0;
int divider = strlen(kp0) + 1;
re = new RE_Matcher(kp1, kp1 + divider);
kp1 += k->Size();
kp1 += k.Size();
}
else
{
@ -906,17 +900,17 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
RecordType* rt = t->AsRecordType();
int num_fields = rt->NumFields();
std::vector<Val*> values;
std::vector<IntrusivePtr<Val>> values;
int i;
for ( i = 0; i < num_fields; ++i )
{
IntrusivePtr<Val> v;
Attributes* a = rt->FieldDecl(i)->attrs.get();
bool optional = (a && a->FindAttr(ATTR_OPTIONAL));
bool optional = (a && a->Find(ATTR_OPTIONAL));
kp = RecoverOneVal(k, kp, k_end,
rt->FieldType(i), &v, optional);
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.
@ -928,15 +922,15 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
break;
}
values.push_back(v.release());
values.emplace_back(std::move(v));
}
ASSERT(int(values.size()) == num_fields);
auto rv = make_intrusive<RecordVal>(rt);
auto rv = make_intrusive<RecordVal>(IntrusivePtr{NewRef{}, rt});
for ( int i = 0; i < num_fields; ++i )
rv->Assign(i, values[i]);
rv->Assign(i, std::move(values[i]));
*pval = std::move(rv);
kp1 = kp;
@ -955,16 +949,16 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
for ( int i = 0; i < n; ++i )
{
IntrusivePtr<Val> key;
kp1 = RecoverOneVal(k, kp1, k_end, tt->Indices(), &key, false);
kp1 = RecoverOneVal(k, kp1, k_end, tt->GetIndices().get(), &key, false);
if ( t->IsSet() )
tv->Assign(key.get(), nullptr);
tv->Assign(std::move(key), nullptr);
else
{
IntrusivePtr<Val> value;
kp1 = RecoverOneVal(k, kp1, k_end, tt->YieldType(), &value,
kp1 = RecoverOneVal(k, kp1, k_end, tt->Yield().get(), &value,
false);
tv->Assign(key.get(), std::move(value));
tv->Assign(std::move(key), std::move(value));
}
}
@ -979,7 +973,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
n = *kp;
kp1 = reinterpret_cast<const char*>(kp+1);
VectorType* vt = t->AsVectorType();
auto vv = make_intrusive<VectorVal>(vt);
auto vv = make_intrusive<VectorVal>(IntrusivePtr{NewRef{}, vt});
for ( unsigned int i = 0; i < n; ++i )
{
@ -992,7 +986,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
IntrusivePtr<Val> value;
if ( have_val )
kp1 = RecoverOneVal(k, kp1, k_end, vt->YieldType(), &value,
kp1 = RecoverOneVal(k, kp1, k_end, vt->Yield().get(), &value,
false);
vv->Assign(index, std::move(value));
@ -1014,9 +1008,9 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
for ( int i = 0; i < n; ++i )
{
IntrusivePtr<Val> v;
BroType* it = (*tl->Types())[i];
BroType* it = tl->Types()[i].get();
kp1 = RecoverOneVal(k, kp1, k_end, it, &v, false);
lv->Append(v.release());
lv->Append(std::move(v));
}
*pval = std::move(lv);
@ -1040,7 +1034,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
if ( is_singleton )
{
kp1 = kp0;
n = k->Size();
n = k.Size();
}
else
{

View file

@ -2,6 +2,8 @@
#pragma once
#include <memory>
#include "Type.h"
#include "IntrusivePtr.h"
@ -14,16 +16,24 @@ public:
~CompositeHash();
// Compute the hash corresponding to the given index val,
// or 0 if it fails to typecheck.
HashKey* ComputeHash(const Val* v, bool type_check) const;
// or nullptr if it fails to typecheck.
std::unique_ptr<HashKey> MakeHashKey(const Val& v, bool type_check) const;
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
HashKey* ComputeHash(const Val* v, bool type_check) const
{ return MakeHashKey(*v, type_check).release(); }
// Given a hash key, recover the values used to create it.
IntrusivePtr<ListVal> RecoverVals(const HashKey* k) const;
IntrusivePtr<ListVal> RecoverVals(const HashKey& k) const;
[[deprecated("Remove in v4.1. Pass in HashKey& instead.")]]
IntrusivePtr<ListVal> RecoverVals(const HashKey* k) const
{ return RecoverVals(*k); }
unsigned int MemoryAllocation() const { return padded_sizeof(*this) + pad_size(size); }
protected:
HashKey* ComputeSingletonHash(const Val* v, bool type_check) const;
std::unique_ptr<HashKey> ComputeSingletonHash(const Val* v, bool type_check) const;
// Computes the piece of the hash for Val*, returning the new kp.
// Used as a helper for ComputeHash in the non-singleton case.
@ -34,7 +44,7 @@ protected:
// 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* RecoverOneVal(const HashKey& k,
const char* kp, const char* const k_end,
BroType* t, IntrusivePtr<Val>* pval, bool optional) const;

View file

@ -146,7 +146,7 @@ void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
{
if ( tunnel_changed )
EnqueueEvent(tunnel_changed, nullptr, ConnVal(),
IntrusivePtr{AdoptRef{}, arg_encap->GetVectorVal()});
arg_encap->ToVal());
delete encapsulation;
encapsulation = new EncapsulationStack(*arg_encap);
@ -158,8 +158,7 @@ void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
if ( tunnel_changed )
{
EncapsulationStack empty;
EnqueueEvent(tunnel_changed, nullptr, ConnVal(),
IntrusivePtr{AdoptRef{}, empty.GetVectorVal()});
EnqueueEvent(tunnel_changed, nullptr, ConnVal(), empty.ToVal());
}
delete encapsulation;
@ -169,8 +168,7 @@ void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap)
else if ( arg_encap )
{
if ( tunnel_changed )
EnqueueEvent(tunnel_changed, nullptr, ConnVal(),
IntrusivePtr{AdoptRef{}, arg_encap->GetVectorVal()});
EnqueueEvent(tunnel_changed, nullptr, ConnVal(), arg_encap->ToVal());
encapsulation = new EncapsulationStack(*arg_encap);
}
@ -348,17 +346,17 @@ const IntrusivePtr<RecordVal>& Connection::ConnVal()
{
if ( ! conn_val )
{
conn_val = make_intrusive<RecordVal>(connection_type);
conn_val = make_intrusive<RecordVal>(zeek::id::connection);
TransportProto prot_type = ConnTransport();
auto id_val = make_intrusive<RecordVal>(conn_id);
auto id_val = make_intrusive<RecordVal>(zeek::id::conn_id);
id_val->Assign(0, make_intrusive<AddrVal>(orig_addr));
id_val->Assign(1, val_mgr->Port(ntohs(orig_port), prot_type));
id_val->Assign(2, make_intrusive<AddrVal>(resp_addr));
id_val->Assign(3, val_mgr->Port(ntohs(resp_port), prot_type));
auto orig_endp = make_intrusive<RecordVal>(endpoint);
auto orig_endp = make_intrusive<RecordVal>(zeek::id::endpoint);
orig_endp->Assign(0, val_mgr->Count(0));
orig_endp->Assign(1, val_mgr->Count(0));
orig_endp->Assign(4, val_mgr->Count(orig_flow_label));
@ -369,7 +367,7 @@ const IntrusivePtr<RecordVal>& Connection::ConnVal()
if ( memcmp(&orig_l2_addr, &null, l2_len) != 0 )
orig_endp->Assign(5, make_intrusive<StringVal>(fmt_mac(orig_l2_addr, l2_len)));
auto resp_endp = make_intrusive<RecordVal>(endpoint);
auto resp_endp = make_intrusive<RecordVal>(zeek::id::endpoint);
resp_endp->Assign(0, val_mgr->Count(0));
resp_endp->Assign(1, val_mgr->Count(0));
resp_endp->Assign(4, val_mgr->Count(resp_flow_label));
@ -381,7 +379,7 @@ const IntrusivePtr<RecordVal>& Connection::ConnVal()
conn_val->Assign(1, std::move(orig_endp));
conn_val->Assign(2, std::move(resp_endp));
// 3 and 4 are set below.
conn_val->Assign(5, make_intrusive<TableVal>(IntrusivePtr{NewRef{}, string_set})); // service
conn_val->Assign(5, make_intrusive<TableVal>(zeek::id::string_set)); // service
conn_val->Assign(6, val_mgr->EmptyString()); // history
if ( ! uid )
@ -390,7 +388,7 @@ const IntrusivePtr<RecordVal>& Connection::ConnVal()
conn_val->Assign(7, make_intrusive<StringVal>(uid.Base62("C").c_str()));
if ( encapsulation && encapsulation->Depth() > 0 )
conn_val->Assign(8, encapsulation->GetVectorVal());
conn_val->Assign(8, encapsulation->ToVal());
if ( vlan != 0 )
conn_val->Assign(9, val_mgr->Int(vlan));
@ -432,7 +430,7 @@ void Connection::AppendAddl(const char* str)
{
const auto& cv = ConnVal();
const char* old = cv->Lookup(6)->AsString()->CheckString();
const char* old = cv->GetField(6)->AsString()->CheckString();
const char* format = *old ? "%s %s" : "%s%s";
cv->Assign(6, make_intrusive<StringVal>(fmt(format, old, str)));
@ -701,7 +699,7 @@ void Connection::CheckFlowLabel(bool is_orig, uint32_t flow_label)
{
if ( conn_val )
{
RecordVal *endp = conn_val->Lookup(is_orig ? 1 : 2)->AsRecordVal();
RecordVal* endp = conn_val->GetField(is_orig ? 1 : 2)->AsRecordVal();
endp->Assign(4, val_mgr->Count(flow_label));
}

View file

@ -36,7 +36,8 @@
#include "Event.h"
#include "Net.h"
#include "Val.h"
#include "Var.h"
#include "NetVar.h"
#include "ID.h"
#include "Reporter.h"
#include "IntrusivePtr.h"
#include "iosource/Manager.h"
@ -285,7 +286,7 @@ IntrusivePtr<ListVal> DNS_Mapping::Addrs()
auto addrs_val = make_intrusive<ListVal>(TYPE_ADDR);
for ( int i = 0; i < num_addrs; ++i )
addrs_val->Append(new AddrVal(addrs[i]));
addrs_val->Append(make_intrusive<AddrVal>(addrs[i]));
}
return addrs_val;
@ -297,7 +298,7 @@ IntrusivePtr<TableVal> DNS_Mapping::AddrsSet() {
if ( ! l )
return empty_addr_set();
return {AdoptRef{}, l->ConvertToSet()};
return l->ToSetVal();
}
IntrusivePtr<StringVal> DNS_Mapping::Host()
@ -380,12 +381,6 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode)
mode = arg_mode;
dns_mapping_valid = dns_mapping_unverified = dns_mapping_new_name =
dns_mapping_lost_name = dns_mapping_name_changed =
dns_mapping_altered = nullptr;
dm_rec = nullptr;
cache_name = dir = nullptr;
asyncs_pending = 0;
@ -455,14 +450,7 @@ void DNS_Mgr::InitSource()
void DNS_Mgr::InitPostScript()
{
dns_mapping_valid = internal_handler("dns_mapping_valid");
dns_mapping_unverified = internal_handler("dns_mapping_unverified");
dns_mapping_new_name = internal_handler("dns_mapping_new_name");
dns_mapping_lost_name = internal_handler("dns_mapping_lost_name");
dns_mapping_name_changed = internal_handler("dns_mapping_name_changed");
dns_mapping_altered = internal_handler("dns_mapping_altered");
dm_rec = internal_type("dns_mapping")->AsRecordType();
dm_rec = zeek::id::find_type<RecordType>("dns_mapping");
// Registering will call Init()
iosource_mgr->Register(this, true);
@ -478,8 +466,8 @@ static IntrusivePtr<TableVal> fake_name_lookup_result(const char* name)
hash128_t hash;
KeyedHash::StaticHash128(name, strlen(name), &hash);
auto hv = make_intrusive<ListVal>(TYPE_ADDR);
hv->Append(new AddrVal(reinterpret_cast<const uint32_t*>(&hash)));
return {AdoptRef{}, hv->ConvertToSet()};
hv->Append(make_intrusive<AddrVal>(reinterpret_cast<const uint32_t*>(&hash)));
return hv->ToSetVal();
}
static const char* fake_text_lookup_result(const char* name)
@ -715,11 +703,7 @@ void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm,
if ( ! e )
return;
mgr.Enqueue(e,
BuildMappingVal(dm),
IntrusivePtr{AdoptRef{}, l1->ConvertToSet()},
IntrusivePtr{AdoptRef{}, l2->ConvertToSet()}
);
mgr.Enqueue(e, BuildMappingVal(dm), l1->ToSetVal(), l2->ToSetVal());
}
void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm)
@ -740,7 +724,7 @@ IntrusivePtr<Val> DNS_Mgr::BuildMappingVal(DNS_Mapping* dm)
r->Assign(3, val_mgr->Bool(dm->Valid()));
auto h = dm->Host();
r->Assign(4, h ? h.release() : new StringVal("<none>"));
r->Assign(4, h ? std::move(h) : make_intrusive<StringVal>("<none>"));
r->Assign(5, dm->AddrsSet());
return r;
@ -892,19 +876,19 @@ IntrusivePtr<ListVal> DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2)
for ( int i = 0; i < al1->Length(); ++i )
{
const IPAddr& al1_i = al1->Index(i)->AsAddr();
const IPAddr& al1_i = al1->Idx(i)->AsAddr();
int j;
for ( j = 0; j < al2->Length(); ++j )
{
const IPAddr& al2_j = al2->Index(j)->AsAddr();
const IPAddr& al2_j = al2->Idx(j)->AsAddr();
if ( al1_i == al2_j )
break;
}
if ( j >= al2->Length() )
// Didn't find it.
delta->Append(al1->Index(i)->Ref());
delta->Append(al1->Idx(i));
}
return delta;
@ -914,7 +898,7 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al)
{
for ( int i = 0; i < al->Length(); ++i )
{
const IPAddr& al_i = al->Index(i)->AsAddr();
const IPAddr& al_i = al->Idx(i)->AsAddr();
fprintf(f, "%s%s", i > 0 ? "," : "", al_i.AsString().c_str());
}
}

View file

@ -149,15 +149,7 @@ protected:
bool did_init;
// DNS-related events.
EventHandlerPtr dns_mapping_valid;
EventHandlerPtr dns_mapping_unverified;
EventHandlerPtr dns_mapping_new_name;
EventHandlerPtr dns_mapping_lost_name;
EventHandlerPtr dns_mapping_name_changed;
EventHandlerPtr dns_mapping_altered;
RecordType* dm_rec;
IntrusivePtr<RecordType> dm_rec;
typedef std::list<LookupCallback*> CallbackList;

View file

@ -258,8 +258,8 @@ BreakCode DbgBreakpoint::HasHit()
return bcHit;
}
if ( ! IsIntegral(yes->Type()->Tag()) &&
! IsBool(yes->Type()->Tag()) )
if ( ! IsIntegral(yes->GetType()->Tag()) &&
! IsBool(yes->GetType()->Tag()) )
{
PrintHitMsg();
debug_msg("Breakpoint condition should return an integral type");

View file

@ -197,7 +197,7 @@ void get_first_statement(Stmt* list, Stmt*& first, Location& loc)
static void parse_function_name(vector<ParseLocationRec>& result,
ParseLocationRec& plr, const string& s)
{ // function name
auto id = lookup_ID(s.c_str(), current_module.c_str());
const auto& id = lookup_ID(s.c_str(), current_module.c_str());
if ( ! id )
{
@ -207,7 +207,7 @@ static void parse_function_name(vector<ParseLocationRec>& result,
return;
}
if ( ! id->Type()->AsFuncType() )
if ( ! id->GetType()->AsFuncType() )
{
debug_msg("Function %s not declared.\n", id->Name());
plr.type = plrUnknown;
@ -221,7 +221,7 @@ static void parse_function_name(vector<ParseLocationRec>& result,
return;
}
const Func* func = id->ID_Val()->AsFunc();
const Func* func = id->GetVal()->AsFunc();
const vector<Func::Body>& bodies = func->GetBodies();
if ( bodies.size() == 0 )

View file

@ -65,7 +65,7 @@ void lookup_global_symbols_regex(const string& orig_regex, vector<ID*>& matches,
for ( const auto& sym : syms )
{
ID* nextid = sym.second.get();
if ( ! func_only || nextid->Type()->Tag() == TYPE_FUNC )
if ( ! func_only || nextid->GetType()->Tag() == TYPE_FUNC )
if ( ! regexec (&re, nextid->Name(), 0, 0, 0) )
matches.push_back(nextid);
}

View file

@ -11,6 +11,7 @@
#include "File.h"
#include "Reporter.h"
#include "ConvertUTF.h"
#include "IPAddr.h"
#define DEFAULT_SIZE 128
#define SLOP 10

View file

@ -218,4 +218,6 @@ public:
{ return (T*) Dictionary::NextEntry(h, cookie, 1); }
T* RemoveEntry(const HashKey* key)
{ return (T*) Remove(key->Key(), key->Size(), key->Hash()); }
T* RemoveEntry(const HashKey& key)
{ return (T*) Remove(key.Key(), key.Size(), key.Hash()); }
};

View file

@ -16,12 +16,12 @@
Discarder::Discarder()
{
check_ip = internal_func("discarder_check_ip");
check_tcp = internal_func("discarder_check_tcp");
check_udp = internal_func("discarder_check_udp");
check_icmp = internal_func("discarder_check_icmp");
check_ip = zeek::id::find_func("discarder_check_ip");
check_tcp = zeek::id::find_func("discarder_check_tcp");
check_udp = zeek::id::find_func("discarder_check_udp");
check_icmp = zeek::id::find_func("discarder_check_icmp");
discarder_maxlen = static_cast<int>(opt_internal_int("discarder_maxlen"));
discarder_maxlen = static_cast<int>(zeek::id::find_val("discarder_maxlen")->AsCount());
}
Discarder::~Discarder()
@ -39,11 +39,11 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
if ( check_ip )
{
zeek::Args args{{AdoptRef{}, ip->BuildPktHdrVal()}};
zeek::Args args{ip->ToPktHdrVal()};
try
{
discard_packet = check_ip->Call(args)->AsBool();
discard_packet = check_ip->Invoke(&args)->AsBool();
}
catch ( InterpreterException& e )
@ -92,13 +92,13 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
int th_len = tp->th_off * 4;
zeek::Args args{
{AdoptRef{}, ip->BuildPktHdrVal()},
ip->ToPktHdrVal(),
{AdoptRef{}, BuildData(data, th_len, len, caplen)},
};
try
{
discard_packet = check_tcp->Call(args)->AsBool();
discard_packet = check_tcp->Invoke(&args)->AsBool();
}
catch ( InterpreterException& e )
@ -116,13 +116,13 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
int uh_len = sizeof (struct udphdr);
zeek::Args args{
{AdoptRef{}, ip->BuildPktHdrVal()},
ip->ToPktHdrVal(),
{AdoptRef{}, BuildData(data, uh_len, len, caplen)},
};
try
{
discard_packet = check_udp->Call(args)->AsBool();
discard_packet = check_udp->Invoke(&args)->AsBool();
}
catch ( InterpreterException& e )
@ -138,11 +138,11 @@ bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
{
const struct icmp* ih = (const struct icmp*) data;
zeek::Args args{{AdoptRef{}, ip->BuildPktHdrVal()}};
zeek::Args args{ip->ToPktHdrVal()};
try
{
discard_packet = check_icmp->Call(args)->AsBool();
discard_packet = check_icmp->Invoke(&args)->AsBool();
}
catch ( InterpreterException& e )

View file

@ -4,6 +4,8 @@
#include <sys/types.h> // for u_char
#include "IntrusivePtr.h"
class IP_Hdr;
class Val;
class Func;
@ -20,10 +22,10 @@ public:
protected:
Val* BuildData(const u_char* data, int hdrlen, int len, int caplen);
Func* check_ip;
Func* check_tcp;
Func* check_udp;
Func* check_icmp;
IntrusivePtr<Func> check_ip;
IntrusivePtr<Func> check_tcp;
IntrusivePtr<Func> check_udp;
IntrusivePtr<Func> check_icmp;
// Maximum amount of application data passed to filtering functions.
int discarder_maxlen;

View file

@ -56,7 +56,7 @@ void Event::Dispatch(bool no_remote)
try
{
handler->Call(args, no_remote);
handler->Call(&args, no_remote);
}
catch ( InterpreterException& e )

View file

@ -5,27 +5,20 @@
#include "Scope.h"
#include "NetVar.h"
#include "ID.h"
#include "Var.h"
#include "broker/Manager.h"
#include "broker/Data.h"
EventHandler::EventHandler(const char* arg_name)
EventHandler::EventHandler(std::string arg_name)
{
name = copy_string(arg_name);
name = std::move(arg_name);
used = false;
local = nullptr;
type = nullptr;
error_handler = false;
enabled = true;
generate_always = false;
}
EventHandler::~EventHandler()
{
Unref(local);
delete [] name;
}
EventHandler::operator bool() const
{
return enabled && ((local && local->HasBodies())
@ -33,34 +26,25 @@ EventHandler::operator bool() const
|| ! auto_publish.empty());
}
FuncType* EventHandler::FType(bool check_export)
const IntrusivePtr<FuncType>& EventHandler::GetType(bool check_export)
{
if ( type )
return type;
auto id = lookup_ID(name, current_module.c_str(), false, false,
const auto& id = lookup_ID(name.data(), current_module.c_str(), false, false,
check_export);
if ( ! id )
return nullptr;
return FuncType::nil;
if ( id->Type()->Tag() != TYPE_FUNC )
return nullptr;
if ( id->GetType()->Tag() != TYPE_FUNC )
return FuncType::nil;
type = id->Type()->AsFuncType();
type = id->GetType<FuncType>();
return type;
}
void EventHandler::SetLocalHandler(Func* f)
{
if ( local )
Unref(local);
Ref(f);
local = f;
}
void EventHandler::Call(const zeek::Args& vl, bool no_remote)
void EventHandler::Call(zeek::Args* vl, bool no_remote)
{
#ifdef PROFILE_BRO_FUNCTIONS
DEBUG_MSG("Event: %s\n", Name());
@ -75,12 +59,12 @@ void EventHandler::Call(const zeek::Args& vl, bool no_remote)
{
// Send event in form [name, xs...] where xs represent the arguments.
broker::vector xs;
xs.reserve(vl.size());
xs.reserve(vl->size());
bool valid_args = true;
for ( auto i = 0u; i < vl.size(); ++i )
for ( auto i = 0u; i < vl->size(); ++i )
{
auto opt_data = bro_broker::val_to_data(vl[i].get());
auto opt_data = bro_broker::val_to_data((*vl)[i].get());
if ( opt_data )
xs.emplace_back(std::move(*opt_data));
@ -114,10 +98,10 @@ void EventHandler::Call(const zeek::Args& vl, bool no_remote)
if ( local )
// No try/catch here; we pass exceptions upstream.
local->Call(vl);
local->Invoke(vl);
}
void EventHandler::NewEvent(const zeek::Args& vl)
void EventHandler::NewEvent(zeek::Args* vl)
{
if ( ! new_event )
return;
@ -126,15 +110,17 @@ void EventHandler::NewEvent(const zeek::Args& vl)
// new_event() is the one event we don't want to report.
return;
RecordType* args = FType()->Args();
const auto& args = GetType()->Params();
static auto call_argument_vector = zeek::id::find_type<VectorType>("call_argument_vector");
auto vargs = make_intrusive<VectorVal>(call_argument_vector);
for ( int i = 0; i < args->NumFields(); i++ )
{
const char* fname = args->FieldName(i);
BroType* ftype = args->FieldType(i);
const auto& ftype = args->GetFieldType(i);
auto fdefault = args->FieldDefault(i);
static auto call_argument = zeek::id::find_type<RecordType>("call_argument");
auto rec = make_intrusive<RecordVal>(call_argument);
rec->Assign(0, make_intrusive<StringVal>(fname));
@ -146,8 +132,8 @@ void EventHandler::NewEvent(const zeek::Args& vl)
if ( fdefault )
rec->Assign(2, std::move(fdefault));
if ( i < static_cast<int>(vl.size()) && vl[i] )
rec->Assign(3, vl[i]);
if ( i < static_cast<int>(vl->size()) && (*vl)[i] )
rec->Assign(3, (*vl)[i]);
vargs->Assign(i, std::move(rec));
}

View file

@ -4,23 +4,36 @@
#include "BroList.h"
#include "ZeekArgs.h"
#include "Type.h"
#include "Func.h"
#include <unordered_set>
#include <string>
class Func;
class FuncType;
class EventHandler {
public:
explicit EventHandler(const char* name);
~EventHandler();
explicit EventHandler(std::string name);
const char* Name() { return name; }
Func* LocalHandler() { return local; }
FuncType* FType(bool check_export = true);
const char* Name() { return name.data(); }
void SetLocalHandler(Func* f);
const IntrusivePtr<Func>& GetFunc()
{ return local; }
[[deprecated("Remove in v4.1. Use GetFunc().")]]
Func* LocalHandler() { return local.get(); }
const IntrusivePtr<FuncType>& GetType(bool check_export = true);
[[deprecated("Remove in v4.1. Use GetType().")]]
FuncType* FType(bool check_export = true)
{ return GetType().get(); }
void SetFunc(IntrusivePtr<Func> f)
{ local = std::move(f); }
[[deprecated("Remove in v4.1. Use SetFunc().")]]
void SetLocalHandler(Func* f)
{ SetFunc({NewRef{}, f}); }
void AutoPublish(std::string topic)
{
@ -32,7 +45,7 @@ public:
auto_publish.erase(topic);
}
void Call(const zeek::Args& vl, bool no_remote = false);
void Call(zeek::Args* vl, bool no_remote = false);
// Returns true if there is at least one local or remote handler.
explicit operator bool() const;
@ -53,11 +66,11 @@ public:
bool GenerateAlways() { return generate_always; }
private:
void NewEvent(const zeek::Args& vl); // Raise new_event() meta event.
void NewEvent(zeek::Args* vl); // Raise new_event() meta event.
const char* name;
Func* local;
FuncType* type;
std::string name;
IntrusivePtr<Func> local;
IntrusivePtr<FuncType> type;
bool used; // this handler is indeed used somewhere
bool enabled;
bool error_handler; // this handler reports error messages.

View file

@ -4,5 +4,6 @@
#include "Event.h"
#include "NetVar.h"
#include "Conn.h"
#include "File.h"
#include "event.bif.func_def"

View file

@ -6,12 +6,32 @@
EventRegistry::EventRegistry() = default;
EventRegistry::~EventRegistry() noexcept = default;
EventHandlerPtr EventRegistry::Register(std::string_view name)
{
// If there already is an entry in the registry, we have a
// local handler on the script layer.
EventHandler* h = event_registry->Lookup(name);
if ( h )
{
h->SetUsed();
return h;
}
h = new EventHandler(std::string(name));
event_registry->Register(h);
h->SetUsed();
return h;
}
void EventRegistry::Register(EventHandlerPtr handler)
{
handlers[std::string(handler->Name())] = std::unique_ptr<EventHandler>(handler.Ptr());
}
EventHandler* EventRegistry::Lookup(const std::string& name)
EventHandler* EventRegistry::Lookup(std::string_view name)
{
auto it = handlers.find(name);
if ( it != handlers.end() )
@ -27,7 +47,7 @@ EventRegistry::string_list EventRegistry::Match(RE_Matcher* pattern)
for ( const auto& entry : handlers )
{
EventHandler* v = entry.second.get();
if ( v->LocalHandler() && pattern->MatchExactly(v->Name()) )
if ( v->GetFunc() && pattern->MatchExactly(v->Name()) )
names.push_back(entry.first);
}
@ -41,7 +61,7 @@ EventRegistry::string_list EventRegistry::UnusedHandlers()
for ( const auto& entry : handlers )
{
EventHandler* v = entry.second.get();
if ( v->LocalHandler() && ! v->Used() )
if ( v->GetFunc() && ! v->Used() )
names.push_back(entry.first);
}
@ -55,7 +75,7 @@ EventRegistry::string_list EventRegistry::UsedHandlers()
for ( const auto& entry : handlers )
{
EventHandler* v = entry.second.get();
if ( v->LocalHandler() && v->Used() )
if ( v->GetFunc() && v->Used() )
names.push_back(entry.first);
}
@ -80,13 +100,13 @@ void EventRegistry::PrintDebug()
{
EventHandler* v = entry.second.get();
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
v->LocalHandler()? "local" : "no",
v->GetFunc() ? "local" : "no",
*v ? "active" : "not active"
);
}
}
void EventRegistry::SetErrorHandler(const std::string& name)
void EventRegistry::SetErrorHandler(std::string_view name)
{
EventHandler* eh = Lookup(name);
@ -97,6 +117,6 @@ void EventRegistry::SetErrorHandler(const std::string& name)
}
reporter->InternalWarning("unknown event handler '%s' in SetErrorHandler()",
name.c_str());
std::string(name).c_str());
}

View file

@ -5,6 +5,7 @@
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <vector>
class EventHandler;
@ -17,10 +18,18 @@ public:
EventRegistry();
~EventRegistry() noexcept;
/**
* Performs a lookup for an existing event handler and returns it
* if one exists, or else creates one, registers it, and returns it.
* @param name The name of the event handler to lookup/register.
* @return The event handler.
*/
EventHandlerPtr Register(std::string_view name);
void Register(EventHandlerPtr handler);
// Return nil if unknown.
EventHandler* Lookup(const std::string& name);
EventHandler* Lookup(std::string_view name);
// Returns a list of all local handlers that match the given pattern.
// Passes ownership of list.
@ -30,7 +39,7 @@ public:
// Marks a handler as handling errors. Error handler will not be called
// recursively to avoid infinite loops in case they trigger an error
// themselves.
void SetErrorHandler(const std::string& name);
void SetErrorHandler(std::string_view name);
string_list UnusedHandlers();
string_list UsedHandlers();
@ -39,7 +48,7 @@ public:
void PrintDebug();
private:
std::map<std::string, std::unique_ptr<EventHandler>> handlers;
std::map<std::string, std::unique_ptr<EventHandler>, std::less<>> handlers;
};
extern EventRegistry* event_registry;

File diff suppressed because it is too large Load diff

View file

@ -50,7 +50,6 @@ enum BroExprTag : int {
EXPR_TABLE_COERCE,
EXPR_VECTOR_COERCE,
EXPR_SIZE,
EXPR_FLATTEN,
EXPR_CAST,
EXPR_IS,
EXPR_INDEX_SLICE_ASSIGN,
@ -75,7 +74,16 @@ struct function_ingredients;
class Expr : public BroObj {
public:
[[deprecated("Remove in v4.1. Use GetType().")]]
BroType* Type() const { return type.get(); }
const IntrusivePtr<BroType>& GetType() const
{ return type; }
template <class T>
IntrusivePtr<T> GetType() const
{ return cast_intrusive<T>(type); }
BroExprTag Tag() const { return tag; }
Expr* Ref() { ::Ref(this); return this; }
@ -511,7 +519,8 @@ public:
// If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers.
AssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, bool is_init,
IntrusivePtr<Val> val = nullptr, attr_list* attrs = nullptr);
IntrusivePtr<Val> val = nullptr,
const IntrusivePtr<Attributes>& attrs = nullptr);
IntrusivePtr<Val> Eval(Frame* f) const override;
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
@ -521,7 +530,7 @@ public:
bool IsPure() const override;
protected:
bool TypeCheck(attr_list* attrs = nullptr);
bool TypeCheck(const IntrusivePtr<Attributes>& attrs = nullptr);
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
bool is_init;
@ -622,11 +631,15 @@ protected:
class TableConstructorExpr final : public UnaryExpr {
public:
TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs,
IntrusivePtr<BroType> arg_type = nullptr);
~TableConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
[[deprecated("Remove in v4.1. Use GetAttrs().")]]
Attributes* Attrs() { return attrs.get(); }
const IntrusivePtr<Attributes>& GetAttrs() const
{ return attrs; }
IntrusivePtr<Val> Eval(Frame* f) const override;
@ -635,16 +648,20 @@ protected:
void ExprDescribe(ODesc* d) const override;
Attributes* attrs;
IntrusivePtr<Attributes> attrs;
};
class SetConstructorExpr final : public UnaryExpr {
public:
SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs,
IntrusivePtr<BroType> arg_type = nullptr);
~SetConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
[[deprecated("Remove in v4.1. Use GetAttrs().")]]
Attributes* Attrs() { return attrs.get(); }
const IntrusivePtr<Attributes>& GetAttrs() const
{ return attrs; }
IntrusivePtr<Val> Eval(Frame* f) const override;
@ -653,7 +670,7 @@ protected:
void ExprDescribe(ODesc* d) const override;
Attributes* attrs;
IntrusivePtr<Attributes> attrs;
};
class VectorConstructorExpr final : public UnaryExpr {
@ -726,18 +743,6 @@ protected:
IntrusivePtr<Val> Fold(Val* v) const override;
};
// An internal operator for flattening array indices that are records
// into a list of individual values.
class FlattenExpr final : public UnaryExpr {
public:
explicit FlattenExpr(IntrusivePtr<Expr> op);
protected:
IntrusivePtr<Val> Fold(Val* v) const override;
int num_fields;
};
class ScheduleTimer final : public Timer {
public:
ScheduleTimer(const EventHandlerPtr& event, zeek::Args args, double t);
@ -945,5 +950,6 @@ std::optional<std::vector<IntrusivePtr<Val>>> eval_list(Frame* f, const ListExpr
// a canonical form.
extern bool expr_greater(const Expr* e1, const Expr* e2);
// True if the given Val* has a vector type
inline bool is_vector(Expr* e) { return e->Type()->Tag() == TYPE_VECTOR; }
// 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 IntrusivePtr<Expr>& e) { return is_vector(e.get()); }

View file

@ -29,6 +29,7 @@
#include "Event.h"
#include "Reporter.h"
#include "Desc.h"
#include "Var.h"
std::list<std::pair<std::string, BroFile*>> BroFile::open_files;
@ -264,7 +265,7 @@ void BroFile::SetAttrs(Attributes* arg_attrs)
attrs = arg_attrs;
Ref(attrs);
if ( attrs->FindAttr(ATTR_RAW_OUTPUT) )
if ( attrs->Find(ATTR_RAW_OUTPUT) )
EnableRawOutput();
}
@ -277,6 +278,7 @@ RecordVal* BroFile::Rotate()
if ( f == stdin || f == stdout || f == stderr )
return nullptr;
static auto rotate_info = zeek::id::find_type<RecordType>("rotate_info");
RecordVal* info = new RecordVal(rotate_info);
FILE* newf = rotate_file(name, info);
@ -326,8 +328,8 @@ void BroFile::RaiseOpenEvent()
if ( ! ::file_opened )
return;
Ref(this);
Event* event = new ::Event(::file_opened, {make_intrusive<Val>(this)});
IntrusivePtr<BroFile> bf{NewRef{}, this};
Event* event = new ::Event(::file_opened, {make_intrusive<Val>(std::move(bf))});
mgr.Dispatch(event, true);
}
@ -344,16 +346,11 @@ double BroFile::Size()
return s.st_size;
}
BroFile* BroFile::GetFile(const char* name)
IntrusivePtr<BroFile> BroFile::Get(const char* name)
{
for ( const auto &el : open_files )
{
if ( el.first == name )
{
Ref(el.second);
return el.second;
}
}
return {NewRef{}, el.second};
return new BroFile(name, "w");
return make_intrusive<BroFile>(name, "w");
}

View file

@ -37,8 +37,12 @@ public:
void SetBuf(bool buffered); // false=line buffered, true=fully buffered
[[deprecated("Remove in v4.1. Use GetType().")]]
BroType* FType() const { return t.get(); }
const IntrusivePtr<BroType>& GetType() const
{ return t; }
// Whether the file is open in a general sense; it might
// not be open as a Unix file due to our management of
// a finite number of FDs.
@ -63,7 +67,10 @@ public:
static void CloseOpenFiles();
// Get the file with the given name, opening it if it doesn't yet exist.
static BroFile* GetFile(const char* name);
static IntrusivePtr<BroFile> Get(const char* name);
[[deprecated("Remove in v4.1. Use BroFile::Get().")]]
static BroFile* GetFile(const char* name)
{ return Get(name).release(); }
void EnableRawOutput() { raw_output = true; }
bool IsRawOutput() const { return raw_output; }

View file

@ -17,7 +17,7 @@ std::vector<Frame*> g_frame_stack;
Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
{
size = arg_size;
frame = new Val*[size];
frame = std::make_unique<Element[]>(size);
function = func;
func_args = fn_args;
@ -29,9 +29,6 @@ Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
delayed = false;
closure = nullptr;
for (int i = 0; i < size; ++i)
frame[i] = nullptr;
}
Frame::~Frame()
@ -51,9 +48,8 @@ Frame::~Frame()
for ( auto& i : outer_ids )
Unref(i);
Release();
delete [] weak_refs;
for ( int i = 0; i < size; ++i )
ClearElement(i);
}
void Frame::AddFunctionWithClosureRef(BroFunc* func)
@ -66,37 +62,28 @@ void Frame::AddFunctionWithClosureRef(BroFunc* func)
functions_with_closure_frame_reference->emplace_back(func);
}
void Frame::SetElement(int n, Val* v, bool weak_ref)
{
UnrefElement(n);
frame[n] = v;
void Frame::SetElement(int n, Val* v)
{ SetElement(n, {AdoptRef{}, v}); }
if ( weak_ref )
void Frame::SetElement(int n, IntrusivePtr<Val> v)
{
if ( ! weak_refs )
{
weak_refs = new bool[size];
for ( auto i = 0; i < size; ++i )
weak_refs[i] = false;
ClearElement(n);
frame[n] = {std::move(v), false};
}
weak_refs[n] = true;
}
else
void Frame::SetElementWeak(int n, Val* v)
{
if ( weak_refs )
weak_refs[n] = false;
}
ClearElement(n);
frame[n] = {{AdoptRef{}, v}, true};
}
void Frame::SetElement(const ID* id, Val* v)
void Frame::SetElement(const ID* id, IntrusivePtr<Val> v)
{
if ( closure )
{
if ( IsOuterID(id) )
{
closure->SetElement(id, v);
closure->SetElement(id, std::move(v));
return;
}
}
@ -112,19 +99,19 @@ void Frame::SetElement(const ID* id, Val* v)
// id->Offset() below is otherwise responsible for keeping track
// of the implied reference count of the passed-in 'v' argument.
// i.e. if we end up storing it twice, we need an addition Ref.
SetElement(where->second, v->Ref());
SetElement(where->second, v);
}
}
SetElement(id->Offset(), v);
SetElement(id->Offset(), std::move(v));
}
Val* Frame::GetElement(const ID* id) const
const IntrusivePtr<Val>& Frame::GetElementByID(const ID* id) const
{
if ( closure )
{
if ( IsOuterID(id) )
return closure->GetElement(id);
return closure->GetElementByID(id);
}
// do we have an offset for it?
@ -132,27 +119,16 @@ Val* Frame::GetElement(const ID* id) const
{
auto where = offset_map->find(std::string(id->Name()));
if ( where != offset_map->end() )
return frame[where->second];
return frame[where->second].val;
}
return frame[id->Offset()];
return frame[id->Offset()].val;
}
void Frame::Reset(int startIdx)
{
for ( int i = startIdx; i < size; ++i )
{
UnrefElement(i);
frame[i] = nullptr;
}
}
void Frame::Release()
{
for ( int i = 0; i < size; ++i )
UnrefElement(i);
delete [] frame;
ClearElement(i);
}
void Frame::Describe(ODesc* d) const
@ -166,14 +142,14 @@ void Frame::Describe(ODesc* d) const
for ( int i = 0; i < size; ++i )
{
d->Add(frame[i] != nullptr);
d->Add(frame[i].val != nullptr);
d->SP();
}
}
for ( int i = 0; i < size; ++i )
if ( frame[i] )
frame[i]->Describe(d);
if ( frame[i].val )
frame[i].val->Describe(d);
else if ( d->IsReadable() )
d->Add("<nil>");
}
@ -190,36 +166,36 @@ Frame* Frame::Clone() const
other->call = call;
other->trigger = trigger;
for (int i = 0; i < size; i++)
other->frame[i] = frame[i] ? frame[i]->Clone().release() : nullptr;
for ( int i = 0; i < size; i++ )
if ( frame[i].val )
other->frame[i].val = frame[i].val->Clone();
return other;
}
static bool val_is_func(Val* v, BroFunc* func)
static bool val_is_func(const IntrusivePtr<Val>& v, BroFunc* func)
{
if ( v->Type()->Tag() != TYPE_FUNC )
if ( v->GetType()->Tag() != TYPE_FUNC )
return false;
return v->AsFunc() == func;
}
static void clone_if_not_func(Val** frame, int offset, BroFunc* func,
Frame* other)
void Frame::CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const
{
auto v = frame[offset];
const auto& v = frame[offset].val;
if ( ! v )
return;
if ( val_is_func(v, func) )
{
other->SetElement(offset, v, true);
other->SetElementWeak(offset, v.get());
return;
}
auto rval = v->Clone();
other->SetElement(offset, rval.release());
other->SetElement(offset, std::move(rval));
}
Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
@ -248,15 +224,15 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
auto where = offset_map->find(std::string(id->Name()));
if ( where != offset_map->end() )
{
clone_if_not_func(frame, where->second, func, other);
CloneNonFuncElement(where->second, func, other);
continue;
}
}
if ( ! frame[id->Offset()] )
if ( ! frame[id->Offset()].val )
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
clone_if_not_func(frame, id->Offset(), func, other);
CloneNonFuncElement(id->Offset(), func, other);
}
/**
@ -355,11 +331,11 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const id_li
if (where != new_map.end())
location = where->second;
Val* val = target->frame[location];
const auto& val = target->frame[location].val;
TypeTag tag = val->Type()->Tag();
TypeTag tag = val->GetType()->Tag();
auto expected = bro_broker::val_to_data(val);
auto expected = bro_broker::val_to_data(val.get());
if ( ! expected )
return broker::ec::invalid_data;
@ -490,7 +466,7 @@ std::pair<bool, IntrusivePtr<Frame>> Frame::Unserialize(const broker::vector& da
if ( ! val )
return std::make_pair(false, nullptr);
rf->frame[i] = val.release();
rf->frame[i].val = std::move(val);
}
return std::make_pair(true, std::move(rf));
@ -539,12 +515,12 @@ void Frame::ClearTrigger()
trigger = nullptr;
}
void Frame::UnrefElement(int n)
void Frame::ClearElement(int n)
{
if ( weak_refs && weak_refs[n] )
return;
Unref(frame[n]);
if ( frame[n].weak_ref )
frame[n].val.release();
else
frame[n] = {nullptr, false};
}
bool Frame::IsOuterID(const ID* in) const

View file

@ -11,6 +11,7 @@
#include <string>
#include <utility>
#include <vector>
#include <memory>
#include <broker/data.hh>
#include <broker/expected.hh>
@ -41,19 +42,21 @@ public:
* @param n the index to get.
* @return the value at index *n* of the underlying array.
*/
Val* NthElement(int n) const { return frame[n]; }
const IntrusivePtr<Val>& GetElement(int n) const
{ return frame[n].val; }
[[deprecated("Remove in v4.1. Use GetElement(int).")]]
Val* NthElement(int n) const { return frame[n].val.get(); }
/**
* Sets the element at index *n* of the underlying array
* to *v*.
*
* Sets the element at index *n* of the underlying array to *v*.
* @param n the index to set
* @param v the value to set it to
* @param weak_ref whether the frame owns the value and should unref
* it upon destruction. Used to break circular references between
* lambda functions and closure frames.
*/
void SetElement(int n, Val* v, bool weak_ref = false);
void SetElement(int n, IntrusivePtr<Val> v);
[[deprecated("Remove in v4.1. Pass IntrusivePtr instead.")]]
void SetElement(int n, Val* v);
/**
* Associates *id* and *v* in the frame. Future lookups of
@ -62,7 +65,9 @@ public:
* @param id the ID to associate
* @param v the value to associate it with
*/
void SetElement(const ID* id, Val* v);
void SetElement(const ID* id, IntrusivePtr<Val> v);
void SetElement(const IntrusivePtr<ID>& id, IntrusivePtr<Val> v)
{ SetElement(id.get(), std::move(v)); }
/**
* Gets the value associated with *id* and returns it. Returns
@ -71,22 +76,20 @@ public:
* @param id the id who's value to retreive
* @return the value associated with *id*
*/
Val* GetElement(const ID* id) const;
const IntrusivePtr<Val>& GetElementByID(const IntrusivePtr<ID>& id) const
{ return GetElementByID(id.get()); }
[[deprecated("Remove in v4.1. Use GetElementByID().")]]
Val* GetElement(const ID* id) const
{ return GetElementByID(id).get(); }
/**
* Resets all of the indexes from [*startIdx, frame_size) in
* the Frame. Unrefs all of the values in reset indexes.
*
* the Frame.
* @param the first index to unref.
*/
void Reset(int startIdx);
/**
* Resets all of the values in the frame and clears out the
* underlying array.
*/
void Release();
/**
* Describes the frame and all of its values.
*/
@ -236,10 +239,37 @@ private:
using OffsetMap = std::unordered_map<std::string, int>;
struct Element {
IntrusivePtr<Val> val;
// Weak reference is used to prevent circular reference memory leaks
// in lambdas/closures.
bool weak_ref;
};
const IntrusivePtr<Val>& GetElementByID(const ID* id) const;
/**
* Unrefs the value at offset 'n' frame unless it's a weak reference.
* Sets the element at index *n* of the underlying array to *v*, but does
* not take ownership of a reference count to it. This method is used to
* break circular references between lambda functions and closure frames.
* @param n the index to set
* @param v the value to set it to (caller has not Ref'd and Frame will
* not Unref it)
*/
void UnrefElement(int n);
void SetElementWeak(int n, Val* v);
/**
* Clone an element at an offset into other frame if not equal to a given
* function (in that case just assigna weak reference). Used to break
* circular references between lambda functions and closure frames.
*/
void CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const;
/**
* Resets the value at offset 'n' frame (by decrementing reference
* count if not a weak reference).
*/
void ClearElement(int n);
/** Have we captured this id? */
bool IsOuterID(const ID* in) const;
@ -269,11 +299,7 @@ private:
bool delayed;
/** Associates ID's offsets with values. */
Val** frame;
/** Values that are weakly referenced by the frame. Used to
* prevent circular reference memory leaks in lambda/closures */
bool* weak_refs = nullptr;
std::unique_ptr<Element[]> frame;
/** The enclosing frame of this frame. */
Frame* closure;

View file

@ -59,8 +59,7 @@ extern RETSIGTYPE sig_handler(int signo);
std::vector<CallInfo> call_stack;
bool did_builtin_init = false;
std::vector<Func*> Func::unique_ids;
static const std::pair<bool, Val*> empty_hook_result(false, NULL);
static const std::pair<bool, IntrusivePtr<Val>> empty_hook_result(false, nullptr);
std::string render_call_stack()
{
@ -111,18 +110,19 @@ std::string render_call_stack()
Func::Func()
{
unique_id = unique_ids.size();
unique_ids.push_back(this);
unique_ids.push_back({NewRef{}, this});
}
Func::Func(Kind arg_kind) : kind(arg_kind)
{
unique_id = unique_ids.size();
unique_ids.push_back(this);
unique_ids.push_back({NewRef{}, this});
}
Func::~Func() = default;
void Func::AddBody(IntrusivePtr<Stmt> /* new_body */, id_list* /* new_inits */,
void Func::AddBody(IntrusivePtr<Stmt> /* new_body */,
const std::vector<IntrusivePtr<ID>>& /* new_inits */,
size_t /* new_frame_size */, int /* priority */)
{
Internal("Func::AddBody called");
@ -147,7 +147,7 @@ void Func::DescribeDebug(ODesc* d, const zeek::Args* args) const
if ( args )
{
d->Add("(");
RecordType* func_args = FType()->Args();
const auto& func_args = GetType()->Params();
auto num_fields = static_cast<size_t>(func_args->NumFields());
for ( auto i = 0u; i < args->size(); ++i )
@ -215,63 +215,66 @@ void Func::CopyStateInto(Func* other) const
other->unique_id = unique_id;
}
std::pair<bool, Val*> Func::HandlePluginResult(std::pair<bool, Val*> plugin_result, function_flavor flavor) const
void Func::CheckPluginResult(bool handled, const IntrusivePtr<Val>& hook_result,
function_flavor flavor) const
{
// Helper function factoring out this code from BroFunc:Call() for
// better readability.
if( ! plugin_result.first )
if ( ! handled )
{
if( plugin_result.second )
if ( hook_result )
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 plugin_result;
return;
}
switch ( flavor ) {
case FUNC_FLAVOR_EVENT:
if( plugin_result.second )
reporter->InternalError("plugin returned non-void result for event %s", this->Name());
if ( hook_result )
reporter->InternalError("plugin returned non-void result for event %s",
this->Name());
break;
case FUNC_FLAVOR_HOOK:
if ( plugin_result.second->Type()->Tag() != TYPE_BOOL )
reporter->InternalError("plugin returned non-bool for hook %s", this->Name());
if ( hook_result->GetType()->Tag() != TYPE_BOOL )
reporter->InternalError("plugin returned non-bool for hook %s",
this->Name());
break;
case FUNC_FLAVOR_FUNCTION:
{
BroType* yt = FType()->YieldType();
const auto& yt = GetType()->Yield();
if ( (! yt) || yt->Tag() == TYPE_VOID )
{
if( plugin_result.second )
reporter->InternalError("plugin returned non-void result for void method %s", this->Name());
if ( hook_result )
reporter->InternalError("plugin returned non-void result for void method %s",
this->Name());
}
else if ( plugin_result.second && plugin_result.second->Type()->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",
plugin_result.second->Type()->Tag(), yt->Tag(), this->Name());
hook_result->GetType()->Tag(), yt->Tag(), this->Name());
}
break;
}
}
return plugin_result;
}
BroFunc::BroFunc(ID* arg_id, IntrusivePtr<Stmt> arg_body, id_list* aggr_inits,
BroFunc::BroFunc(const IntrusivePtr<ID>& arg_id, IntrusivePtr<Stmt> arg_body,
const std::vector<IntrusivePtr<ID>>& aggr_inits,
size_t arg_frame_size, int priority)
: Func(BRO_FUNC)
{
name = arg_id->Name();
type = {NewRef{}, arg_id->Type()};
type = arg_id->GetType<FuncType>();
frame_size = arg_frame_size;
if ( arg_body )
@ -295,12 +298,13 @@ bool BroFunc::IsPure() const
[](const Body& b) { return b.stmts->IsPure(); });
}
IntrusivePtr<Val> Func::Call(val_list* args, Frame* parent) const
Val* Func::Call(val_list* args, Frame* parent) const
{
return Call(zeek::val_list_to_args(*args), parent);
}
auto zargs = zeek::val_list_to_args(*args);
return Invoke(&zargs, parent).release();
};
IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
IntrusivePtr<Val> BroFunc::Invoke(zeek::Args* args, Frame* parent) const
{
#ifdef PROFILE_BRO_FUNCTIONS
DEBUG_MSG("Function: %s\n", Name());
@ -310,12 +314,14 @@ IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
if ( sample_logger )
sample_logger->FunctionSeen(this);
std::pair<bool, Val*> plugin_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);
plugin_result = HandlePluginResult(plugin_result, Flavor());
CheckPluginResult(handled, hook_result, Flavor());
if( plugin_result.first )
return {AdoptRef{}, plugin_result.second};
if ( handled )
return hook_result;
if ( bodies.empty() )
{
@ -324,7 +330,7 @@ IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
return Flavor() == FUNC_FLAVOR_HOOK ? val_mgr->True() : nullptr;
}
auto f = make_intrusive<Frame>(frame_size, this, &args);
auto f = make_intrusive<Frame>(frame_size, this, args);
if ( closure )
f->CaptureClosure(closure, outer_ids);
@ -338,15 +344,15 @@ IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
g_frame_stack.push_back(f.get()); // used for backtracing
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
call_stack.emplace_back(CallInfo{call_expr, this, args});
call_stack.emplace_back(CallInfo{call_expr, this, *args});
if ( g_trace_state.DoTrace() )
{
ODesc d;
DescribeDebug(&d, &args);
DescribeDebug(&d, args);
g_trace_state.LogTrace("%s called: %s\n",
FType()->FlavorString().c_str(), d.Description());
GetType()->FlavorString().c_str(), d.Description());
}
stmt_flow_type flow = FLOW_NEXT;
@ -359,16 +365,16 @@ IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
body.stmts->GetLocationInfo());
// Fill in the rest of the frame with the function's arguments.
for ( auto j = 0u; j < args.size(); ++j )
for ( auto j = 0u; j < args->size(); ++j )
{
Val* arg = args[j].get();
const auto& arg = (*args)[j];
if ( f->NthElement(j) != arg )
if ( f->GetElement(j) != arg )
// Either not yet set, or somebody reassigned the frame slot.
f->SetElement(j, arg->Ref());
f->SetElement(j, arg);
}
f->Reset(args.size());
f->Reset(args->size());
try
{
@ -423,7 +429,7 @@ IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
// Warn if the function returns something, but we returned from
// the function without an explicit return, or without a value.
else if ( FType()->YieldType() && FType()->YieldType()->Tag() != TYPE_VOID &&
else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID &&
(flow != FLOW_RETURN /* we fell off the end */ ||
! result /* explicit return with no result */) &&
! f->HasDelayed() )
@ -443,13 +449,14 @@ IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
return result;
}
void BroFunc::AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
void BroFunc::AddBody(IntrusivePtr<Stmt> new_body,
const std::vector<IntrusivePtr<ID>>& new_inits,
size_t new_frame_size, int priority)
{
if ( new_frame_size > frame_size )
frame_size = new_frame_size;
auto num_args = FType()->Args()->NumFields();
auto num_args = GetType()->Params()->NumFields();
if ( num_args > static_cast<int>(frame_size) )
frame_size = num_args;
@ -567,9 +574,10 @@ void BroFunc::Describe(ODesc* d) const
}
}
IntrusivePtr<Stmt> BroFunc::AddInits(IntrusivePtr<Stmt> body, id_list* inits)
IntrusivePtr<Stmt> BroFunc::AddInits(IntrusivePtr<Stmt> body,
const std::vector<IntrusivePtr<ID>>& inits)
{
if ( ! inits || inits->length() == 0 )
if ( inits.empty() )
return body;
auto stmt_series = make_intrusive<StmtList>();
@ -587,14 +595,14 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
name = make_full_var_name(GLOBAL_MODULE_NAME, arg_name);
is_pure = arg_is_pure;
auto id = lookup_ID(Name(), GLOBAL_MODULE_NAME, false);
const auto& id = lookup_ID(Name(), GLOBAL_MODULE_NAME, false);
if ( ! id )
reporter->InternalError("built-in function %s missing", Name());
if ( id->HasVal() )
reporter->InternalError("built-in function %s multiply defined", Name());
type = {NewRef{}, id->Type()};
id->SetVal(make_intrusive<Val>(this));
type = id->GetType<FuncType>();
id->SetVal(make_intrusive<Val>(IntrusivePtr{NewRef{}, this}));
}
BuiltinFunc::~BuiltinFunc()
@ -606,7 +614,7 @@ bool BuiltinFunc::IsPure() const
return is_pure;
}
IntrusivePtr<Val> BuiltinFunc::Call(const zeek::Args& args, Frame* parent) const
IntrusivePtr<Val> BuiltinFunc::Invoke(zeek::Args* args, Frame* parent) const
{
#ifdef PROFILE_BRO_FUNCTIONS
DEBUG_MSG("Function: %s\n", Name());
@ -616,24 +624,26 @@ IntrusivePtr<Val> BuiltinFunc::Call(const zeek::Args& args, Frame* parent) const
if ( sample_logger )
sample_logger->FunctionSeen(this);
std::pair<bool, Val*> plugin_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);
plugin_result = HandlePluginResult(plugin_result, FUNC_FLAVOR_FUNCTION);
CheckPluginResult(handled, hook_result, FUNC_FLAVOR_FUNCTION);
if ( plugin_result.first )
return {AdoptRef{}, plugin_result.second};
if ( handled )
return hook_result;
if ( g_trace_state.DoTrace() )
{
ODesc d;
DescribeDebug(&d, &args);
DescribeDebug(&d, args);
g_trace_state.LogTrace("\tBuiltin Function called: %s\n", d.Description());
}
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
call_stack.emplace_back(CallInfo{call_expr, this, args});
auto result = std::move(func(parent, &args).rval);
call_stack.emplace_back(CallInfo{call_expr, this, *args});
auto result = std::move(func(parent, args).rval);
call_stack.pop_back();
if ( result && g_trace_state.DoTrace() )
@ -748,21 +758,21 @@ void builtin_error(const char* msg, BroObj* arg)
void init_builtin_funcs()
{
ProcStats = internal_type("ProcStats")->AsRecordType();
NetStats = internal_type("NetStats")->AsRecordType();
MatcherStats = internal_type("MatcherStats")->AsRecordType();
ConnStats = internal_type("ConnStats")->AsRecordType();
ReassemblerStats = internal_type("ReassemblerStats")->AsRecordType();
DNSStats = internal_type("DNSStats")->AsRecordType();
GapStats = internal_type("GapStats")->AsRecordType();
EventStats = internal_type("EventStats")->AsRecordType();
TimerStats = internal_type("TimerStats")->AsRecordType();
FileAnalysisStats = internal_type("FileAnalysisStats")->AsRecordType();
ThreadStats = internal_type("ThreadStats")->AsRecordType();
BrokerStats = internal_type("BrokerStats")->AsRecordType();
ReporterStats = internal_type("ReporterStats")->AsRecordType();
ProcStats = zeek::id::find_type<RecordType>("ProcStats");
NetStats = zeek::id::find_type<RecordType>("NetStats");
MatcherStats = zeek::id::find_type<RecordType>("MatcherStats");
ConnStats = zeek::id::find_type<RecordType>("ConnStats");
ReassemblerStats = zeek::id::find_type<RecordType>("ReassemblerStats");
DNSStats = zeek::id::find_type<RecordType>("DNSStats");
GapStats = zeek::id::find_type<RecordType>("GapStats");
EventStats = zeek::id::find_type<RecordType>("EventStats");
TimerStats = zeek::id::find_type<RecordType>("TimerStats");
FileAnalysisStats = zeek::id::find_type<RecordType>("FileAnalysisStats");
ThreadStats = zeek::id::find_type<RecordType>("ThreadStats");
BrokerStats = zeek::id::find_type<RecordType>("BrokerStats");
ReporterStats = zeek::id::find_type<RecordType>("ReporterStats");
var_sizes = internal_type("var_sizes")->AsTableType();
var_sizes = zeek::id::find_type("var_sizes")->AsTableType();
#include "zeek.bif.func_init"
#include "stats.bif.func_init"
@ -781,7 +791,7 @@ void init_builtin_funcs_subdirs()
bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
{
if ( f->TheFunc() != BifFunc::bro_fmt )
if ( f->TheFunc() != zeek::BifFunc::fmt_bif)
return true;
const expr_list& args = call->Args()->Exprs();
@ -793,7 +803,7 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
}
const Expr* fmt_str_arg = args[0];
if ( fmt_str_arg->Type()->Tag() != TYPE_STRING )
if ( fmt_str_arg->GetType()->Tag() != TYPE_STRING )
{
call->Error("first argument to fmt() needs to be a format string");
return false;
@ -834,7 +844,7 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
// Gets a function's priority from its Scope's attributes. Errors if it sees any
// problems.
static int get_func_priority(const attr_list& attrs)
static int get_func_priority(const std::vector<IntrusivePtr<Attr>>& attrs)
{
int priority = 0;
@ -849,7 +859,7 @@ static int get_func_priority(const attr_list& attrs)
continue;
}
auto v = a->AttrExpr()->Eval(nullptr);
auto v = a->GetExpr()->Eval(nullptr);
if ( ! v )
{
@ -857,7 +867,7 @@ static int get_func_priority(const attr_list& attrs)
continue;
}
if ( ! IsIntegral(v->Type()->Tag()) )
if ( ! IsIntegral(v->GetType()->Tag()) )
{
a->Error("expression is not of integral type");
continue;
@ -875,22 +885,14 @@ function_ingredients::function_ingredients(IntrusivePtr<Scope> scope, IntrusiveP
inits = scope->GetInits();
this->scope = std::move(scope);
id = {NewRef{}, this->scope->ScopeID()};
id = this->scope->GetID();
auto attrs = this->scope->Attrs();
const auto& attrs = this->scope->Attrs();
priority = (attrs ? get_func_priority(*attrs) : 0);
this->body = std::move(body);
}
function_ingredients::~function_ingredients()
{
for ( const auto& i : *inits )
Unref(i);
delete inits;
}
BifReturnVal::BifReturnVal(std::nullptr_t) noexcept
{ }

View file

@ -30,6 +30,8 @@ class Scope;
class Func : public BroObj {
public:
static inline const IntrusivePtr<Func> nil;
enum Kind { BRO_FUNC, BUILTIN_FUNC };
explicit Func(Kind arg_kind);
@ -37,7 +39,7 @@ public:
~Func() override;
virtual bool IsPure() const = 0;
function_flavor Flavor() const { return FType()->Flavor(); }
function_flavor Flavor() const { return GetType()->Flavor(); }
struct Body {
IntrusivePtr<Stmt> stmts;
@ -49,8 +51,8 @@ public:
const std::vector<Body>& GetBodies() const { return bodies; }
bool HasBodies() const { return bodies.size(); }
[[deprecated("Remove in v4.1. Use zeek::Args overload instead.")]]
virtual IntrusivePtr<Val> Call(val_list* args, Frame* parent = nullptr) const;
[[deprecated("Remove in v4.1. Use Invoke() instead.")]]
Val* Call(val_list* args, Frame* parent = nullptr) const;
/**
* Calls a Zeek function.
@ -58,27 +60,36 @@ public:
* @param parent the frame from which the function is being called.
* @return the return value of the function call.
*/
virtual IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent = nullptr) const = 0;
virtual IntrusivePtr<Val> Invoke(zeek::Args* args,
Frame* parent = nullptr) const = 0;
/**
* A version of Call() taking a variable number of individual arguments.
* 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...>>,
IntrusivePtr<Val>>,
IntrusivePtr<Val>>
Call(Args&&... args) const
{ return Call(zeek::Args{std::forward<Args>(args)...}); }
Invoke(Args&&... args) const
{
auto zargs = zeek::Args{std::forward<Args>(args)...};
return Invoke(&zargs);
}
// Add a new event handler to an existing function (event).
virtual void AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
virtual void AddBody(IntrusivePtr<Stmt> new_body,
const std::vector<IntrusivePtr<ID>>& new_inits,
size_t new_frame_size, int priority = 0);
virtual void SetScope(IntrusivePtr<Scope> newscope);
virtual Scope* GetScope() const { return scope.get(); }
virtual FuncType* FType() const { return type->AsFuncType(); }
[[deprecated("Remove in v4.1. Use GetType().")]]
virtual FuncType* FType() const { return type.get(); }
const IntrusivePtr<FuncType>& GetType() const
{ return type; }
Kind GetKind() const { return kind; }
@ -93,8 +104,8 @@ public:
virtual TraversalCode Traverse(TraversalCallback* cb) const;
uint32_t GetUniqueFuncID() const { return unique_id; }
static Func* GetFuncPtrByID(uint32_t id)
{ return id >= unique_ids.size() ? nullptr : unique_ids[id]; }
static const IntrusivePtr<Func>& GetFuncPtrByID(uint32_t id)
{ return id >= unique_ids.size() ? Func::nil : unique_ids[id]; }
protected:
Func();
@ -102,26 +113,30 @@ protected:
// Copies this function's state into other.
void CopyStateInto(Func* other) const;
// Helper function for handling result of plugin hook.
std::pair<bool, Val*> HandlePluginResult(std::pair<bool, Val*> plugin_result, function_flavor flavor) const;
// Helper function for checking result of plugin hook.
void CheckPluginResult(bool handled, const IntrusivePtr<Val>& hook_result,
function_flavor flavor) const;
std::vector<Body> bodies;
IntrusivePtr<Scope> scope;
Kind kind;
uint32_t unique_id;
IntrusivePtr<BroType> type;
IntrusivePtr<FuncType> type;
std::string name;
static std::vector<Func*> unique_ids;
static inline std::vector<IntrusivePtr<Func>> unique_ids;
};
class BroFunc final : public Func {
public:
BroFunc(ID* id, IntrusivePtr<Stmt> body, id_list* inits, size_t frame_size, int priority);
BroFunc(const IntrusivePtr<ID>& id, IntrusivePtr<Stmt> body,
const std::vector<IntrusivePtr<ID>>& inits,
size_t frame_size, int priority);
~BroFunc() override;
bool IsPure() const override;
IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent) const override;
IntrusivePtr<Val> Invoke(zeek::Args* args, Frame* parent) const override;
/**
* Adds adds a closure to the function. Closures are cloned and
@ -152,7 +167,8 @@ public:
*/
broker::expected<broker::data> SerializeClosure() const;
void AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
void AddBody(IntrusivePtr<Stmt> new_body,
const std::vector<IntrusivePtr<ID>>& new_inits,
size_t new_frame_size, int priority) override;
/** Sets this function's outer_id list. */
@ -163,7 +179,8 @@ public:
protected:
BroFunc() : Func(BRO_FUNC) {}
IntrusivePtr<Stmt> AddInits(IntrusivePtr<Stmt> body, id_list* inits);
IntrusivePtr<Stmt> AddInits(IntrusivePtr<Stmt> body,
const std::vector<IntrusivePtr<ID>>& inits);
/**
* Clones this function along with its closures.
@ -206,10 +223,6 @@ public:
[[deprecated("Remove in v4.1. Return an IntrusivePtr instead.")]]
BifReturnVal(Val* v) noexcept;
private:
friend class BuiltinFunc;
IntrusivePtr<Val> rval;
};
@ -221,7 +234,7 @@ public:
~BuiltinFunc() override;
bool IsPure() const override;
IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent) const override;
IntrusivePtr<Val> Invoke(zeek::Args* args, Frame* parent) const override;
built_in_func TheFunc() const { return func; }
void Describe(ODesc* d) const override;
@ -256,11 +269,9 @@ struct function_ingredients {
// to build a function.
function_ingredients(IntrusivePtr<Scope> scope, IntrusivePtr<Stmt> body);
~function_ingredients();
IntrusivePtr<ID> id;
IntrusivePtr<Stmt> body;
id_list* inits;
std::vector<IntrusivePtr<ID>> inits;
int frame_size;
int priority;
IntrusivePtr<Scope> scope;

View file

@ -40,7 +40,7 @@ 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, zeek::BifConst::digest_salt->Bytes(), zeek::BifConst::digest_salt->Len(), reinterpret_cast<unsigned char*>(cluster_highwayhash_key));
}
hash64_t KeyedHash::Hash64(const void* bytes, uint64_t size)

View file

@ -30,8 +30,8 @@ class BroString;
class Val;
class Frame;
class BifReturnVal;
namespace BifFunc {
extern BifReturnVal bro_md5_hmac(Frame* frame, const zeek::Args*);
namespace zeek::BifFunc {
extern BifReturnVal md5_hmac_bif(Frame* frame, const zeek::Args*);
}
typedef uint64_t hash_t;
@ -196,7 +196,7 @@ private:
inline static bool seeds_initialized = false;
friend void hmac_md5(size_t size, const unsigned char* bytes, unsigned char digest[16]);
friend BifReturnVal BifFunc::bro_md5_hmac(Frame* frame, const zeek::Args*);
friend BifReturnVal zeek::BifFunc::md5_hmac_bif(Frame* frame, const zeek::Args*);
};
typedef enum {

162
src/ID.cc
View file

@ -19,20 +19,101 @@
#include "zeekygen/ScriptInfo.h"
#include "module_util.h"
IntrusivePtr<RecordType> zeek::id::conn_id;
IntrusivePtr<RecordType> zeek::id::endpoint;
IntrusivePtr<RecordType> zeek::id::connection;
IntrusivePtr<RecordType> zeek::id::fa_file;
IntrusivePtr<RecordType> zeek::id::fa_metadata;
IntrusivePtr<EnumType> zeek::id::transport_proto;
IntrusivePtr<TableType> zeek::id::string_set;
IntrusivePtr<TableType> zeek::id::string_array;
IntrusivePtr<TableType> zeek::id::count_set;
IntrusivePtr<VectorType> zeek::id::string_vec;
IntrusivePtr<VectorType> zeek::id::index_vec;
const IntrusivePtr<ID>& zeek::id::find(std::string_view name)
{
return global_scope()->Find(name);
}
const IntrusivePtr<BroType>& zeek::id::find_type(std::string_view name)
{
auto id = global_scope()->Find(name);
if ( ! id )
reporter->InternalError("Failed to find type named: %s",
std::string(name).data());
return id->GetType();
}
const IntrusivePtr<Val>& zeek::id::find_val(std::string_view name)
{
auto id = global_scope()->Find(name);
if ( ! id )
reporter->InternalError("Failed to find variable named: %s",
std::string(name).data());
return id->GetVal();
}
const IntrusivePtr<Val>& zeek::id::find_const(std::string_view name)
{
auto id = global_scope()->Find(name);
if ( ! id )
reporter->InternalError("Failed to find variable named: %s",
std::string(name).data());
if ( ! id->IsConst() )
reporter->InternalError("Variable is not 'const', but expected to be: %s",
std::string(name).data());
return id->GetVal();
}
IntrusivePtr<Func> zeek::id::find_func(std::string_view name)
{
const auto& v = zeek::id::find_val(name);
if ( ! v )
return nullptr;
if ( ! IsFunc(v->GetType()->Tag()) )
reporter->InternalError("Expected variable '%s' to be a function",
std::string(name).data());
return v->AsFuncPtr();
}
void zeek::id::detail::init()
{
conn_id = zeek::id::find_type<RecordType>("conn_id");
endpoint = zeek::id::find_type<RecordType>("endpoint");
connection = zeek::id::find_type<RecordType>("connection");
fa_file = zeek::id::find_type<RecordType>("fa_file");
fa_metadata = zeek::id::find_type<RecordType>("fa_metadata");
transport_proto = zeek::id::find_type<EnumType>("transport_proto");
string_set = zeek::id::find_type<TableType>("string_set");
string_array = zeek::id::find_type<TableType>("string_array");
count_set = zeek::id::find_type<TableType>("count_set");
string_vec = zeek::id::find_type<VectorType>("string_vec");
index_vec = zeek::id::find_type<VectorType>("index_vec");
}
ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
{
name = copy_string(arg_name);
scope = arg_scope;
is_export = arg_is_export;
is_option = false;
val = nullptr;
is_const = false;
is_enum_const = false;
is_type = false;
offset = 0;
infer_return_type = false;
weak_ref = false;
SetLocationInfo(&start_location, &end_location);
}
@ -40,9 +121,6 @@ ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
ID::~ID()
{
delete [] name;
if ( ! weak_ref )
Unref(val);
}
std::string ID::ModuleName() const
@ -57,19 +135,12 @@ void ID::SetType(IntrusivePtr<BroType> t)
void ID::ClearVal()
{
if ( ! weak_ref )
Unref(val);
val = nullptr;
}
void ID::SetVal(IntrusivePtr<Val> v, bool arg_weak_ref)
void ID::SetVal(IntrusivePtr<Val> v)
{
if ( ! weak_ref )
Unref(val);
val = v.release();
weak_ref = arg_weak_ref;
val = std::move(v);
Modified();
#ifdef DEBUG
@ -84,14 +155,14 @@ void ID::SetVal(IntrusivePtr<Val> v, bool arg_weak_ref)
if ( ! handler )
{
handler = new EventHandler(name);
handler->SetLocalHandler(val->AsFunc());
handler->SetFunc(val->AsFuncPtr());
event_registry->Register(handler);
}
else
{
// Otherwise, internally defined events cannot
// have local handler.
handler->SetLocalHandler(val->AsFunc());
handler->SetFunc(val->AsFuncPtr());
}
}
}
@ -124,30 +195,29 @@ void ID::SetVal(IntrusivePtr<Val> v, init_class c)
return;
}
else
v->AddTo(val, false);
v->AddTo(val.get(), false);
}
else
{
if ( val )
v->RemoveFrom(val);
v->RemoveFrom(val.get());
}
}
}
void ID::SetVal(IntrusivePtr<Expr> ev, init_class c)
{
Attr* a = attrs->FindAttr(c == INIT_EXTRA ?
ATTR_ADD_FUNC : ATTR_DEL_FUNC);
const auto& a = attrs->Find(c == INIT_EXTRA ? ATTR_ADD_FUNC : ATTR_DEL_FUNC);
if ( ! a )
Internal("no add/delete function in ID::SetVal");
EvalFunc({NewRef{}, a->AttrExpr()}, std::move(ev));
EvalFunc(a->GetExpr(), std::move(ev));
}
bool ID::IsRedefinable() const
{
return FindAttr(ATTR_REDEF) != nullptr;
return GetAttr(ATTR_REDEF) != nullptr;
}
void ID::SetAttrs(IntrusivePtr<Attributes> a)
@ -161,33 +231,34 @@ void ID::UpdateValAttrs()
if ( ! attrs )
return;
if ( val && val->Type()->Tag() == TYPE_TABLE )
if ( val && val->GetType()->Tag() == TYPE_TABLE )
val->AsTableVal()->SetAttrs(attrs);
if ( val && val->Type()->Tag() == TYPE_FILE )
if ( val && val->GetType()->Tag() == TYPE_FILE )
val->AsFile()->SetAttrs(attrs.get());
if ( Type()->Tag() == TYPE_FUNC )
if ( GetType()->Tag() == TYPE_FUNC )
{
Attr* attr = attrs->FindAttr(ATTR_ERROR_HANDLER);
const auto& attr = attrs->Find(ATTR_ERROR_HANDLER);
if ( attr )
event_registry->SetErrorHandler(Name());
}
if ( Type()->Tag() == TYPE_RECORD )
if ( GetType()->Tag() == TYPE_RECORD )
{
Attr* attr = attrs->FindAttr(ATTR_LOG);
const auto& attr = attrs->Find(ATTR_LOG);
if ( attr )
{
// Apply &log to all record fields.
RecordType* rt = Type()->AsRecordType();
RecordType* rt = GetType()->AsRecordType();
for ( int i = 0; i < rt->NumFields(); ++i )
{
TypeDecl* fd = rt->FieldDecl(i);
if ( ! fd->attrs )
fd->attrs = make_intrusive<Attributes>(new attr_list, IntrusivePtr{NewRef{}, rt->FieldType(i)}, true, IsGlobal());
fd->attrs = make_intrusive<Attributes>(rt->GetFieldType(i), true, IsGlobal());
fd->attrs->AddAttr(make_intrusive<Attr>(ATTR_LOG));
}
@ -195,14 +266,14 @@ void ID::UpdateValAttrs()
}
}
Attr* ID::FindAttr(attr_tag t) const
const IntrusivePtr<Attr>& ID::GetAttr(attr_tag t) const
{
return attrs ? attrs->FindAttr(t) : nullptr;
return attrs ? attrs->Find(t) : Attr::nil;
}
bool ID::IsDeprecated() const
{
return FindAttr(ATTR_DEPRECATED) != nullptr;
return GetAttr(ATTR_DEPRECATED) != nullptr;
}
void ID::MakeDeprecated(IntrusivePtr<Expr> deprecation)
@ -210,17 +281,18 @@ void ID::MakeDeprecated(IntrusivePtr<Expr> deprecation)
if ( IsDeprecated() )
return;
attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, std::move(deprecation))};
AddAttrs(make_intrusive<Attributes>(attr, IntrusivePtr{NewRef{}, Type()}, false, IsGlobal()));
std::vector<IntrusivePtr<Attr>> attrv{make_intrusive<Attr>(ATTR_DEPRECATED, std::move(deprecation))};
AddAttrs(make_intrusive<Attributes>(std::move(attrv), GetType(), false, IsGlobal()));
}
std::string ID::GetDeprecationWarning() const
{
std::string result;
Attr* depr_attr = FindAttr(ATTR_DEPRECATED);
const auto& depr_attr = GetAttr(ATTR_DEPRECATED);
if ( depr_attr )
{
ConstExpr* expr = static_cast<ConstExpr*>(depr_attr->AttrExpr());
auto expr = static_cast<ConstExpr*>(depr_attr->GetExpr().get());
if ( expr )
{
StringVal* text = expr->Value()->AsStringVal();
@ -237,7 +309,7 @@ std::string ID::GetDeprecationWarning() const
void ID::AddAttrs(IntrusivePtr<Attributes> a)
{
if ( attrs )
attrs->AddAttrs(a.release());
attrs->AddAttrs(a);
else
attrs = std::move(a);
@ -260,14 +332,14 @@ void ID::SetOption()
// option implied redefinable
if ( ! IsRedefinable() )
{
attr_list* attr = new attr_list{new Attr(ATTR_REDEF)};
AddAttrs(make_intrusive<Attributes>(attr, IntrusivePtr{NewRef{}, Type()}, false, IsGlobal()));
std::vector<IntrusivePtr<Attr>> attrv{make_intrusive<Attr>(ATTR_REDEF)};
AddAttrs(make_intrusive<Attributes>(std::move(attrv), GetType(), false, IsGlobal()));
}
}
void ID::EvalFunc(IntrusivePtr<Expr> ef, IntrusivePtr<Expr> ev)
{
auto arg1 = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, val});
auto arg1 = make_intrusive<ConstExpr>(val);
auto args = make_intrusive<ListExpr>();
args->Append(std::move(arg1));
args->Append(std::move(ev));
@ -290,7 +362,7 @@ TraversalCode ID::Traverse(TraversalCallback* cb) const
}
// FIXME: Perhaps we should be checking at other than global scope.
else if ( val && IsFunc(val->Type()->Tag()) &&
else if ( val && IsFunc(val->GetType()->Tag()) &&
cb->current_scope == global_scope() )
{
tc = val->AsFunc()->Traverse(cb);
@ -488,10 +560,8 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
d->Add(":Default:");
auto ii = zeekygen_mgr->GetIdentifierInfo(Name());
auto redefs = ii->GetRedefs();
auto iv = val;
if ( ! redefs.empty() && ii->InitialVal() )
iv = ii->InitialVal();
const auto& iv = ! redefs.empty() && ii->InitialVal() ? ii->InitialVal()
: val;
if ( type->InternalType() == TYPE_INTERNAL_OTHER )
{

156
src/ID.h
View file

@ -10,12 +10,17 @@
#include <map>
#include <string>
#include <string_view>
#include <vector>
class Val;
class Expr;
class Func;
class BroType;
class RecordType;
class TableType;
class VectorType;
class EnumType;
class Attributes;
typedef enum { INIT_NONE, INIT_FULL, INIT_EXTRA, INIT_REMOVE, } init_class;
@ -23,6 +28,8 @@ typedef enum { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL } IDScope;
class ID final : public BroObj, public notifier::Modifiable {
public:
static inline const IntrusivePtr<ID> nil;
ID(const char* name, IDScope arg_scope, bool arg_is_export);
~ID() override;
@ -37,29 +44,44 @@ public:
std::string ModuleName() const;
void SetType(IntrusivePtr<BroType> t);
[[deprecated("Remove in v4.1. Use GetType().")]]
BroType* Type() { return type.get(); }
[[deprecated("Remove in v4.1. Use GetType().")]]
const BroType* Type() const { return type.get(); }
void MakeType() { is_type = true; }
BroType* AsType() { return is_type ? Type() : nullptr; }
const BroType* AsType() const { return is_type ? Type() : nullptr; }
const IntrusivePtr<BroType>& GetType() const
{ return type; }
// If weak_ref is false, the Val is assumed to be already ref'ed
// and will be deref'ed when the ID is deleted.
//
// If weak_ref is true, we store the Val but don't ref/deref it.
// That means that when the ID becomes the only one holding a
// reference to the Val, the Val will be destroyed (naturally,
// you have to take care that it will not be accessed via
// the ID afterwards).
void SetVal(IntrusivePtr<Val> v, bool weak_ref = false);
template <class T>
IntrusivePtr<T> GetType() const
{ return cast_intrusive<T>(type); }
[[deprecated("Remove in v4.1. Use IsType() and GetType().")]]
BroType* AsType() { return is_type ? GetType().get() : nullptr; }
[[deprecated("Remove in v4.1. Use IsType() and GetType().")]]
const BroType* AsType() const { return is_type ? GetType().get() : nullptr; }
bool IsType() const
{ return is_type; }
void MakeType() { is_type = true; }
void SetVal(IntrusivePtr<Val> v);
void SetVal(IntrusivePtr<Val> v, init_class c);
void SetVal(IntrusivePtr<Expr> ev, init_class c);
bool HasVal() const { return val != nullptr; }
Val* ID_Val() { return val; }
const Val* ID_Val() const { return val; }
[[deprecated("Remove in v4.1. Use GetVal().")]]
Val* ID_Val() { return val.get(); }
[[deprecated("Remove in v4.1. Use GetVal().")]]
const Val* ID_Val() const { return val.get(); }
const IntrusivePtr<Val>& GetVal() const
{ return val; }
void ClearVal();
void SetConst() { is_const = true; }
@ -80,9 +102,18 @@ public:
void AddAttrs(IntrusivePtr<Attributes> attr);
void RemoveAttr(attr_tag a);
void UpdateValAttrs();
const IntrusivePtr<Attributes>& GetAttrs() const
{ return attrs; }
[[deprecated("Remove in 4.1. Use GetAttrs().")]]
Attributes* Attrs() const { return attrs.get(); }
Attr* FindAttr(attr_tag t) const;
[[deprecated("Remove in 4.1. Use GetAttr().")]]
Attr* FindAttr(attr_tag t) const
{ return GetAttr(t).get(); }
const IntrusivePtr<Attr>& GetAttr(attr_tag t) const;
bool IsDeprecated() const;
@ -123,13 +154,104 @@ protected:
IDScope scope;
bool is_export;
bool infer_return_type;
bool weak_ref;
IntrusivePtr<BroType> type;
bool is_const, is_enum_const, is_type, is_option;
int offset;
Val* val;
IntrusivePtr<Val> val;
IntrusivePtr<Attributes> attrs;
// contains list of functions that are called when an option changes
std::multimap<int, IntrusivePtr<Func>> option_handlers;
};
namespace zeek::id {
/**
* Lookup an ID in the global module and return it, if one exists;
* @param name The identifier name to lookup.
* @return The identifier, which may reference a nil object if no such
* name exists.
*/
const IntrusivePtr<ID>& find(std::string_view name);
/**
* Lookup an ID by its name and return its type. A fatal occurs if the ID
* does not exist.
* @param name The identifier name to lookup
* @return The type of the identifier.
*/
const IntrusivePtr<BroType>& find_type(std::string_view name);
/**
* Lookup an ID by its name and return its type (as cast to @c T).
* A fatal occurs if the ID does not exist.
* @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)); }
/**
* Lookup an ID by its name and return its value. A fatal occurs if the ID
* does not exist.
* @param name The identifier name to lookup
* @return The current value of the identifier
*/
const IntrusivePtr<Val>& find_val(std::string_view name);
/**
* Lookup an ID by its name and return its value (as cast to @c T).
* A fatal occurs if the ID does not exist.
* @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)); }
/**
* Lookup an ID by its name and return its value. A fatal occurs if the ID
* does not exist or if it is not "const".
* @param name The identifier name to lookup
* @return The current value of the identifier
*/
const IntrusivePtr<Val>& find_const(std::string_view name);
/**
* Lookup an ID by its name and return its value (as cast to @c T).
* A fatal occurs if the ID does not exist.
* @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)); }
/**
* Lookup an ID by its name and return the function it references.
* A fatal occurs if the ID does not exist or if it is not a function.
* @param name The identifier name to lookup
* @return The current function value the identifier references.
*/
IntrusivePtr<Func> find_func(std::string_view name);
extern IntrusivePtr<RecordType> conn_id;
extern IntrusivePtr<RecordType> endpoint;
extern IntrusivePtr<RecordType> connection;
extern IntrusivePtr<RecordType> fa_file;
extern IntrusivePtr<RecordType> fa_metadata;
extern IntrusivePtr<EnumType> transport_proto;
extern IntrusivePtr<TableType> string_set;
extern IntrusivePtr<TableType> string_array;
extern IntrusivePtr<TableType> count_set;
extern IntrusivePtr<VectorType> string_vec;
extern IntrusivePtr<VectorType> index_vec;
namespace detail {
void init();
} // namespace zeek::id::detail
} // namespace zeek::id

245
src/IP.cc
View file

@ -13,43 +13,15 @@
#include "BroString.h"
#include "Reporter.h"
static RecordType* ip4_hdr_type = nullptr;
static RecordType* ip6_hdr_type = nullptr;
static RecordType* ip6_ext_hdr_type = nullptr;
static RecordType* ip6_option_type = nullptr;
static RecordType* ip6_hopopts_type = nullptr;
static RecordType* ip6_dstopts_type = nullptr;
static RecordType* ip6_routing_type = nullptr;
static RecordType* ip6_fragment_type = nullptr;
static RecordType* ip6_ah_type = nullptr;
static RecordType* ip6_esp_type = nullptr;
static RecordType* ip6_mob_type = nullptr;
static RecordType* ip6_mob_msg_type = nullptr;
static RecordType* ip6_mob_brr_type = nullptr;
static RecordType* ip6_mob_hoti_type = nullptr;
static RecordType* ip6_mob_coti_type = nullptr;
static RecordType* ip6_mob_hot_type = nullptr;
static RecordType* ip6_mob_cot_type = nullptr;
static RecordType* ip6_mob_bu_type = nullptr;
static RecordType* ip6_mob_back_type = nullptr;
static RecordType* ip6_mob_be_type = nullptr;
static inline RecordType* hdrType(RecordType*& type, const char* name)
static IntrusivePtr<VectorVal> BuildOptionsVal(const u_char* data, int len)
{
if ( ! type )
type = internal_type(name)->AsRecordType();
return type;
}
static VectorVal* BuildOptionsVal(const u_char* data, int len)
{
VectorVal* vv = new VectorVal(internal_type("ip6_options")->AsVectorType());
auto vv = make_intrusive<VectorVal>(zeek::id::find_type<VectorType>("ip6_options"));
while ( len > 0 )
{
static auto ip6_option_type = zeek::id::find_type<RecordType>("ip6_option");
const struct ip6_opt* opt = (const struct ip6_opt*) data;
RecordVal* rv = new RecordVal(hdrType(ip6_option_type, "ip6_option"));
auto rv = make_intrusive<RecordVal>(ip6_option_type);
rv->Assign(0, val_mgr->Count(opt->ip6o_type));
if ( opt->ip6o_type == 0 )
@ -71,20 +43,21 @@ static VectorVal* BuildOptionsVal(const u_char* data, int len)
len -= opt->ip6o_len + off;
}
vv->Assign(vv->Size(), rv);
vv->Assign(vv->Size(), std::move(rv));
}
return vv;
}
RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
IntrusivePtr<RecordVal> IPv6_Hdr::ToVal(IntrusivePtr<VectorVal> chain) const
{
RecordVal* rv = nullptr;
IntrusivePtr<RecordVal> rv;
switch ( type ) {
case IPPROTO_IPV6:
{
rv = new RecordVal(hdrType(ip6_hdr_type, "ip6_hdr"));
static auto ip6_hdr_type = zeek::id::find_type<RecordType>("ip6_hdr");
rv = make_intrusive<RecordVal>(ip6_hdr_type);
const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data;
rv->Assign(0, val_mgr->Count((ntohl(ip6->ip6_flow) & 0x0ff00000)>>20));
rv->Assign(1, val_mgr->Count(ntohl(ip6->ip6_flow) & 0x000fffff));
@ -94,15 +67,16 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* 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 = new VectorVal(
internal_type("ip6_ext_hdr_chain")->AsVectorType());
rv->Assign(7, chain);
chain = make_intrusive<VectorVal>(
zeek::id::find_type<VectorType>("ip6_ext_hdr_chain"));
rv->Assign(7, std::move(chain));
}
break;
case IPPROTO_HOPOPTS:
{
rv = new RecordVal(hdrType(ip6_hopopts_type, "ip6_hopopts"));
static auto ip6_hopopts_type = zeek::id::find_type<RecordType>("ip6_hopopts");
rv = make_intrusive<RecordVal>(ip6_hopopts_type);
const struct ip6_hbh* hbh = (const struct ip6_hbh*)data;
rv->Assign(0, val_mgr->Count(hbh->ip6h_nxt));
rv->Assign(1, val_mgr->Count(hbh->ip6h_len));
@ -114,7 +88,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
case IPPROTO_DSTOPTS:
{
rv = new RecordVal(hdrType(ip6_dstopts_type, "ip6_dstopts"));
static auto ip6_dstopts_type = zeek::id::find_type<RecordType>("ip6_dstopts");
rv = make_intrusive<RecordVal>(ip6_dstopts_type);
const struct ip6_dest* dst = (const struct ip6_dest*)data;
rv->Assign(0, val_mgr->Count(dst->ip6d_nxt));
rv->Assign(1, val_mgr->Count(dst->ip6d_len));
@ -125,7 +100,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
case IPPROTO_ROUTING:
{
rv = new RecordVal(hdrType(ip6_routing_type, "ip6_routing"));
static auto ip6_routing_type = zeek::id::find_type<RecordType>("ip6_routing");
rv = make_intrusive<RecordVal>(ip6_routing_type);
const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data;
rv->Assign(0, val_mgr->Count(rt->ip6r_nxt));
rv->Assign(1, val_mgr->Count(rt->ip6r_len));
@ -138,7 +114,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
case IPPROTO_FRAGMENT:
{
rv = new RecordVal(hdrType(ip6_fragment_type, "ip6_fragment"));
static auto ip6_fragment_type = zeek::id::find_type<RecordType>("ip6_fragment");
rv = make_intrusive<RecordVal>(ip6_fragment_type);
const struct ip6_frag* frag = (const struct ip6_frag*)data;
rv->Assign(0, val_mgr->Count(frag->ip6f_nxt));
rv->Assign(1, val_mgr->Count(frag->ip6f_reserved));
@ -151,7 +128,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
case IPPROTO_AH:
{
rv = new RecordVal(hdrType(ip6_ah_type, "ip6_ah"));
static auto ip6_ah_type = zeek::id::find_type<RecordType>("ip6_ah");
rv = make_intrusive<RecordVal>(ip6_ah_type);
rv->Assign(0, val_mgr->Count(((ip6_ext*)data)->ip6e_nxt));
rv->Assign(1, val_mgr->Count(((ip6_ext*)data)->ip6e_len));
rv->Assign(2, val_mgr->Count(ntohs(((uint16_t*)data)[1])));
@ -170,7 +148,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
case IPPROTO_ESP:
{
rv = new RecordVal(hdrType(ip6_esp_type, "ip6_esp"));
static auto ip6_esp_type = zeek::id::find_type<RecordType>("ip6_esp");
rv = make_intrusive<RecordVal>(ip6_esp_type);
const uint32_t* esp = (const uint32_t*)data;
rv->Assign(0, val_mgr->Count(ntohl(esp[0])));
rv->Assign(1, val_mgr->Count(ntohl(esp[1])));
@ -180,7 +159,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
#ifdef ENABLE_MOBILE_IPV6
case IPPROTO_MOBILITY:
{
rv = new RecordVal(hdrType(ip6_mob_type, "ip6_mobility_hdr"));
static auto ip6_mob_type = zeek::id::find_type<RecordType>("ip6_mobility_hdr");
rv = make_intrusive<RecordVal>(ip6_mob_type);
const struct ip6_mobility* mob = (const struct ip6_mobility*) data;
rv->Assign(0, val_mgr->Count(mob->ip6mob_payload));
rv->Assign(1, val_mgr->Count(mob->ip6mob_len));
@ -188,72 +168,82 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
rv->Assign(3, val_mgr->Count(mob->ip6mob_rsv));
rv->Assign(4, val_mgr->Count(ntohs(mob->ip6mob_chksum)));
RecordVal* msg = new RecordVal(hdrType(ip6_mob_msg_type, "ip6_mobility_msg"));
static auto ip6_mob_msg_type = zeek::id::find_type<RecordType>("ip6_mobility_msg");
auto msg = make_intrusive<RecordVal>(ip6_mob_msg_type);
msg->Assign(0, val_mgr->Count(mob->ip6mob_type));
uint16_t off = sizeof(ip6_mobility);
const u_char* msg_data = data + off;
static auto ip6_mob_brr_type = zeek::id::find_type<RecordType>("ip6_mobility_brr");
static auto ip6_mob_hoti_type = zeek::id::find_type<RecordType>("ip6_mobility_hoti");
static auto ip6_mob_coti_type = zeek::id::find_type<RecordType>("ip6_mobility_coti");
static auto ip6_mob_hot_type = zeek::id::find_type<RecordType>("ip6_mobility_hot");
static auto ip6_mob_cot_type = zeek::id::find_type<RecordType>("ip6_mobility_cot");
static auto ip6_mob_bu_type = zeek::id::find_type<RecordType>("ip6_mobility_bu");
static auto ip6_mob_back_type = zeek::id::find_type<RecordType>("ip6_mobility_back");
static auto ip6_mob_be_type = zeek::id::find_type<RecordType>("ip6_mobility_be");
switch ( mob->ip6mob_type ) {
case 0:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_brr"));
auto m = make_intrusive<RecordVal>(ip6_mob_brr_type);
m->Assign(0, val_mgr->Count(ntohs(*((uint16_t*)msg_data))));
off += sizeof(uint16_t);
m->Assign(1, BuildOptionsVal(data + off, Length() - off));
msg->Assign(1, m);
msg->Assign(1, std::move(m));
}
break;
case 1:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_hoti"));
auto m = make_intrusive<RecordVal>(ip6_mobility_hoti_type);
m->Assign(0, val_mgr->Count(ntohs(*((uint16_t*)msg_data))));
m->Assign(1, val_mgr->Count(ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))));
off += sizeof(uint16_t) + sizeof(uint64_t);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(2, m);
msg->Assign(2, std::move(m));
break;
}
case 2:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_coti"));
auto m = make_intrusive<RecordVal>(ip6_mobility_coti_type);
m->Assign(0, val_mgr->Count(ntohs(*((uint16_t*)msg_data))));
m->Assign(1, val_mgr->Count(ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))));
off += sizeof(uint16_t) + sizeof(uint64_t);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(3, m);
msg->Assign(3, std::move(m));
break;
}
case 3:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_hot"));
auto m = make_intrusive<RecordVal>(ip6_mobility_hot_type);
m->Assign(0, val_mgr->Count(ntohs(*((uint16_t*)msg_data))));
m->Assign(1, val_mgr->Count(ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))));
m->Assign(2, val_mgr->Count(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, m);
msg->Assign(4, std::move(m));
break;
}
case 4:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_cot"));
auto m = make_intrusive<RecordVal>(ip6_mobility_cot_type);
m->Assign(0, val_mgr->Count(ntohs(*((uint16_t*)msg_data))));
m->Assign(1, val_mgr->Count(ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))));
m->Assign(2, val_mgr->Count(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, m);
msg->Assign(5, std::move(m));
break;
}
case 5:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_bu"));
auto m = make_intrusive<RecordVal>(ip6_mobility_bu_type);
m->Assign(0, val_mgr->Count(ntohs(*((uint16_t*)msg_data))));
m->Assign(1, val_mgr->Bool(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x8000));
m->Assign(2, val_mgr->Bool(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x4000));
@ -262,32 +252,32 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
m->Assign(5, val_mgr->Count(ntohs(*((uint16_t*)(msg_data + 2*sizeof(uint16_t))))));
off += 3 * sizeof(uint16_t);
m->Assign(6, BuildOptionsVal(data + off, Length() - off));
msg->Assign(6, m);
msg->Assign(6, std::move(m));
break;
}
case 6:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_back"));
auto m = make_intrusive<RecordVal>(ip6_mobility_back_type);
m->Assign(0, val_mgr->Count(*((uint8_t*)msg_data)));
m->Assign(1, val_mgr->Bool(*((uint8_t*)(msg_data + sizeof(uint8_t))) & 0x80));
m->Assign(2, val_mgr->Count(ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t))))));
m->Assign(3, val_mgr->Count(ntohs(*((uint16_t*)(msg_data + 2*sizeof(uint16_t))))));
off += 3 * sizeof(uint16_t);
m->Assign(4, BuildOptionsVal(data + off, Length() - off));
msg->Assign(7, m);
msg->Assign(7, std::move(m));
break;
}
case 7:
{
RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_be"));
auto m = make_intrusive<RecordVal>(ip6_mobility_be_type);
m->Assign(0, val_mgr->Count(*((uint8_t*)msg_data)));
const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16_t));
m->Assign(1, make_intrusive<AddrVal>(IPAddr(*hoa)));
off += sizeof(uint16_t) + sizeof(in6_addr);
m->Assign(2, BuildOptionsVal(data + off, Length() - off));
msg->Assign(8, m);
msg->Assign(8, std::move(m));
break;
}
@ -296,7 +286,7 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
break;
}
rv->Assign(5, msg);
rv->Assign(5, std::move(msg));
}
break;
#endif //ENABLE_MOBILE_IPV6
@ -308,6 +298,14 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
return rv;
}
IntrusivePtr<RecordVal> IPv6_Hdr::ToVal() const
{ return ToVal(nullptr); }
RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
{
return ToVal({AdoptRef{}, chain}).release();
}
IPAddr IP_Hdr::IPHeaderSrcAddr() const
{
return ip4 ? IPAddr(ip4->ip_src) : IPAddr(ip6->ip6_src);
@ -328,13 +326,14 @@ IPAddr IP_Hdr::DstAddr() const
return ip4 ? IPAddr(ip4->ip_dst) : ip6_hdrs->DstAddr();
}
RecordVal* IP_Hdr::BuildIPHdrVal() const
IntrusivePtr<RecordVal> IP_Hdr::ToIPHdrVal() const
{
RecordVal* rval = nullptr;
IntrusivePtr<RecordVal> rval;
if ( ip4 )
{
rval = new RecordVal(hdrType(ip4_hdr_type, "ip4_hdr"));
static auto ip4_hdr_type = zeek::id::find_type<RecordType>("ip4_hdr");
rval = make_intrusive<RecordVal>(ip4_hdr_type);
rval->Assign(0, val_mgr->Count(ip4->ip_hl * 4));
rval->Assign(1, val_mgr->Count(ip4->ip_tos));
rval->Assign(2, val_mgr->Count(ntohs(ip4->ip_len)));
@ -346,40 +345,38 @@ RecordVal* IP_Hdr::BuildIPHdrVal() const
}
else
{
rval = ((*ip6_hdrs)[0])->BuildRecordVal(ip6_hdrs->BuildVal());
rval = ((*ip6_hdrs)[0])->ToVal(ip6_hdrs->ToVal());
}
return rval;
}
RecordVal* IP_Hdr::BuildIPHdrVal() const
{
return ToIPHdrVal().release();
}
IntrusivePtr<RecordVal> IP_Hdr::ToPktHdrVal() const
{
static auto pkt_hdr_type = zeek::id::find_type<RecordType>("pkt_hdr");
return ToPktHdrVal(make_intrusive<RecordVal>(pkt_hdr_type), 0);
}
RecordVal* IP_Hdr::BuildPktHdrVal() const
{
static RecordType* pkt_hdr_type = nullptr;
if ( ! pkt_hdr_type )
pkt_hdr_type = internal_type("pkt_hdr")->AsRecordType();
RecordVal* pkt_hdr = new RecordVal(pkt_hdr_type);
return BuildPktHdrVal(pkt_hdr, 0);
return ToPktHdrVal().release();
}
RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
IntrusivePtr<RecordVal> IP_Hdr::ToPktHdrVal(IntrusivePtr<RecordVal> pkt_hdr, int sindex) const
{
static RecordType* tcp_hdr_type = nullptr;
static RecordType* udp_hdr_type = nullptr;
static RecordType* icmp_hdr_type = nullptr;
if ( ! tcp_hdr_type )
{
tcp_hdr_type = internal_type("tcp_hdr")->AsRecordType();
udp_hdr_type = internal_type("udp_hdr")->AsRecordType();
icmp_hdr_type = internal_type("icmp_hdr")->AsRecordType();
}
static auto tcp_hdr_type = zeek::id::find_type<RecordType>("tcp_hdr");
static auto udp_hdr_type = zeek::id::find_type<RecordType>("udp_hdr");
static auto icmp_hdr_type = zeek::id::find_type<RecordType>("icmp_hdr");
if ( ip4 )
pkt_hdr->Assign(sindex + 0, BuildIPHdrVal());
pkt_hdr->Assign(sindex + 0, ToIPHdrVal());
else
pkt_hdr->Assign(sindex + 1, BuildIPHdrVal());
pkt_hdr->Assign(sindex + 1, ToIPHdrVal());
// L4 header.
const u_char* data = Payload();
@ -389,7 +386,7 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
case IPPROTO_TCP:
{
const struct tcphdr* tp = (const struct tcphdr*) data;
RecordVal* tcp_hdr = new RecordVal(tcp_hdr_type);
auto tcp_hdr = make_intrusive<RecordVal>(tcp_hdr_type);
int tcp_hdr_len = tp->th_off * 4;
int data_len = PayloadLen() - tcp_hdr_len;
@ -404,42 +401,42 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
tcp_hdr->Assign(7, val_mgr->Count(tp->th_flags));
tcp_hdr->Assign(8, val_mgr->Count(ntohs(tp->th_win)));
pkt_hdr->Assign(sindex + 2, tcp_hdr);
pkt_hdr->Assign(sindex + 2, std::move(tcp_hdr));
break;
}
case IPPROTO_UDP:
{
const struct udphdr* up = (const struct udphdr*) data;
RecordVal* udp_hdr = new RecordVal(udp_hdr_type);
auto udp_hdr = make_intrusive<RecordVal>(udp_hdr_type);
udp_hdr->Assign(0, val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP));
udp_hdr->Assign(1, val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP));
udp_hdr->Assign(2, val_mgr->Count(ntohs(up->uh_ulen)));
pkt_hdr->Assign(sindex + 3, udp_hdr);
pkt_hdr->Assign(sindex + 3, std::move(udp_hdr));
break;
}
case IPPROTO_ICMP:
{
const struct icmp* icmpp = (const struct icmp *) data;
RecordVal* icmp_hdr = new RecordVal(icmp_hdr_type);
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, val_mgr->Count(icmpp->icmp_type));
pkt_hdr->Assign(sindex + 4, icmp_hdr);
pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr));
break;
}
case IPPROTO_ICMPV6:
{
const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*) data;
RecordVal* icmp_hdr = new RecordVal(icmp_hdr_type);
auto icmp_hdr = make_intrusive<RecordVal>(icmp_hdr_type);
icmp_hdr->Assign(0, val_mgr->Count(icmpp->icmp6_type));
pkt_hdr->Assign(sindex + 4, icmp_hdr);
pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr));
break;
}
@ -453,6 +450,11 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
return pkt_hdr;
}
RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
{
return ToPktHdrVal({AdoptRef{}, pkt_hdr}, sindex).release();
}
static inline bool isIPv6ExtHeader(uint8_t type)
{
switch (type) {
@ -674,66 +676,65 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
}
#endif
VectorVal* IPv6_Hdr_Chain::BuildVal() const
IntrusivePtr<VectorVal> IPv6_Hdr_Chain::ToVal() const
{
if ( ! ip6_ext_hdr_type )
{
ip6_ext_hdr_type = internal_type("ip6_ext_hdr")->AsRecordType();
ip6_hopopts_type = internal_type("ip6_hopopts")->AsRecordType();
ip6_dstopts_type = internal_type("ip6_dstopts")->AsRecordType();
ip6_routing_type = internal_type("ip6_routing")->AsRecordType();
ip6_fragment_type = internal_type("ip6_fragment")->AsRecordType();
ip6_ah_type = internal_type("ip6_ah")->AsRecordType();
ip6_esp_type = internal_type("ip6_esp")->AsRecordType();
ip6_mob_type = internal_type("ip6_mobility_hdr")->AsRecordType();
}
VectorVal* rval = new VectorVal(
internal_type("ip6_ext_hdr_chain")->AsVectorType());
static auto ip6_ext_hdr_type = zeek::id::find_type<RecordType>("ip6_ext_hdr");
static auto ip6_hopopts_type = zeek::id::find_type<RecordType>("ip6_hopopts");
static auto ip6_dstopts_type = zeek::id::find_type<RecordType>("ip6_dstopts");
static auto ip6_routing_type = zeek::id::find_type<RecordType>("ip6_routing");
static auto ip6_fragment_type = zeek::id::find_type<RecordType>("ip6_fragment");
static auto ip6_ah_type = zeek::id::find_type<RecordType>("ip6_ah");
static auto ip6_esp_type = zeek::id::find_type<RecordType>("ip6_esp");
static auto ip6_ext_hdr_chain_type = zeek::id::find_type<VectorType>("ip6_ext_hdr_chain");
auto rval = make_intrusive<VectorVal>(ip6_ext_hdr_chain_type);
for ( size_t i = 1; i < chain.size(); ++i )
{
RecordVal* v = chain[i]->BuildRecordVal();
RecordVal* ext_hdr = new RecordVal(ip6_ext_hdr_type);
auto v = chain[i]->ToVal();
auto ext_hdr = make_intrusive<RecordVal>(ip6_ext_hdr_type);
uint8_t type = chain[i]->Type();
ext_hdr->Assign(0, val_mgr->Count(type));
switch (type) {
case IPPROTO_HOPOPTS:
ext_hdr->Assign(1, v);
ext_hdr->Assign(1, std::move(v));
break;
case IPPROTO_DSTOPTS:
ext_hdr->Assign(2, v);
ext_hdr->Assign(2, std::move(v));
break;
case IPPROTO_ROUTING:
ext_hdr->Assign(3, v);
ext_hdr->Assign(3, std::move(v));
break;
case IPPROTO_FRAGMENT:
ext_hdr->Assign(4, v);
ext_hdr->Assign(4, std::move(v));
break;
case IPPROTO_AH:
ext_hdr->Assign(5, v);
ext_hdr->Assign(5, std::move(v));
break;
case IPPROTO_ESP:
ext_hdr->Assign(6, v);
ext_hdr->Assign(6, std::move(v));
break;
#ifdef ENABLE_MOBILE_IPV6
case IPPROTO_MOBILITY:
ext_hdr->Assign(7, v);
ext_hdr->Assign(7, std::move(v));
break;
#endif
default:
reporter->InternalWarning("IPv6_Hdr_Chain bad header %d", type);
Unref(ext_hdr);
continue;
}
rval->Assign(rval->Size(), ext_hdr);
rval->Assign(rval->Size(), std::move(ext_hdr));
}
return rval;
}
VectorVal* IPv6_Hdr_Chain::BuildVal() const
{
return ToVal().release();
}
IP_Hdr* IP_Hdr::Copy() const
{
char* new_hdr = new char[HdrLen()];

View file

@ -14,6 +14,8 @@
#include <vector>
#include "IntrusivePtr.h"
class IPAddr;
class RecordVal;
class VectorVal;
@ -134,6 +136,10 @@ public:
/**
* Returns the script-layer record representation of the header.
*/
IntrusivePtr<RecordVal> ToVal(IntrusivePtr<VectorVal> chain) const;
IntrusivePtr<RecordVal> ToVal() const;
[[deprecated("Remove in v4.1. Use ToVal() instead.")]]
RecordVal* BuildRecordVal(VectorVal* chain = nullptr) const;
protected:
@ -223,6 +229,9 @@ public:
* Returns a vector of ip6_ext_hdr RecordVals that includes script-layer
* representation of all extension headers in the chain.
*/
IntrusivePtr<VectorVal> ToVal() const;
[[deprecated("Remove in v4.1. Use ToVal() instead.")]]
VectorVal* BuildVal() const;
protected:
@ -517,18 +526,27 @@ public:
/**
* Returns an ip_hdr or ip6_hdr_chain RecordVal.
*/
IntrusivePtr<RecordVal> ToIPHdrVal() const;
[[deprecated("Remove in v4.1. Use ToIPHdrVal() instead.")]]
RecordVal* BuildIPHdrVal() const;
/**
* Returns a pkt_hdr RecordVal, which includes not only the IP header, but
* also upper-layer (tcp/udp/icmp) headers.
*/
IntrusivePtr<RecordVal> ToPktHdrVal() const;
[[deprecated("Remove in v4.1. Use ToPktHdrVal() instead.")]]
RecordVal* BuildPktHdrVal() const;
/**
* Same as above, but simply add our values into the record at the
* specified starting index.
*/
IntrusivePtr<RecordVal> ToPktHdrVal(IntrusivePtr<RecordVal> pkt_hdr, int sindex) const;
[[deprecated("Remove in v4.1. Use ToPktHdrVal() instead.")]]
RecordVal* BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const;
private:

View file

@ -53,8 +53,11 @@ IPAddr::IPAddr(const BroString& s)
}
HashKey* IPAddr::GetHashKey() const
{ return MakeHashKey().release(); }
std::unique_ptr<HashKey> IPAddr::MakeHashKey() const
{
return new HashKey((void*)in6.s6_addr, sizeof(in6.s6_addr));
return std::make_unique<HashKey>((void*)in6.s6_addr, sizeof(in6.s6_addr));
}
static inline uint32_t bit_mask32(int bottom_bits)
@ -303,6 +306,9 @@ std::string IPPrefix::AsString() const
}
HashKey* IPPrefix::GetHashKey() const
{ return MakeHashKey().release(); }
std::unique_ptr<HashKey> IPPrefix::MakeHashKey() const
{
struct {
in6_addr ip;
@ -312,7 +318,7 @@ HashKey* IPPrefix::GetHashKey() const
key.ip = prefix.in6;
key.len = Length();
return new HashKey(&key, sizeof(key));
return std::make_unique<HashKey>(&key, sizeof(key));
}
bool IPPrefix::ConvertString(const char* text, IPPrefix* result)

View file

@ -6,6 +6,7 @@
#include <arpa/inet.h>
#include <string.h>
#include <string>
#include <memory>
#include "threading/SerialTypes.h"
@ -247,9 +248,11 @@ public:
}
/**
* Returns a key that can be used to lookup the IP Address in a hash
* table. Passes ownership to caller.
* Returns a key that can be used to lookup the IP Address in a hash table.
*/
std::unique_ptr<HashKey> MakeHashKey() const;
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
HashKey* GetHashKey() const;
/**
@ -629,9 +632,11 @@ public:
operator std::string() const { return AsString(); }
/**
* Returns a key that can be used to lookup the IP Prefix in a hash
* table. Passes ownership to caller.
* Returns a key that can be used to lookup the IP Prefix in a hash table.
*/
std::unique_ptr<HashKey> MakeHashKey() const;
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
HashKey* GetHashKey() const;
/** Converts the prefix into the type used internally by the

View file

@ -184,6 +184,18 @@ IntrusivePtr<T> make_intrusive(Ts&&... args)
return {AdoptRef{}, new T(std::forward<Ts>(args)...)};
}
/**
* Casts an @c IntrusivePtr object to another by way of static_cast on
* the underlying pointer.
* @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
{
return {AdoptRef{}, static_cast<T*>(p.release())};
}
// -- comparison to nullptr ----------------------------------------------------
/**

View file

@ -28,7 +28,7 @@ extern "C" {
#include "Sessions.h"
#include "Event.h"
#include "Timer.h"
#include "Var.h"
#include "ID.h"
#include "Reporter.h"
#include "Scope.h"
#include "Anon.h"
@ -193,7 +193,7 @@ void net_init(const std::optional<std::string>& interface,
reporter->FatalError("problem opening dump file %s (%s)",
writefile, pkt_dumper->ErrorMsg());
if ( ID* id = global_scope()->Lookup("trace_output_file") )
if ( const auto& id = global_scope()->Find("trace_output_file") )
id->SetVal(make_intrusive<StringVal>(writefile));
else
reporter->Error("trace_output_file not defined in bro.init");
@ -283,7 +283,7 @@ void net_run()
ready.reserve(iosource_mgr->TotalSize());
while ( iosource_mgr->Size() ||
(BifConst::exit_only_after_terminate && ! terminating) )
(zeek::BifConst::exit_only_after_terminate && ! terminating) )
{
iosource_mgr->FindReadySources(&ready);
@ -314,7 +314,7 @@ void net_run()
}
}
else if ( (have_pending_timers || communication_enabled ||
BifConst::exit_only_after_terminate) &&
zeek::BifConst::exit_only_after_terminate) &&
! pseudo_realtime )
{
// Take advantage of the lull to get up to
@ -331,6 +331,8 @@ void net_run()
current_dispatched = 0;
current_iosrc = nullptr;
extern int signal_val;
if ( signal_val == SIGTERM || signal_val == SIGINT )
// We received a signal while processing the
// current packet and its related events.

View file

@ -6,6 +6,7 @@
#include "Var.h"
#include "EventHandler.h"
#include "Val.h"
#include "ID.h"
RecordType* conn_id;
RecordType* endpoint;
@ -83,14 +84,6 @@ bool udp_content_delivery_ports_use_resp;
double dns_session_timeout;
double rpc_timeout;
ListVal* skip_authentication;
ListVal* direct_login_prompts;
ListVal* login_prompts;
ListVal* login_non_failure_msgs;
ListVal* login_failure_msgs;
ListVal* login_success_msgs;
ListVal* login_timeouts;
int mime_segment_length;
int mime_segment_overlap_length;
RecordType* mime_header_rec;
@ -156,8 +149,6 @@ Val* pkt_profile_file;
int load_sample_freq;
double gap_report_freq;
int packet_filter_default;
int sig_max_group_size;
@ -175,8 +166,6 @@ TableVal* likely_server_ports;
int check_for_unused_event_handlers;
int suppress_local_output;
double timer_mgr_inactivity_timeout;
StringVal* trace_output_file;
@ -209,37 +198,18 @@ void init_event_handlers()
void init_general_global_var()
{
table_expire_interval = opt_internal_double("table_expire_interval");
table_expire_delay = opt_internal_double("table_expire_delay");
table_incremental_step = opt_internal_int("table_incremental_step");
rotate_info = internal_type("rotate_info")->AsRecordType();
log_rotate_base_time = opt_internal_string("log_rotate_base_time");
peer_description =
internal_val("peer_description")->AsStringVal();
packet_filter_default = opt_internal_int("packet_filter_default");
sig_max_group_size = opt_internal_int("sig_max_group_size");
check_for_unused_event_handlers =
opt_internal_int("check_for_unused_event_handlers");
suppress_local_output = opt_internal_int("suppress_local_output");
trace_output_file = internal_val("trace_output_file")->AsStringVal();
record_all_packets = opt_internal_int("record_all_packets");
cmd_line_bpf_filter =
internal_val("cmd_line_bpf_filter")->AsStringVal();
global_hash_seed = opt_internal_string("global_hash_seed");
bits_per_uid = opt_internal_unsigned("bits_per_uid");
table_expire_interval = zeek::id::find_val("table_expire_interval")->AsInterval();
table_expire_delay = zeek::id::find_val("table_expire_delay")->AsInterval();
table_incremental_step = zeek::id::find_val("table_incremental_step")->AsCount();
packet_filter_default = zeek::id::find_val("packet_filter_default")->AsBool();
sig_max_group_size = zeek::id::find_val("sig_max_group_size")->AsCount();
check_for_unused_event_handlers = zeek::id::find_val("check_for_unused_event_handlers")->AsBool();
record_all_packets = zeek::id::find_val("record_all_packets")->AsBool();
bits_per_uid = zeek::id::find_val("bits_per_uid")->AsCount();
}
extern void zeek_legacy_netvar_init();
void init_net_var()
{
#include "const.bif.netvar_init"
@ -247,188 +217,105 @@ void init_net_var()
#include "reporter.bif.netvar_init"
#include "supervisor.bif.netvar_init"
conn_id = internal_type("conn_id")->AsRecordType();
endpoint = internal_type("endpoint")->AsRecordType();
endpoint_stats = internal_type("endpoint_stats")->AsRecordType();
connection_type = internal_type("connection")->AsRecordType();
fa_file_type = internal_type("fa_file")->AsRecordType();
fa_metadata_type = internal_type("fa_metadata")->AsRecordType();
icmp_conn = internal_type("icmp_conn")->AsRecordType();
icmp_context = internal_type("icmp_context")->AsRecordType();
signature_state = internal_type("signature_state")->AsRecordType();
SYN_packet = internal_type("SYN_packet")->AsRecordType();
pcap_packet = internal_type("pcap_packet")->AsRecordType();
raw_pkt_hdr_type = internal_type("raw_pkt_hdr")->AsRecordType();
l2_hdr_type = internal_type("l2_hdr")->AsRecordType();
transport_proto = internal_type("transport_proto")->AsEnumType();
string_set = internal_type("string_set")->AsTableType();
string_array = internal_type("string_array")->AsTableType();
string_vec = internal_type("string_vec")->AsVectorType();
index_vec = internal_type("index_vec")->AsVectorType();
mime_match = internal_type("mime_match")->AsRecordType();
mime_matches = internal_type("mime_matches")->AsVectorType();
zeek::id::detail::init();
zeek_legacy_netvar_init();
ignore_checksums = opt_internal_int("ignore_checksums");
partial_connection_ok = opt_internal_int("partial_connection_ok");
tcp_SYN_ack_ok = opt_internal_int("tcp_SYN_ack_ok");
tcp_match_undelivered = opt_internal_int("tcp_match_undelivered");
ignore_checksums = zeek::id::find_val("ignore_checksums")->AsBool();
partial_connection_ok = zeek::id::find_val("partial_connection_ok")->AsBool();
tcp_SYN_ack_ok = zeek::id::find_val("tcp_SYN_ack_ok")->AsBool();
tcp_match_undelivered = zeek::id::find_val("tcp_match_undelivered")->AsBool();
encap_hdr_size = opt_internal_int("encap_hdr_size");
encap_hdr_size = zeek::id::find_val("encap_hdr_size")->AsCount();
frag_timeout = opt_internal_double("frag_timeout");
frag_timeout = zeek::id::find_val("frag_timeout")->AsInterval();
tcp_SYN_timeout = opt_internal_double("tcp_SYN_timeout");
tcp_session_timer = opt_internal_double("tcp_session_timer");
tcp_connection_linger = opt_internal_double("tcp_connection_linger");
tcp_attempt_delay = opt_internal_double("tcp_attempt_delay");
tcp_close_delay = opt_internal_double("tcp_close_delay");
tcp_reset_delay = opt_internal_double("tcp_reset_delay");
tcp_partial_close_delay = opt_internal_double("tcp_partial_close_delay");
tcp_SYN_timeout = zeek::id::find_val("tcp_SYN_timeout")->AsInterval();
tcp_session_timer = zeek::id::find_val("tcp_session_timer")->AsInterval();
tcp_connection_linger = zeek::id::find_val("tcp_connection_linger")->AsInterval();
tcp_attempt_delay = zeek::id::find_val("tcp_attempt_delay")->AsInterval();
tcp_close_delay = zeek::id::find_val("tcp_close_delay")->AsInterval();
tcp_reset_delay = zeek::id::find_val("tcp_reset_delay")->AsInterval();
tcp_partial_close_delay = zeek::id::find_val("tcp_partial_close_delay")->AsInterval();
tcp_max_initial_window = opt_internal_int("tcp_max_initial_window");
tcp_max_above_hole_without_any_acks =
opt_internal_int("tcp_max_above_hole_without_any_acks");
tcp_excessive_data_without_further_acks =
opt_internal_int("tcp_excessive_data_without_further_acks");
tcp_max_old_segments = opt_internal_int("tcp_max_old_segments");
tcp_max_initial_window = zeek::id::find_val("tcp_max_initial_window")->AsCount();
tcp_max_above_hole_without_any_acks = zeek::id::find_val("tcp_max_above_hole_without_any_acks")->AsCount();
tcp_excessive_data_without_further_acks = zeek::id::find_val("tcp_excessive_data_without_further_acks")->AsCount();
tcp_max_old_segments = zeek::id::find_val("tcp_max_old_segments")->AsCount();
socks_address = internal_type("SOCKS::Address")->AsRecordType();
non_analyzed_lifetime = zeek::id::find_val("non_analyzed_lifetime")->AsInterval();
tcp_inactivity_timeout = zeek::id::find_val("tcp_inactivity_timeout")->AsInterval();
udp_inactivity_timeout = zeek::id::find_val("udp_inactivity_timeout")->AsInterval();
icmp_inactivity_timeout = zeek::id::find_val("icmp_inactivity_timeout")->AsInterval();
non_analyzed_lifetime = opt_internal_double("non_analyzed_lifetime");
tcp_inactivity_timeout = opt_internal_double("tcp_inactivity_timeout");
udp_inactivity_timeout = opt_internal_double("udp_inactivity_timeout");
icmp_inactivity_timeout = opt_internal_double("icmp_inactivity_timeout");
tcp_storm_thresh = zeek::id::find_val("tcp_storm_thresh")->AsCount();
tcp_storm_interarrival_thresh = zeek::id::find_val("tcp_storm_interarrival_thresh")->AsInterval();
tcp_storm_thresh = opt_internal_int("tcp_storm_thresh");
tcp_storm_interarrival_thresh =
opt_internal_double("tcp_storm_interarrival_thresh");
tcp_reassembler_ports_orig =
internal_val("tcp_reassembler_ports_orig")->AsTableVal();
tcp_reassembler_ports_resp =
internal_val("tcp_reassembler_ports_resp")->AsTableVal();
tcp_content_delivery_ports_orig =
internal_val("tcp_content_delivery_ports_orig")->AsTableVal();
tcp_content_delivery_ports_resp =
internal_val("tcp_content_delivery_ports_resp")->AsTableVal();
tcp_content_deliver_all_orig =
bool(internal_val("tcp_content_deliver_all_orig")->AsBool());
bool(zeek::id::find_val("tcp_content_deliver_all_orig")->AsBool());
tcp_content_deliver_all_resp =
bool(internal_val("tcp_content_deliver_all_resp")->AsBool());
bool(zeek::id::find_val("tcp_content_deliver_all_resp")->AsBool());
udp_content_delivery_ports_orig =
internal_val("udp_content_delivery_ports_orig")->AsTableVal();
udp_content_delivery_ports_resp =
internal_val("udp_content_delivery_ports_resp")->AsTableVal();
udp_content_ports =
internal_val("udp_content_ports")->AsTableVal();
udp_content_deliver_all_orig =
bool(internal_val("udp_content_deliver_all_orig")->AsBool());
bool(zeek::id::find_val("udp_content_deliver_all_orig")->AsBool());
udp_content_deliver_all_resp =
bool(internal_val("udp_content_deliver_all_resp")->AsBool());
bool(zeek::id::find_val("udp_content_deliver_all_resp")->AsBool());
udp_content_delivery_ports_use_resp =
bool(internal_val("udp_content_delivery_ports_use_resp")->AsBool());
bool(zeek::id::find_val("udp_content_delivery_ports_use_resp")->AsBool());
dns_session_timeout = opt_internal_double("dns_session_timeout");
rpc_timeout = opt_internal_double("rpc_timeout");
dns_session_timeout = zeek::id::find_val("dns_session_timeout")->AsInterval();
rpc_timeout = zeek::id::find_val("rpc_timeout")->AsInterval();
watchdog_interval = int(opt_internal_double("watchdog_interval"));
watchdog_interval = int(zeek::id::find_val("watchdog_interval")->AsInterval());
max_timer_expires = opt_internal_int("max_timer_expires");
max_timer_expires = zeek::id::find_val("max_timer_expires")->AsCount();
skip_authentication = internal_list_val("skip_authentication");
direct_login_prompts = internal_list_val("direct_login_prompts");
login_prompts = internal_list_val("login_prompts");
login_non_failure_msgs = internal_list_val("login_non_failure_msgs");
login_failure_msgs = internal_list_val("login_failure_msgs");
login_success_msgs = internal_list_val("login_success_msgs");
login_timeouts = internal_list_val("login_timeouts");
mime_segment_length = zeek::id::find_val("mime_segment_length")->AsCount();
mime_segment_overlap_length = zeek::id::find_val("mime_segment_overlap_length")->AsCount();
mime_segment_length = opt_internal_int("mime_segment_length");
mime_segment_overlap_length = opt_internal_int("mime_segment_overlap_length");
mime_header_rec = internal_type("mime_header_rec")->AsRecordType();
mime_header_list = internal_type("mime_header_list")->AsTableType();
http_entity_data_delivery_size = zeek::id::find_val("http_entity_data_delivery_size")->AsCount();
truncate_http_URI = zeek::id::find_val("truncate_http_URI")->AsInt();
http_entity_data_delivery_size = opt_internal_int("http_entity_data_delivery_size");
http_stats_rec = internal_type("http_stats_rec")->AsRecordType();
http_message_stat = internal_type("http_message_stat")->AsRecordType();
truncate_http_URI = opt_internal_int("truncate_http_URI");
dns_skip_all_auth = zeek::id::find_val("dns_skip_all_auth")->AsBool();
dns_skip_all_addl = zeek::id::find_val("dns_skip_all_addl")->AsBool();
dns_max_queries = zeek::id::find_val("dns_max_queries")->AsCount();
pm_mapping = internal_type("pm_mapping")->AsRecordType();
pm_mappings = internal_type("pm_mappings")->AsTableType();
pm_port_request = internal_type("pm_port_request")->AsRecordType();
pm_callit_request = internal_type("pm_callit_request")->AsRecordType();
stp_delta = 0.0;
if ( const auto& v = zeek::id::find_val("stp_delta") ) stp_delta = v->AsInterval();
stp_idle_min = 0.0;
if ( const auto& v = zeek::id::find_val("stp_idle_min") ) stp_delta = v->AsInterval();
geo_location = internal_type("geo_location")->AsRecordType();
orig_addr_anonymization = 0;
if ( const auto& id = zeek::id::find("orig_addr_anonymization") )
if ( const auto& v = id->GetVal() )
orig_addr_anonymization = v->AsInt();
resp_addr_anonymization = 0;
if ( const auto& id = zeek::id::find("resp_addr_anonymization") )
if ( const auto& v = id->GetVal() )
resp_addr_anonymization = v->AsInt();
other_addr_anonymization = 0;
if ( const auto& id = zeek::id::find("other_addr_anonymization") )
if ( const auto& v = id->GetVal() )
other_addr_anonymization = v->AsInt();
entropy_test_result = internal_type("entropy_test_result")->AsRecordType();
connection_status_update_interval = 0.0;
if ( const auto& id = zeek::id::find("connection_status_update_interval") )
if ( const auto& v = id->GetVal() )
connection_status_update_interval = v->AsInterval();
dns_msg = internal_type("dns_msg")->AsRecordType();
dns_answer = internal_type("dns_answer")->AsRecordType();
dns_soa = internal_type("dns_soa")->AsRecordType();
dns_edns_additional =
internal_type("dns_edns_additional")->AsRecordType();
dns_tsig_additional =
internal_type("dns_tsig_additional")->AsRecordType();
dns_rrsig_rr = internal_type("dns_rrsig_rr")->AsRecordType();
dns_dnskey_rr = internal_type("dns_dnskey_rr")->AsRecordType();
dns_nsec3_rr = internal_type("dns_nsec3_rr")->AsRecordType();
dns_ds_rr = internal_type("dns_ds_rr")->AsRecordType();
dns_skip_auth = internal_val("dns_skip_auth")->AsTableVal();
dns_skip_addl = internal_val("dns_skip_addl")->AsTableVal();
dns_skip_all_auth = opt_internal_int("dns_skip_all_auth");
dns_skip_all_addl = opt_internal_int("dns_skip_all_addl");
dns_max_queries = opt_internal_int("dns_max_queries");
expensive_profiling_multiple = zeek::id::find_val("expensive_profiling_multiple")->AsCount();
profiling_interval = zeek::id::find_val("profiling_interval")->AsInterval();
segment_profiling = zeek::id::find_val("segment_profiling")->AsBool();
stp_delta = opt_internal_double("stp_delta");
stp_idle_min = opt_internal_double("stp_idle_min");
stp_skip_src = internal_val("stp_skip_src")->AsTableVal();
pkt_profile_mode = zeek::id::find_val("pkt_profile_mode")->InternalInt();
pkt_profile_freq = zeek::id::find_val("pkt_profile_freq")->AsDouble();
orig_addr_anonymization = opt_internal_int("orig_addr_anonymization");
resp_addr_anonymization = opt_internal_int("resp_addr_anonymization");
other_addr_anonymization = opt_internal_int("other_addr_anonymization");
load_sample_freq = zeek::id::find_val("load_sample_freq")->AsCount();
preserve_orig_addr = opt_internal_table("preserve_orig_addr");
preserve_resp_addr = opt_internal_table("preserve_resp_addr");
preserve_other_addr = opt_internal_table("preserve_other_addr");
dpd_reassemble_first_packets = zeek::id::find_val("dpd_reassemble_first_packets")->AsBool();
dpd_buffer_size = zeek::id::find_val("dpd_buffer_size")->AsCount();
dpd_match_only_beginning = zeek::id::find_val("dpd_match_only_beginning")->AsBool();
dpd_late_match_stop = zeek::id::find_val("dpd_late_match_stop")->AsBool();
dpd_ignore_ports = zeek::id::find_val("dpd_ignore_ports")->AsBool();
connection_status_update_interval =
opt_internal_double("connection_status_update_interval");
profiling_file = internal_val("profiling_file");
expensive_profiling_multiple =
opt_internal_int("expensive_profiling_multiple");
profiling_interval = opt_internal_double("profiling_interval");
segment_profiling = opt_internal_int("segment_profiling");
pkt_profile_mode = opt_internal_int("pkt_profile_mode");
pkt_profile_freq = opt_internal_double("pkt_profile_freq");
pkt_profile_file = opt_internal_val("pkt_profile_file");
load_sample_freq = opt_internal_int("load_sample_freq");
gap_report_freq = opt_internal_double("gap_report_freq");
irc_join_info = internal_type("irc_join_info")->AsRecordType();
irc_join_list = internal_type("irc_join_list")->AsTableType();
dpd_reassemble_first_packets =
opt_internal_int("dpd_reassemble_first_packets");
dpd_buffer_size = opt_internal_int("dpd_buffer_size");
dpd_match_only_beginning = opt_internal_int("dpd_match_only_beginning");
dpd_late_match_stop = opt_internal_int("dpd_late_match_stop");
dpd_ignore_ports = opt_internal_int("dpd_ignore_ports");
likely_server_ports = internal_val("likely_server_ports")->AsTableVal();
timer_mgr_inactivity_timeout =
opt_internal_double("timer_mgr_inactivity_timeout");
script_id = internal_type("script_id")->AsRecordType();
id_table = internal_type("id_table")->AsTableType();
record_field = internal_type("record_field")->AsRecordType();
record_field_table = internal_type("record_field_table")->AsTableType();
call_argument_vector = internal_type("call_argument_vector")->AsVectorType();
call_argument = internal_type("call_argument")->AsRecordType();
timer_mgr_inactivity_timeout = zeek::id::find_val("timer_mgr_inactivity_timeout")->AsInterval();
}

View file

@ -3,30 +3,50 @@
#pragma once
#include "Val.h"
#include "Func.h"
#include "EventRegistry.h"
#include "Stats.h"
[[deprecated("Remove in v4.1. Use zeek::id::conn_id.")]]
extern RecordType* conn_id;
[[deprecated("Remove in v4.1. Use zeek::id::endpoint.")]]
extern RecordType* endpoint;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* endpoint_stats;
[[deprecated("Remove in v4.1. Use zeek::id::connection.")]]
extern RecordType* connection_type;
[[deprecated("Remove in v4.1. Use zeek::id::fa_file.")]]
extern RecordType* fa_file_type;
[[deprecated("Remove in v4.1. Use zeek::id::fa_metadata.")]]
extern RecordType* fa_metadata_type;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* icmp_conn;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* icmp_context;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* signature_state;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* SYN_packet;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* pcap_packet;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* raw_pkt_hdr_type;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* l2_hdr_type;
[[deprecated("Remove in v4.1. Use zeek::id::transport_proto.")]]
extern EnumType* transport_proto;
[[deprecated("Remove in v4.1. Use zeek::id::string_set.")]]
extern TableType* string_set;
[[deprecated("Remove in v4.1. Use zeek::id::string_array.")]]
extern TableType* string_array;
[[deprecated("Remove in v4.1. Use zeek::id::count_set.")]]
extern TableType* count_set;
[[deprecated("Remove in v4.1. Use zeek::id::string_vec.")]]
extern VectorType* string_vec;
[[deprecated("Remove in v4.1. Use zeek::id::index_vec.")]]
extern VectorType* index_vec;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern VectorType* mime_matches;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* mime_match;
extern int watchdog_interval;
@ -55,6 +75,7 @@ extern int tcp_max_above_hole_without_any_acks;
extern int tcp_excessive_data_without_further_acks;
extern int tcp_max_old_segments;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* socks_address;
extern double non_analyzed_lifetime;
@ -65,16 +86,23 @@ extern double icmp_inactivity_timeout;
extern int tcp_storm_thresh;
extern double tcp_storm_interarrival_thresh;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* tcp_reassembler_ports_orig;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* tcp_reassembler_ports_resp;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* tcp_content_delivery_ports_orig;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* tcp_content_delivery_ports_resp;
extern bool tcp_content_deliver_all_orig;
extern bool tcp_content_deliver_all_resp;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* udp_content_delivery_ports_orig;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* udp_content_delivery_ports_resp;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* udp_content_ports;
extern bool udp_content_deliver_all_orig;
extern bool udp_content_deliver_all_resp;
@ -83,43 +111,56 @@ extern bool udp_content_delivery_ports_use_resp;
extern double dns_session_timeout;
extern double rpc_timeout;
extern ListVal* skip_authentication;
extern ListVal* direct_login_prompts;
extern ListVal* login_prompts;
extern ListVal* login_non_failure_msgs;
extern ListVal* login_failure_msgs;
extern ListVal* login_success_msgs;
extern ListVal* login_timeouts;
extern int mime_segment_length;
extern int mime_segment_overlap_length;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* mime_header_rec;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableType* mime_header_list;
extern int http_entity_data_delivery_size;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* http_stats_rec;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* http_message_stat;
extern int truncate_http_URI;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* pm_mapping;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableType* pm_mappings;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* pm_port_request;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* pm_callit_request;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* geo_location;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* entropy_test_result;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_msg;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_answer;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_soa;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_edns_additional;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_tsig_additional;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_rrsig_rr;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_dnskey_rr;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_nsec3_rr;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* dns_ds_rr;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* dns_skip_auth;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* dns_skip_addl;
extern int dns_skip_all_auth;
extern int dns_skip_all_addl;
@ -127,6 +168,7 @@ extern int dns_max_queries;
extern double stp_delta;
extern double stp_idle_min;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* stp_skip_src;
extern double table_expire_interval;
@ -135,17 +177,24 @@ extern int table_incremental_step;
extern int orig_addr_anonymization, resp_addr_anonymization;
extern int other_addr_anonymization;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* preserve_orig_addr;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* preserve_resp_addr;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* preserve_other_addr;
extern double connection_status_update_interval;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* rotate_info;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern StringVal* log_rotate_base_time;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern StringVal* peer_description;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern Val* profiling_file;
extern double profiling_interval;
extern int expensive_profiling_multiple;
@ -153,6 +202,7 @@ extern int expensive_profiling_multiple;
extern int segment_profiling;
extern int pkt_profile_mode;
extern double pkt_profile_freq;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern Val* pkt_profile_file;
extern int load_sample_freq;
@ -161,7 +211,9 @@ extern int packet_filter_default;
extern int sig_max_group_size;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableType* irc_join_list;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* irc_join_info;
extern int dpd_reassemble_first_packets;
@ -170,27 +222,35 @@ extern int dpd_match_only_beginning;
extern int dpd_late_match_stop;
extern int dpd_ignore_ports;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableVal* likely_server_ports;
extern int check_for_unused_event_handlers;
extern int suppress_local_output;
extern double timer_mgr_inactivity_timeout;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern StringVal* trace_output_file;
extern int record_all_packets;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* script_id;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableType* id_table;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* record_field;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern TableType* record_field_table;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern RecordType* call_argument;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern VectorType* call_argument_vector;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern StringVal* cmd_line_bpf_filter;
[[deprecated("Remove in v4.1. Perform your own lookup.")]]
extern StringVal* global_hash_seed;
extern bro_uint_t bits_per_uid;

View file

@ -90,7 +90,7 @@ void BroObj::BadTag(const char* msg, const char* t1, const char* t2) const
ODesc d;
DoMsg(&d, out);
reporter->FatalError("%s", d.Description());
reporter->FatalErrorWithCore("%s", d.Description());
reporter->PopLocation();
}

View file

@ -37,9 +37,11 @@ OpaqueMgr* OpaqueMgr::mgr()
return &mgr;
}
OpaqueVal::OpaqueVal(OpaqueType* t) : Val(t)
{
}
OpaqueVal::OpaqueVal(OpaqueType* t) : OpaqueVal({NewRef{}, t})
{}
OpaqueVal::OpaqueVal(IntrusivePtr<OpaqueType> t) : Val(std::move(t))
{}
OpaqueVal::~OpaqueVal()
{
@ -94,7 +96,7 @@ IntrusivePtr<OpaqueVal> OpaqueVal::Unserialize(const broker::data& data)
return val;
}
broker::expected<broker::data> OpaqueVal::SerializeType(BroType* t)
broker::expected<broker::data> OpaqueVal::SerializeType(const IntrusivePtr<BroType>& t)
{
if ( t->InternalType() == TYPE_INTERNAL_ERROR )
return broker::ec::invalid_data;
@ -110,7 +112,7 @@ broker::expected<broker::data> OpaqueVal::SerializeType(BroType* t)
return {broker::vector{false, static_cast<uint64_t>(t->Tag())}};
}
BroType* OpaqueVal::UnserializeType(const broker::data& data)
IntrusivePtr<BroType> OpaqueVal::UnserializeType(const broker::data& data)
{
auto v = caf::get_if<broker::vector>(&data);
if ( ! (v && v->size() == 2) )
@ -126,22 +128,21 @@ BroType* OpaqueVal::UnserializeType(const broker::data& data)
if ( ! name )
return nullptr;
ID* id = global_scope()->Lookup(*name);
const auto& id = global_scope()->Find(*name);
if ( ! id )
return nullptr;
BroType* t = id->AsType();
if ( ! t )
if ( ! id->IsType() )
return nullptr;
return t->Ref();
return id->GetType();
}
auto tag = caf::get_if<uint64_t>(&(*v)[1]);
if ( ! tag )
return nullptr;
return base_type(static_cast<TypeTag>(*tag)).release();
return base_type(static_cast<TypeTag>(*tag));
}
IntrusivePtr<Val> OpaqueVal::DoClone(CloneState* state)
@ -205,11 +206,14 @@ IntrusivePtr<StringVal> HashVal::DoGet()
return val_mgr->EmptyString();
}
HashVal::HashVal(OpaqueType* t) : OpaqueVal(t)
HashVal::HashVal(IntrusivePtr<OpaqueType> t) : OpaqueVal(std::move(t))
{
valid = false;
}
HashVal::HashVal(OpaqueType* t) : HashVal({NewRef{}, t})
{}
MD5Val::MD5Val() : HashVal(md5_type)
{
}
@ -222,7 +226,7 @@ MD5Val::~MD5Val()
void HashVal::digest_one(EVP_MD_CTX* h, const Val* v)
{
if ( v->Type()->Tag() == TYPE_STRING )
if ( v->GetType()->Tag() == TYPE_STRING )
{
const BroString* str = v->AsString();
hash_update(h, str->Bytes(), str->Len());
@ -696,15 +700,6 @@ bool EntropyVal::DoUnserialize(const broker::data& data)
BloomFilterVal::BloomFilterVal()
: OpaqueVal(bloomfilter_type)
{
type = nullptr;
hash = nullptr;
bloom_filter = nullptr;
}
BloomFilterVal::BloomFilterVal(OpaqueType* t)
: OpaqueVal(t)
{
type = nullptr;
hash = nullptr;
bloom_filter = nullptr;
}
@ -712,7 +707,6 @@ BloomFilterVal::BloomFilterVal(OpaqueType* t)
BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf)
: OpaqueVal(bloomfilter_type)
{
type = nullptr;
hash = nullptr;
bloom_filter = bf;
}
@ -729,38 +723,30 @@ IntrusivePtr<Val> BloomFilterVal::DoClone(CloneState* state)
return state->NewClone(this, make_intrusive<BloomFilterVal>());
}
bool BloomFilterVal::Typify(BroType* arg_type)
bool BloomFilterVal::Typify(IntrusivePtr<BroType> arg_type)
{
if ( type )
return false;
type = arg_type;
type->Ref();
type = std::move(arg_type);
auto tl = make_intrusive<TypeList>(IntrusivePtr{NewRef{}, type});
tl->Append({NewRef{}, type});
auto tl = make_intrusive<TypeList>(type);
tl->Append(type);
hash = new CompositeHash(std::move(tl));
return true;
}
BroType* BloomFilterVal::Type() const
{
return type;
}
void BloomFilterVal::Add(const Val* val)
{
HashKey* key = hash->ComputeHash(val, true);
bloom_filter->Add(key);
delete key;
auto key = hash->MakeHashKey(*val, true);
bloom_filter->Add(key.get());
}
size_t BloomFilterVal::Count(const Val* val) const
{
HashKey* key = hash->ComputeHash(val, true);
size_t cnt = bloom_filter->Count(key);
delete key;
auto key = hash->MakeHashKey(*val, true);
size_t cnt = bloom_filter->Count(key.get());
return cnt;
}
@ -818,7 +804,6 @@ IntrusivePtr<BloomFilterVal> BloomFilterVal::Merge(const BloomFilterVal* x,
BloomFilterVal::~BloomFilterVal()
{
Unref(type);
delete hash;
delete bloom_filter;
}
@ -858,8 +843,9 @@ bool BloomFilterVal::DoUnserialize(const broker::data& data)
auto no_type = caf::get_if<broker::none>(&(*v)[0]);
if ( ! no_type )
{
BroType* t = UnserializeType((*v)[0]);
if ( ! (t && Typify(t)) )
auto t = UnserializeType((*v)[0]);
if ( ! (t && Typify(std::move(t))) )
return false;
}
@ -874,7 +860,6 @@ bool BloomFilterVal::DoUnserialize(const broker::data& data)
CardinalityVal::CardinalityVal() : OpaqueVal(cardinality_type)
{
c = nullptr;
type = nullptr;
hash = nullptr;
}
@ -882,13 +867,11 @@ CardinalityVal::CardinalityVal(probabilistic::CardinalityCounter* arg_c)
: OpaqueVal(cardinality_type)
{
c = arg_c;
type = nullptr;
hash = nullptr;
}
CardinalityVal::~CardinalityVal()
{
Unref(type);
delete c;
delete hash;
}
@ -899,31 +882,24 @@ IntrusivePtr<Val> CardinalityVal::DoClone(CloneState* state)
make_intrusive<CardinalityVal>(new probabilistic::CardinalityCounter(*c)));
}
bool CardinalityVal::Typify(BroType* arg_type)
bool CardinalityVal::Typify(IntrusivePtr<BroType> arg_type)
{
if ( type )
return false;
type = arg_type;
type->Ref();
type = std::move(arg_type);
auto tl = make_intrusive<TypeList>(IntrusivePtr{NewRef{}, type});
tl->Append({NewRef{}, type});
auto tl = make_intrusive<TypeList>(type);
tl->Append(type);
hash = new CompositeHash(std::move(tl));
return true;
}
BroType* CardinalityVal::Type() const
{
return type;
}
void CardinalityVal::Add(const Val* val)
{
HashKey* key = hash->ComputeHash(val, true);
auto key = hash->MakeHashKey(*val, true);
c->AddElement(key->Hash());
delete key;
}
IMPLEMENT_OPAQUE_VALUE(CardinalityVal)
@ -961,8 +937,9 @@ bool CardinalityVal::DoUnserialize(const broker::data& data)
auto no_type = caf::get_if<broker::none>(&(*v)[0]);
if ( ! no_type )
{
BroType* t = UnserializeType((*v)[0]);
if ( ! (t && Typify(t)) )
auto t = UnserializeType((*v)[0]);
if ( ! (t && Typify(std::move(t))) )
return false;
}
@ -982,7 +959,7 @@ ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p)
IntrusivePtr<VectorVal> ParaglobVal::Get(StringVal* &pattern)
{
auto rval = make_intrusive<VectorVal>(internal_type("string_vec")->AsVectorType());
auto rval = make_intrusive<VectorVal>(zeek::id::string_vec);
std::string string_pattern (reinterpret_cast<const char*>(pattern->Bytes()), pattern->Len());
std::vector<std::string> matches = this->internal_paraglob->get(string_pattern);

View file

@ -87,7 +87,9 @@ private:
*/
class OpaqueVal : public Val {
public:
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit OpaqueVal(OpaqueType* t);
explicit OpaqueVal(IntrusivePtr<OpaqueType> t);
~OpaqueVal() override;
/**
@ -146,13 +148,13 @@ protected:
* Helper function for derived class that need to record a type
* during serialization.
*/
static broker::expected<broker::data> SerializeType(BroType* t);
static broker::expected<broker::data> SerializeType(const IntrusivePtr<BroType>& t);
/**
* Helper function for derived class that need to restore a type
* during unserialization. Returns the type at reference count +1.
*/
static BroType* UnserializeType(const broker::data& data);
static IntrusivePtr<BroType> UnserializeType(const broker::data& data);
};
namespace probabilistic {
@ -183,7 +185,10 @@ protected:
static void digest_one(EVP_MD_CTX* h, const IntrusivePtr<Val>& v);
HashVal() { valid = false; }
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit HashVal(OpaqueType* t);
explicit HashVal(IntrusivePtr<OpaqueType> t);
virtual bool DoInit();
virtual bool DoFeed(const void* data, size_t size);
@ -299,8 +304,10 @@ public:
IntrusivePtr<Val> DoClone(CloneState* state) override;
BroType* Type() const;
bool Typify(BroType* type);
const IntrusivePtr<BroType>& Type() const
{ return type; }
bool Typify(IntrusivePtr<BroType> type);
void Add(const Val* val);
size_t Count(const Val* val) const;
@ -314,7 +321,6 @@ public:
protected:
friend class Val;
BloomFilterVal();
explicit BloomFilterVal(OpaqueType* t);
DECLARE_OPAQUE_VALUE(BloomFilterVal)
private:
@ -322,7 +328,7 @@ private:
BloomFilterVal(const BloomFilterVal&);
BloomFilterVal& operator=(const BloomFilterVal&);
BroType* type;
IntrusivePtr<BroType> type;
CompositeHash* hash;
probabilistic::BloomFilter* bloom_filter;
};
@ -337,8 +343,10 @@ public:
void Add(const Val* val);
BroType* Type() const;
bool Typify(BroType* type);
const IntrusivePtr<BroType>& Type() const
{ return type; }
bool Typify(IntrusivePtr<BroType> type);
probabilistic::CardinalityCounter* Get() { return c; };
@ -347,7 +355,7 @@ protected:
DECLARE_OPAQUE_VALUE(CardinalityVal)
private:
BroType* type;
IntrusivePtr<BroType> type;
CompositeHash* hash;
probabilistic::CardinalityCounter* c;
};

View file

@ -43,11 +43,11 @@ void* PrefixTable::Insert(const IPAddr& addr, int width, void* data)
void* PrefixTable::Insert(const Val* value, void* data)
{
// [elem] -> elem
if ( value->Type()->Tag() == TYPE_LIST &&
if ( value->GetType()->Tag() == TYPE_LIST &&
value->AsListVal()->Length() == 1 )
value = value->AsListVal()->Index(0);
value = value->AsListVal()->Idx(0).get();
switch ( value->Type()->Tag() ) {
switch ( value->GetType()->Tag() ) {
case TYPE_ADDR:
return Insert(value->AsAddr(), 128, data);
break;
@ -103,11 +103,11 @@ void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const
void* PrefixTable::Lookup(const Val* value, bool exact) const
{
// [elem] -> elem
if ( value->Type()->Tag() == TYPE_LIST &&
if ( value->GetType()->Tag() == TYPE_LIST &&
value->AsListVal()->Length() == 1 )
value = value->AsListVal()->Index(0);
value = value->AsListVal()->Idx(0).get();
switch ( value->Type()->Tag() ) {
switch ( value->GetType()->Tag() ) {
case TYPE_ADDR:
return Lookup(value->AsAddr(), 128, exact);
break;
@ -119,7 +119,7 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const
default:
reporter->InternalWarning("Wrong index type %d for PrefixTable",
value->Type()->Tag());
value->GetType()->Tag());
return nullptr;
}
}
@ -142,11 +142,11 @@ void* PrefixTable::Remove(const IPAddr& addr, int width)
void* PrefixTable::Remove(const Val* value)
{
// [elem] -> elem
if ( value->Type()->Tag() == TYPE_LIST &&
if ( value->GetType()->Tag() == TYPE_LIST &&
value->AsListVal()->Length() == 1 )
value = value->AsListVal()->Index(0);
value = value->AsListVal()->Idx(0).get();
switch ( value->Type()->Tag() ) {
switch ( value->GetType()->Tag() ) {
case TYPE_ADDR:
return Remove(value->AsAddr(), 128);
break;

View file

@ -15,7 +15,7 @@
#include "Net.h"
#include "Conn.h"
#include "Timer.h"
#include "Var.h" // for internal_val()
#include "ID.h"
#include "EventHandler.h"
#include "plugin/Plugin.h"
#include "plugin/Manager.h"
@ -63,13 +63,13 @@ Reporter::~Reporter()
void Reporter::InitOptions()
{
info_to_stderr = internal_val("Reporter::info_to_stderr")->AsBool();
warnings_to_stderr = internal_val("Reporter::warnings_to_stderr")->AsBool();
errors_to_stderr = internal_val("Reporter::errors_to_stderr")->AsBool();
weird_sampling_rate = internal_val("Weird::sampling_rate")->AsCount();
weird_sampling_threshold = internal_val("Weird::sampling_threshold")->AsCount();
weird_sampling_duration = internal_val("Weird::sampling_duration")->AsInterval();
auto wl_val = internal_val("Weird::sampling_whitelist")->AsTableVal();
info_to_stderr = zeek::id::find_val("Reporter::info_to_stderr")->AsBool();
warnings_to_stderr = zeek::id::find_val("Reporter::warnings_to_stderr")->AsBool();
errors_to_stderr = zeek::id::find_val("Reporter::errors_to_stderr")->AsBool();
weird_sampling_rate = zeek::id::find_val("Weird::sampling_rate")->AsCount();
weird_sampling_threshold = zeek::id::find_val("Weird::sampling_threshold")->AsCount();
weird_sampling_duration = zeek::id::find_val("Weird::sampling_duration")->AsInterval();
auto wl_val = zeek::id::find_val("Weird::sampling_whitelist")->AsTableVal();
auto wl_table = wl_val->AsTable();
HashKey* k;
@ -78,8 +78,8 @@ void Reporter::InitOptions()
while ( (v = wl_table->NextEntry(k, c)) )
{
auto index = wl_val->RecoverIndex(k);
std::string key = index->Index(0)->AsString()->CheckString();
auto index = wl_val->RecreateIndex(*k);
std::string key = index->Idx(0)->AsString()->CheckString();
weird_sampling_whitelist.emplace(move(key));
delete k;
}
@ -349,7 +349,7 @@ void Reporter::Weird(file_analysis::File* f, const char* name, const char* addl)
return;
}
WeirdHelper(file_weird, {f->GetVal()->Ref(), new StringVal(addl)},
WeirdHelper(file_weird, {f->ToVal()->Ref(), new StringVal(addl)},
"%s", name);
}

View file

@ -11,7 +11,7 @@
#include <unordered_set>
#include <unordered_map>
#include "IPAddr.h"
#include "BroList.h"
namespace analyzer { class Analyzer; }
namespace file_analysis { class File; }
@ -35,6 +35,9 @@ protected:
InterpreterException() {}
};
class IPAddr;
class Expr;
#define FMT_ATTR __attribute__((format(printf, 2, 3))) // sic! 1st is "this" I guess.
class Reporter {

View file

@ -6,8 +6,8 @@
#include "Reporter.h"
#include "Scope.h"
#include "Func.h"
#include "ID.h"
#include "Val.h"
#include "Var.h" // for internal_type()
static inline bool is_established(const analyzer::tcp::TCP_Endpoint* e)
{
@ -129,23 +129,24 @@ bool RuleConditionPayloadSize::DoMatch(Rule* rule, RuleEndpointState* state,
RuleConditionEval::RuleConditionEval(const char* func)
{
id = global_scope()->Lookup(func);
id = global_scope()->Find(func).get();
if ( ! id )
{
rules_error("unknown identifier", func);
return;
}
if ( id->Type()->Tag() == TYPE_FUNC )
if ( id->GetType()->Tag() == TYPE_FUNC )
{
// Validate argument quantity and type.
FuncType* f = id->Type()->AsFuncType();
FuncType* f = id->GetType()->AsFuncType();
if ( f->YieldType()->Tag() != TYPE_BOOL )
if ( f->Yield()->Tag() != TYPE_BOOL )
rules_error("eval function type must yield a 'bool'", func);
static auto signature_state = zeek::id::find_type<RecordType>("signature_state");
TypeList tl;
tl.Append({NewRef{}, internal_type("signature_state")});
tl.Append(signature_state);
tl.Append(base_type(TYPE_STRING));
if ( ! f->CheckArgs(tl.Types()) )
@ -163,8 +164,8 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
return false;
}
if ( id->Type()->Tag() != TYPE_FUNC )
return id->ID_Val()->AsBool();
if ( id->GetType()->Tag() != TYPE_FUNC )
return id->GetVal()->AsBool();
// Call function with a signature_state value as argument.
zeek::Args args;
@ -180,7 +181,7 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
try
{
auto val = id->ID_Val()->AsFunc()->Call(args);
auto val = id->GetVal()->AsFunc()->Invoke(&args);
result = val && val->AsBool();
}

View file

@ -20,6 +20,8 @@
#include "File.h"
#include "Reporter.h"
#include "module_util.h"
#include "Var.h"
#include "IPAddr.h"
using namespace std;
@ -79,6 +81,7 @@ RuleHdrTest::RuleHdrTest(Prot arg_prot, Comp arg_comp, vector<IPPrefix> arg_v)
Val* RuleMatcher::BuildRuleStateValue(const Rule* rule,
const RuleEndpointState* state) const
{
static auto signature_state = zeek::id::find_type<RecordType>("signature_state");
RecordVal* val = new RecordVal(signature_state);
val->Assign(0, make_intrusive<StringVal>(rule->ID()));
val->Assign(1, state->GetAnalyzer()->ConnVal());
@ -1278,7 +1281,7 @@ static Val* get_bro_val(const char* label)
return nullptr;
}
return id->ID_Val();
return id->GetVal().get();
}
@ -1290,7 +1293,7 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to,
{
MaskedValue* mval = new MaskedValue;
switch ( v->Type()->Tag() ) {
switch ( v->GetType()->Tag() ) {
case TYPE_PORT:
mval->val = v->AsPortVal()->Port();
mval->mask = 0xffffffff;
@ -1359,18 +1362,13 @@ void id_to_maskedvallist(const char* id, maskedvalue_list* append_to,
if ( ! v )
return;
if ( v->Type()->Tag() == TYPE_TABLE )
if ( v->GetType()->Tag() == TYPE_TABLE )
{
ListVal* lv = v->AsTableVal()->ConvertToPureList();
val_list* vals = lv->Vals();
for ( const auto& val : *vals )
if ( ! val_to_maskedval(val, append_to, prefix_vector) )
{
Unref(lv);
return;
}
auto lv = v->AsTableVal()->ToPureListVal();
Unref(lv);
for ( const auto& val : lv->Vals() )
if ( ! val_to_maskedval(val.get(), append_to, prefix_vector) )
return;
}
else
@ -1386,7 +1384,7 @@ char* id_to_str(const char* id)
if ( ! v )
goto error;
if ( v->Type()->Tag() != TYPE_STRING )
if ( v->GetType()->Tag() != TYPE_STRING )
{
rules_error("Identifier must refer to string");
goto error;
@ -1409,7 +1407,7 @@ uint32_t id_to_uint(const char* id)
if ( ! v )
return 0;
TypeTag t = v->Type()->Tag();
TypeTag t = v->GetType()->Tag();
if ( t == TYPE_BOOL || t == TYPE_COUNT || t == TYPE_ENUM ||
t == TYPE_INT || t == TYPE_PORT )

View file

@ -15,58 +15,60 @@ typedef PList<Scope> scope_list;
static scope_list scopes;
static Scope* top_scope;
Scope::Scope(IntrusivePtr<ID> id, attr_list* al)
: scope_id(std::move(id))
Scope::Scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> al)
: scope_id(std::move(id)), attrs(std::move(al))
{
attrs = al;
return_type = nullptr;
inits = new id_list;
if ( id )
{
BroType* id_type = scope_id->Type();
const auto& id_type = scope_id->GetType();
if ( id_type->Tag() == TYPE_ERROR )
return;
else if ( id_type->Tag() != TYPE_FUNC )
reporter->InternalError("bad scope id");
FuncType* ft = id->Type()->AsFuncType();
return_type = {NewRef{}, ft->YieldType()};
FuncType* ft = id->GetType()->AsFuncType();
return_type = ft->Yield();
}
}
Scope::~Scope()
const IntrusivePtr<ID>& Scope::Find(std::string_view name) const
{
if ( attrs )
{
for ( const auto& attr : *attrs )
Unref(attr);
auto entry = local.find(name);
delete attrs;
if ( entry != local.end() )
return entry->second;
return ID::nil;
}
if ( inits )
IntrusivePtr<ID> Scope::Remove(std::string_view name)
{
for ( const auto& i : *inits )
Unref(i);
auto entry = local.find(name);
delete inits;
}
if ( entry != local.end() )
{
auto id = std::move(entry->second);
local.erase(entry);
return id;
}
ID* Scope::GenerateTemporary(const char* name)
{
return new ID(name, SCOPE_FUNCTION, false);
return nullptr;
}
id_list* Scope::GetInits()
IntrusivePtr<ID> Scope::GenerateTemporary(const char* name)
{
id_list* ids = inits;
inits = nullptr;
return ids;
return make_intrusive<ID>(name, SCOPE_FUNCTION, false);
}
std::vector<IntrusivePtr<ID>> Scope::GetInits()
{
auto rval = std::move(inits);
inits = {};
return rval;
}
void Scope::Describe(ODesc* d) const
@ -117,7 +119,7 @@ TraversalCode Scope::Traverse(TraversalCallback* cb) const
}
IntrusivePtr<ID> lookup_ID(const char* name, const char* curr_module,
const IntrusivePtr<ID>& lookup_ID(const char* name, const char* curr_module,
bool no_global, bool same_module_only,
bool check_export)
{
@ -129,14 +131,15 @@ IntrusivePtr<ID> lookup_ID(const char* name, const char* curr_module,
for ( int i = scopes.length() - 1; i >= 0; --i )
{
ID* id = scopes[i]->Lookup(fullname);
const auto& id = scopes[i]->Find(fullname);
if ( id )
{
if ( need_export && ! id->IsExport() && ! in_debug )
reporter->Error("identifier is not exported: %s",
fullname.c_str());
return {NewRef{}, id};
return id;
}
}
@ -144,12 +147,10 @@ IntrusivePtr<ID> lookup_ID(const char* name, const char* curr_module,
! same_module_only) )
{
std::string globalname = make_full_var_name(GLOBAL_MODULE_NAME, name);
ID* id = global_scope()->Lookup(globalname);
if ( id )
return {NewRef{}, id};
return global_scope()->Find(globalname);
}
return nullptr;
return ID::nil;
}
IntrusivePtr<ID> install_ID(const char* name, const char* module_name,
@ -188,9 +189,10 @@ void push_existing_scope(Scope* scope)
scopes.push_back(scope);
}
void push_scope(IntrusivePtr<ID> id, attr_list* attrs)
void push_scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs)
{
top_scope = new Scope(std::move(id), attrs);
top_scope = new Scope(std::move(id), std::move(attrs));
scopes.push_back(top_scope);
}

View file

@ -4,6 +4,7 @@
#include <utility>
#include <string>
#include <string_view>
#include <map>
#include "Obj.h"
@ -18,53 +19,48 @@ class ListVal;
class Scope : public BroObj {
public:
explicit Scope(IntrusivePtr<ID> id, attr_list* al);
~Scope() override;
explicit Scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> al);
const IntrusivePtr<ID>& Find(std::string_view name) const;
template<typename N>
[[deprecated("Remove in v4.1. Use Find().")]]
ID* Lookup(N&& name) const
{
const auto& entry = local.find(std::forward<N>(name));
if ( entry != local.end() )
return entry->second.get();
return nullptr;
}
{ return Find(name).get(); }
template<typename N, typename I>
void Insert(N&& name, I&& id) { local[std::forward<N>(name)] = std::forward<I>(id); }
template<typename N>
IntrusivePtr<ID> Remove(N&& name)
{
const auto& entry = local.find(std::forward<N>(name));
if ( entry != local.end() )
{
auto id = std::move(entry->second);
local.erase(entry);
return id;
}
return nullptr;
}
IntrusivePtr<ID> Remove(std::string_view name);
[[deprecated("Remove in v4.1. Use GetID().")]]
ID* ScopeID() const { return scope_id.get(); }
attr_list* Attrs() const { return attrs; }
const IntrusivePtr<ID>& GetID() const
{ return scope_id; }
const std::unique_ptr<std::vector<IntrusivePtr<Attr>>>& Attrs() const
{ return attrs; }
[[deprecated("Remove in v4.1. Use GetReturnTrype().")]]
BroType* ReturnType() const { return return_type.get(); }
const IntrusivePtr<BroType>& GetReturnType() const
{ return return_type; }
size_t Length() const { return local.size(); }
const auto& Vars() { return local; }
ID* GenerateTemporary(const char* name);
IntrusivePtr<ID> GenerateTemporary(const char* name);
// Returns the list of variables needing initialization, and
// removes it from this Scope.
id_list* GetInits();
std::vector<IntrusivePtr<ID>> GetInits();
// Adds a variable to the list.
void AddInit(IntrusivePtr<ID> id) { inits->push_back(id.release()); }
void AddInit(IntrusivePtr<ID> id)
{ inits.emplace_back(std::move(id)); }
void Describe(ODesc* d) const override;
@ -72,17 +68,17 @@ public:
protected:
IntrusivePtr<ID> scope_id;
attr_list* attrs;
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs;
IntrusivePtr<BroType> return_type;
std::map<std::string, IntrusivePtr<ID>> local;
id_list* inits;
std::map<std::string, IntrusivePtr<ID>, std::less<>> local;
std::vector<IntrusivePtr<ID>> inits;
};
extern bool in_debug;
// If no_global is true, don't search in the default "global" namespace.
extern IntrusivePtr<ID> lookup_ID(const char* name, const char* module,
extern const IntrusivePtr<ID>& lookup_ID(const char* name, const char* module,
bool no_global = false,
bool same_module_only = false,
bool check_export = true);
@ -90,7 +86,8 @@ extern IntrusivePtr<ID> lookup_ID(const char* name, const char* module,
extern IntrusivePtr<ID> install_ID(const char* name, const char* module_name,
bool is_global, bool is_export);
extern void push_scope(IntrusivePtr<ID> id, attr_list* attrs);
extern void push_scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs);
extern void push_existing_scope(Scope* scope);
// Returns the one popped off.

View file

@ -5,6 +5,7 @@
#include "DebugLogger.h"
#include "Reporter.h"
#include "net_util.h"
#include "IPAddr.h"
const float SerializationFormat::GROWTH_FACTOR = 2.5;
@ -435,4 +436,3 @@ bool BinarySerializationFormat::Write(const char* buf, int len, const char* tag)
uint32_t l = htonl(len);
return WriteData(&l, sizeof(l)) && WriteData(buf, len);
}

View file

@ -54,7 +54,7 @@ void IPTunnelTimer::Dispatch(double t, bool is_expire)
double last_active = it->second.second;
double inactive_time = t > last_active ? t - last_active : 0;
if ( inactive_time >= BifConst::Tunnel::ip_tunnel_timeout )
if ( inactive_time >= zeek::BifConst::Tunnel::ip_tunnel_timeout )
// tunnel activity timed out, delete it from map
sessions->ip_tunnels.erase(tunnel_idx);
@ -81,6 +81,7 @@ NetSessions::NetSessions()
dump_this_packet = false;
num_packets_processed = 0;
static auto pkt_profile_file = zeek::id::find_val("pkt_profile_file");
if ( pkt_profile_mode && pkt_profile_freq > 0 && pkt_profile_file )
pkt_profiler = new PacketProfiler(pkt_profile_mode,
@ -123,7 +124,7 @@ void NetSessions::NextPacket(double t, const Packet* pkt)
SegmentProfiler prof(segment_logger, "dispatching-packet");
if ( raw_packet )
mgr.Enqueue(raw_packet, IntrusivePtr{AdoptRef{}, pkt->BuildPktHdrVal()});
mgr.Enqueue(raw_packet, pkt->ToRawPktHdrVal());
if ( pkt_profiler )
pkt_profiler->ProfilePkt(t, pkt->cap_len);
@ -310,7 +311,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
{
dump_this_packet = true;
if ( esp_packet )
mgr.Enqueue(esp_packet, IntrusivePtr{AdoptRef{}, ip_hdr->BuildPktHdrVal()});
mgr.Enqueue(esp_packet, ip_hdr->ToPktHdrVal());
// Can't do more since upper-layer payloads are going to be encrypted.
return;
@ -330,8 +331,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
}
if ( mobile_ipv6_message )
mgr.Enqueue(mobile_ipv6_message,
IntrusivePtr{AdoptRef{}, ip_hdr->BuildPktHdrVal()});
mgr.Enqueue(mobile_ipv6_message, ip_hdr->ToPktHdrVal());
if ( ip_hdr->NextProto() != IPPROTO_NONE )
Weird("mobility_piggyback", pkt, encapsulation);
@ -409,7 +409,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
case IPPROTO_GRE:
{
if ( ! BifConst::Tunnel::enable_gre )
if ( ! zeek::BifConst::Tunnel::enable_gre )
{
Weird("GRE_tunnel", ip_hdr, encapsulation);
return;
@ -561,14 +561,14 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
case IPPROTO_IPV4:
case IPPROTO_IPV6:
{
if ( ! BifConst::Tunnel::enable_ip )
if ( ! zeek::BifConst::Tunnel::enable_ip )
{
Weird("IP_tunnel", ip_hdr, encapsulation);
return;
}
if ( encapsulation &&
encapsulation->Depth() >= BifConst::Tunnel::max_depth )
encapsulation->Depth() >= zeek::BifConst::Tunnel::max_depth )
{
Weird("exceeded_tunnel_max_depth", ip_hdr, encapsulation);
return;
@ -686,19 +686,18 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
conn->CheckFlowLabel(is_orig, ip_hdr->FlowLabel());
Val* pkt_hdr_val = nullptr;
IntrusivePtr<Val> pkt_hdr_val;
if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 )
{
pkt_hdr_val = ip_hdr->BuildPktHdrVal();
pkt_hdr_val = ip_hdr->ToPktHdrVal();
conn->EnqueueEvent(ipv6_ext_headers, nullptr, conn->ConnVal(),
IntrusivePtr{AdoptRef{}, pkt_hdr_val});
pkt_hdr_val);
}
if ( new_packet )
conn->EnqueueEvent(new_packet, nullptr, conn->ConnVal(), pkt_hdr_val ?
IntrusivePtr{NewRef{}, pkt_hdr_val} :
IntrusivePtr{AdoptRef{}, ip_hdr->BuildPktHdrVal()});
std::move(pkt_hdr_val) : ip_hdr->ToPktHdrVal());
conn->NextPacket(t, is_orig, ip_hdr, len, caplen, data,
record_packet, record_content, pkt);
@ -906,17 +905,17 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip,
Connection* NetSessions::FindConnection(Val* v)
{
BroType* vt = v->Type();
const auto& vt = v->GetType();
if ( ! IsRecord(vt->Tag()) )
return nullptr;
RecordType* vr = vt->AsRecordType();
const val_list* vl = v->AsRecord();
auto vl = v->AsRecord();
int orig_h, orig_p; // indices into record's value list
int resp_h, resp_p;
if ( vr == conn_id )
if ( vr == zeek::id::conn_id )
{
orig_h = 0;
orig_p = 1;
@ -1220,11 +1219,11 @@ bool NetSessions::IsLikelyServerPort(uint32_t port, TransportProto proto) const
if ( ! have_cache )
{
ListVal* lv = likely_server_ports->ConvertToPureList();
auto likely_server_ports = zeek::id::find_val<TableVal>("likely_server_ports");
auto lv = likely_server_ports->ToPureListVal();
for ( int i = 0; i < lv->Length(); i++ )
port_cache.insert(lv->Index(i)->InternalUnsigned());
port_cache.insert(lv->Idx(i)->InternalUnsigned());
have_cache = true;
Unref(lv);
}
// We exploit our knowledge of PortVal's internal storage mechanism

View file

@ -243,7 +243,7 @@ protected:
class IPTunnelTimer final : public Timer {
public:
IPTunnelTimer(double t, NetSessions::IPPair p)
: Timer(t + BifConst::Tunnel::ip_tunnel_timeout,
: Timer(t + zeek::BifConst::Tunnel::ip_tunnel_timeout,
TIMER_IP_TUNNEL_INACTIVITY), tunnel_idx(p) {}
~IPTunnelTimer() override {}

View file

@ -58,25 +58,12 @@ bool BroSubstring::DoesCover(const BroSubstring* bst) const
VectorVal* BroSubstring::VecToPolicy(Vec* vec)
{
RecordType* sw_substring_type =
internal_type("sw_substring")->AsRecordType();
if ( ! sw_substring_type )
return nullptr;
static auto sw_substring_type = zeek::id::find_type<RecordType>("sw_substring");
static auto sw_align_type = zeek::id::find_type<RecordType>("sw_align");
static auto sw_align_vec_type = zeek::id::find_type<VectorType>("sw_align_vec");
static auto sw_substring_vec_type = zeek::id::find_type<VectorType>("sw_substring_vec");
RecordType* sw_align_type =
internal_type("sw_align")->AsRecordType();
if ( ! sw_align_type )
return nullptr;
VectorType* sw_align_vec_type =
internal_type("sw_align_vec")->AsVectorType();
if ( ! sw_align_vec_type )
return nullptr;
VectorVal* result =
new VectorVal(internal_type("sw_substring_vec")->AsVectorType());
if ( ! result )
return nullptr;
auto result = make_intrusive<VectorVal>(sw_substring_vec_type);
if ( vec )
{
@ -106,7 +93,7 @@ VectorVal* BroSubstring::VecToPolicy(Vec* vec)
}
}
return result;
return result.release();
}
BroSubstring::Vec* BroSubstring::VecFromPolicy(VectorVal* vec)
@ -116,23 +103,23 @@ BroSubstring::Vec* BroSubstring::VecFromPolicy(VectorVal* vec)
// VectorVals start at index 1!
for ( unsigned int i = 1; i <= vec->Size(); ++i )
{
Val* v = vec->Lookup(i); // get the RecordVal
const auto& v = vec->At(i); // get the RecordVal
if ( ! v )
continue;
const BroString* str = v->AsRecordVal()->Lookup(0)->AsString();
const BroString* str = v->AsRecordVal()->GetField(0)->AsString();
BroSubstring* substr = new BroSubstring(*str);
const VectorVal* aligns = v->AsRecordVal()->Lookup(1)->AsVectorVal();
const VectorVal* aligns = v->AsRecordVal()->GetField(1)->AsVectorVal();
for ( unsigned int j = 1; j <= aligns->Size(); ++j )
{
const RecordVal* align = aligns->AsVectorVal()->Lookup(j)->AsRecordVal();
const BroString* str = align->Lookup(0)->AsString();
int index = align->Lookup(1)->AsCount();
const RecordVal* align = aligns->AsVectorVal()->At(j)->AsRecordVal();
const BroString* str = align->GetField(0)->AsString();
int index = align->GetField(1)->AsCount();
substr->AddAlignment(str, index);
}
bool new_alignment = v->AsRecordVal()->Lookup(2)->AsBool();
bool new_alignment = v->AsRecordVal()->GetField(2)->AsBool();
substr->MarkNewAlignment(new_alignment);
result->push_back(substr);

View file

@ -5,7 +5,7 @@
#include "Event.h"
#include "Net.h"
#include "NetVar.h"
#include "Var.h" // for internal_type()
#include "ID.h"
#include "Sessions.h"
#include "Scope.h"
#include "DNS_Mgr.h"
@ -13,6 +13,7 @@
#include "threading/Manager.h"
#include "broker/Manager.h"
#include "input.h"
#include "Func.h"
uint64_t killed_by_inactivity = 0;
@ -257,9 +258,9 @@ void ProfileLogger::Log()
// contained in some other global user-visible container.
if ( id->HasVal() )
{
Val* v = id->ID_Val();
const auto& v = id->GetVal();
size = id->ID_Val()->MemoryAllocation();
size = v->MemoryAllocation();
mem += size;
bool print = false;
@ -269,7 +270,7 @@ void ProfileLogger::Log()
if ( size > 100 * 1024 )
print = true;
if ( v->Type()->Tag() == TYPE_TABLE )
if ( v->GetType()->Tag() == TYPE_TABLE )
{
entries = v->AsTable()->Length();
total_table_entries += entries;
@ -311,9 +312,8 @@ void ProfileLogger::Log()
// (and for consistency we dispatch it *now*)
if ( profiling_update )
{
Ref(file);
mgr.Dispatch(new Event(profiling_update, {
make_intrusive<Val>(file),
make_intrusive<Val>(IntrusivePtr{NewRef{}, file}),
val_mgr->Bool(expensive),
}));
}
@ -342,7 +342,7 @@ SampleLogger::SampleLogger()
static TableType* load_sample_info = nullptr;
if ( ! load_sample_info )
load_sample_info = internal_type("load_sample_info")->AsTableType();
load_sample_info = zeek::id::find_type("load_sample_info")->AsTableType();
load_samples = new TableVal({NewRef{}, load_sample_info});
}
@ -354,16 +354,14 @@ SampleLogger::~SampleLogger()
void SampleLogger::FunctionSeen(const Func* func)
{
Val* idx = new StringVal(func->Name());
load_samples->Assign(idx, nullptr);
Unref(idx);
auto idx = make_intrusive<StringVal>(func->Name());
load_samples->Assign(std::move(idx), nullptr);
}
void SampleLogger::LocationSeen(const Location* loc)
{
Val* idx = new StringVal(loc->filename);
load_samples->Assign(idx, nullptr);
Unref(idx);
auto idx = make_intrusive<StringVal>(loc->filename);
load_samples->Assign(std::move(idx), nullptr);
}
void SampleLogger::SegmentProfile(const char* /* name */,

View file

@ -136,7 +136,7 @@ ExprListStmt::ExprListStmt(BroStmtTag t, IntrusivePtr<ListExpr> arg_l)
const expr_list& e = l->Exprs();
for ( const auto& expr : e )
{
const BroType* t = expr->Type();
const auto& t = expr->GetType();
if ( ! t || t->Tag() == TYPE_VOID )
Error("value of type void illegal");
}
@ -186,11 +186,11 @@ static BroFile* print_stdout = nullptr;
static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char* name)
{
auto id = lookup_ID(name, module_name);
const auto& id = lookup_ID(name, module_name);
assert(id);
assert(id->IsEnumConst());
EnumType* et = id->Type()->AsEnumType();
EnumType* et = id->GetType()->AsEnumType();
int index = et->Lookup(module_name, name);
assert(index >= 0);
@ -200,9 +200,10 @@ static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char
static void print_log(const std::vector<IntrusivePtr<Val>>& vals)
{
auto plval = lookup_enum_val("Log", "PRINTLOG");
auto record = make_intrusive<RecordVal>(internal_type("Log::PrintLogInfo")->AsRecordType());
auto vec = make_intrusive<VectorVal>(internal_type("string_vec")->AsVectorType());
static auto plval = lookup_enum_val("Log", "PRINTLOG");
static auto lpli = zeek::id::find_type<RecordType>("Log::PrintLogInfo");
auto record = make_intrusive<RecordVal>(lpli);
auto vec = make_intrusive<VectorVal>(zeek::id::string_vec);
for ( const auto& val : vals )
{
@ -227,7 +228,7 @@ IntrusivePtr<Val> PrintStmt::DoExec(std::vector<IntrusivePtr<Val>> vals,
BroFile* f = print_stdout;
int offset = 0;
if ( vals.size() > 0 && (vals)[0]->Type()->Tag() == TYPE_FILE )
if ( vals.size() > 0 && (vals)[0]->GetType()->Tag() == TYPE_FILE )
{
f = (vals)[0]->AsFile();
if ( ! f->IsOpen() )
@ -237,7 +238,7 @@ IntrusivePtr<Val> PrintStmt::DoExec(std::vector<IntrusivePtr<Val>> vals,
}
static auto print_log_type = static_cast<BifEnum::Log::PrintLogType>(
internal_val("Log::print_to_log")->AsEnum());
zeek::id::find_val("Log::print_to_log")->AsEnum());
switch ( print_log_type ) {
case BifEnum::Log::REDIRECT_NONE:
@ -366,7 +367,7 @@ IfStmt::IfStmt(IntrusivePtr<Expr> test,
: ExprStmt(STMT_IF, std::move(test)),
s1(std::move(arg_s1)), s2(std::move(arg_s2))
{
if ( ! e->IsError() && ! IsBool(e->Type()->Tag()) )
if ( ! e->IsError() && ! IsBool(e->GetType()->Tag()) )
e->Error("conditional in test must be boolean");
const Location* loc1 = s1->GetLocationInfo();
@ -530,7 +531,7 @@ void Case::Describe(ODesc* d) const
d->SP();
d->Add("type");
d->SP();
t[i]->Type()->Describe(d);
t[i]->GetType()->Describe(d);
if ( t[i]->Name() )
{
@ -580,7 +581,7 @@ static void int_del_func(void* v)
void SwitchStmt::Init()
{
auto t = make_intrusive<TypeList>();
t->Append({NewRef{}, e->Type()});
t->Append(e->GetType());
comp_hash = new CompositeHash(std::move(t));
case_label_value_map.SetDeleteFunc(int_del_func);
@ -605,10 +606,10 @@ SwitchStmt::SwitchStmt(IntrusivePtr<Expr> index, case_list* arg_cases)
{
have_exprs = true;
if ( ! is_atomic_type(e->Type()) )
if ( ! is_atomic_type(e->GetType()) )
e->Error("switch expression must be of an atomic type when cases are expressions");
if ( ! le->Type()->AsTypeList()->AllMatch(e->Type(), false) )
if ( ! le->GetType()->AsTypeList()->AllMatch(e->GetType(), false) )
{
le->Error("case expression type differs from switch type", e.get());
continue;
@ -677,9 +678,9 @@ SwitchStmt::SwitchStmt(IntrusivePtr<Expr> index, case_list* arg_cases)
for ( const auto& t : *tl )
{
BroType* ct = t->Type();
const auto& ct = t->GetType();
if ( ! can_cast_value_to_type(e->Type(), ct) )
if ( ! can_cast_value_to_type(e->GetType().get(), ct.get()) )
{
c->Error("cannot cast switch expression to case type");
continue;
@ -718,25 +719,21 @@ SwitchStmt::~SwitchStmt()
bool SwitchStmt::AddCaseLabelValueMapping(const Val* v, int idx)
{
HashKey* hk = comp_hash->ComputeHash(v, true);
auto hk = comp_hash->MakeHashKey(*v, true);
if ( ! hk )
{
reporter->PushLocation(e->GetLocationInfo());
reporter->InternalError("switch expression type mismatch (%s/%s)",
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
type_name(v->GetType()->Tag()), type_name(e->GetType()->Tag()));
}
int* label_idx = case_label_value_map.Lookup(hk);
int* label_idx = case_label_value_map.Lookup(hk.get());
if ( label_idx )
{
delete hk;
return false;
}
case_label_value_map.Insert(hk, new int(idx));
delete hk;
case_label_value_map.Insert(hk.get(), new int(idx));
return true;
}
@ -744,7 +741,7 @@ bool SwitchStmt::AddCaseLabelTypeMapping(ID* t, int idx)
{
for ( auto i : case_label_type_list )
{
if ( same_type(i.first->Type(), t->Type()) )
if ( same_type(i.first->GetType(), t->GetType()) )
return false;
}
@ -762,29 +759,27 @@ std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
// Find matching expression cases.
if ( case_label_value_map.Length() )
{
HashKey* hk = comp_hash->ComputeHash(v, true);
auto hk = comp_hash->MakeHashKey(*v, true);
if ( ! hk )
{
reporter->PushLocation(e->GetLocationInfo());
reporter->Error("switch expression type mismatch (%s/%s)",
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
type_name(v->GetType()->Tag()), type_name(e->GetType()->Tag()));
return std::make_pair(-1, nullptr);
}
if ( auto i = case_label_value_map.Lookup(hk) )
if ( auto i = case_label_value_map.Lookup(hk.get()) )
label_idx = *i;
delete hk;
}
// Find matching type cases.
for ( auto i : case_label_type_list )
{
auto id = i.first;
auto type = id->Type();
const auto& type = id->GetType();
if ( can_cast_value_to_type(v, type) )
if ( can_cast_value_to_type(v, type.get()) )
{
label_idx = i.second;
label_id = id;
@ -815,8 +810,8 @@ IntrusivePtr<Val> SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) con
if ( matching_id )
{
auto cv = cast_value_to_type(v, matching_id->Type());
f->SetElement(matching_id, cv.release());
auto cv = cast_value_to_type(v, matching_id->GetType().get());
f->SetElement(matching_id, std::move(cv));
}
flow = FLOW_NEXT;
@ -987,7 +982,7 @@ WhileStmt::WhileStmt(IntrusivePtr<Expr> arg_loop_condition,
: loop_condition(std::move(arg_loop_condition)), body(std::move(arg_body))
{
if ( ! loop_condition->IsError() &&
! IsBool(loop_condition->Type()->Tag()) )
! IsBool(loop_condition->GetType()->Tag()) )
loop_condition->Error("while conditional must be boolean");
}
@ -1067,35 +1062,37 @@ ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr<Expr> loop_expr)
loop_vars = arg_loop_vars;
body = nullptr;
if ( e->Type()->Tag() == TYPE_TABLE )
if ( e->GetType()->Tag() == TYPE_TABLE )
{
const type_list* indices = e->Type()->AsTableType()->IndexTypes();
if ( indices->length() != loop_vars->length() )
const auto& indices = e->GetType()->AsTableType()->IndexTypes();
if ( static_cast<int>(indices.size()) != loop_vars->length() )
{
e->Error("wrong index size");
return;
}
for ( int i = 0; i < indices->length(); i++ )
for ( auto i = 0u; i < indices.size(); i++ )
{
BroType* ind_type = (*indices)[i]->Ref();
const auto& ind_type = indices[i];
const auto& lv = (*loop_vars)[i];
const auto& lvt = lv->GetType();
if ( (*loop_vars)[i]->Type() )
if ( lvt )
{
if ( ! same_type((*loop_vars)[i]->Type(), ind_type) )
(*loop_vars)[i]->Type()->Error("type clash in iteration", ind_type);
if ( ! same_type(lvt, ind_type) )
lvt->Error("type clash in iteration", ind_type.get());
}
else
{
add_local({NewRef{}, (*loop_vars)[i]},
{NewRef{}, ind_type}, INIT_NONE,
add_local({NewRef{}, lv}, ind_type, INIT_NONE,
nullptr, nullptr, VAR_REGULAR);
}
}
}
else if ( e->Type()->Tag() == TYPE_VECTOR )
else if ( e->GetType()->Tag() == TYPE_VECTOR )
{
if ( loop_vars->length() != 1 )
{
@ -1103,7 +1100,8 @@ ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr<Expr> loop_expr)
return;
}
BroType* t = (*loop_vars)[0]->Type();
const auto& t = (*loop_vars)[0]->GetType();
if ( ! t )
add_local({NewRef{}, (*loop_vars)[0]}, base_type(TYPE_COUNT),
INIT_NONE, nullptr, nullptr, VAR_REGULAR);
@ -1115,7 +1113,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr<Expr> loop_expr)
}
}
else if ( e->Type()->Tag() == TYPE_STRING )
else if ( e->GetType()->Tag() == TYPE_STRING )
{
if ( loop_vars->length() != 1 )
{
@ -1123,7 +1121,8 @@ ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr<Expr> loop_expr)
return;
}
BroType* t = (*loop_vars)[0]->Type();
const auto& t = (*loop_vars)[0]->GetType();
if ( ! t )
add_local({NewRef{}, (*loop_vars)[0]},
base_type(TYPE_STRING),
@ -1145,20 +1144,19 @@ ForStmt::ForStmt(id_list* arg_loop_vars,
{
value_var = std::move(val_var);
if ( e->Type()->IsTable() )
if ( e->GetType()->IsTable() )
{
BroType* yield_type = e->Type()->AsTableType()->YieldType();
const auto& yield_type = e->GetType()->AsTableType()->Yield();
// Verify value_vars type if its already been defined
if ( value_var->Type() )
if ( value_var->GetType() )
{
if ( ! same_type(value_var->Type(), yield_type) )
value_var->Type()->Error("type clash in iteration", yield_type);
if ( ! same_type(value_var->GetType(), yield_type) )
value_var->GetType()->Error("type clash in iteration", yield_type.get());
}
else
{
add_local(value_var, {NewRef{}, yield_type}, INIT_NONE,
nullptr, nullptr, VAR_REGULAR);
add_local(value_var, yield_type, INIT_NONE, nullptr, nullptr, VAR_REGULAR);
}
}
else
@ -1176,7 +1174,7 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{
IntrusivePtr<Val> ret;
if ( v->Type()->Tag() == TYPE_TABLE )
if ( v->GetType()->Tag() == TYPE_TABLE )
{
TableVal* tv = v->AsTableVal();
const PDict<TableEntryVal>* loop_vals = tv->AsTable();
@ -1189,14 +1187,14 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
IterCookie* c = loop_vals->InitForIteration();
while ( (current_tev = loop_vals->NextEntry(k, c)) )
{
auto ind_lv = tv->RecoverIndex(k);
auto ind_lv = tv->RecreateIndex(*k);
delete k;
if ( value_var )
f->SetElement(value_var.get(), current_tev->Value()->Ref());
f->SetElement(value_var, current_tev->GetVal());
for ( int i = 0; i < ind_lv->Length(); i++ )
f->SetElement((*loop_vars)[i], ind_lv->Index(i)->Ref());
f->SetElement((*loop_vars)[i], ind_lv->Idx(i));
flow = FLOW_NEXT;
@ -1220,19 +1218,19 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
}
}
else if ( v->Type()->Tag() == TYPE_VECTOR )
else if ( v->GetType()->Tag() == TYPE_VECTOR )
{
VectorVal* vv = v->AsVectorVal();
for ( auto i = 0u; i <= vv->Size(); ++i )
{
// Skip unassigned vector indices.
if ( ! vv->Lookup(i) )
if ( ! vv->At(i) )
continue;
// Set the loop variable to the current index, and make
// another pass over the loop body.
f->SetElement((*loop_vars)[0], val_mgr->Count(i).release());
f->SetElement((*loop_vars)[0], val_mgr->Count(i));
flow = FLOW_NEXT;
ret = body->Exec(f, flow);
@ -1240,14 +1238,14 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
break;
}
}
else if ( v->Type()->Tag() == TYPE_STRING )
else if ( v->GetType()->Tag() == TYPE_STRING )
{
StringVal* sval = v->AsStringVal();
for ( int i = 0; i < sval->Len(); ++i )
{
f->SetElement((*loop_vars)[0],
new StringVal(1, (const char*) sval->Bytes() + i));
auto sv = make_intrusive<StringVal>(1, (const char*) sval->Bytes() + i);
f->SetElement((*loop_vars)[0], std::move(sv));
flow = FLOW_NEXT;
ret = body->Exec(f, flow);
@ -1416,21 +1414,21 @@ ReturnStmt::ReturnStmt(IntrusivePtr<Expr> arg_e)
{
Scope* s = current_scope();
if ( ! s || ! s->ScopeID() )
if ( ! s || ! s->GetID() )
{
Error("return statement outside of function/event");
return;
}
FuncType* ft = s->ScopeID()->Type()->AsFuncType();
BroType* yt = ft->YieldType();
FuncType* ft = s->GetID()->GetType()->AsFuncType();
const auto& yt = ft->Yield();
if ( s->ScopeID()->DoInferReturnType() )
if ( s->GetID()->DoInferReturnType() )
{
if ( e )
{
ft->SetYieldType({NewRef{}, e->Type()});
s->ScopeID()->SetInferReturnType(false);
ft->SetYieldType(e->GetType());
s->GetID()->SetInferReturnType(false);
}
}
@ -1448,7 +1446,7 @@ ReturnStmt::ReturnStmt(IntrusivePtr<Expr> arg_e)
else
{
auto promoted_e = check_and_promote_expr(e.get(), yt);
auto promoted_e = check_and_promote_expr(e.get(), yt.get());
if ( promoted_e )
e = std::move(promoted_e);
@ -1631,19 +1629,12 @@ void EventBodyList::Describe(ODesc* d) const
StmtList::Describe(d);
}
InitStmt::InitStmt(id_list* arg_inits) : Stmt(STMT_INIT)
InitStmt::InitStmt(std::vector<IntrusivePtr<ID>> arg_inits) : Stmt(STMT_INIT)
{
inits = arg_inits;
if ( arg_inits && arg_inits->length() )
SetLocationInfo((*arg_inits)[0]->GetLocationInfo());
}
inits = std::move(arg_inits);
InitStmt::~InitStmt()
{
for ( const auto& init : *inits )
Unref(init);
delete inits;
if ( ! inits.empty() )
SetLocationInfo(inits[0]->GetLocationInfo());
}
IntrusivePtr<Val> InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
@ -1651,27 +1642,28 @@ IntrusivePtr<Val> InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
RegisterAccess();
flow = FLOW_NEXT;
for ( const auto& aggr : *inits )
for ( const auto& aggr : inits )
{
BroType* t = aggr->Type();
const auto& t = aggr->GetType();
Val* v = nullptr;
IntrusivePtr<Val> v;
switch ( t->Tag() ) {
case TYPE_RECORD:
v = new RecordVal(t->AsRecordType());
v = make_intrusive<RecordVal>(cast_intrusive<RecordType>(t));
break;
case TYPE_VECTOR:
v = new VectorVal(t->AsVectorType());
v = make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
break;
case TYPE_TABLE:
v = new TableVal({NewRef{}, t->AsTableType()}, {NewRef{}, aggr->Attrs()});
v = make_intrusive<TableVal>(cast_intrusive<TableType>(t),
aggr->GetAttrs());
break;
default:
break;
}
f->SetElement(aggr, v);
f->SetElement(aggr, std::move(v));
}
return nullptr;
@ -1682,14 +1674,14 @@ void InitStmt::Describe(ODesc* d) const
AddTag(d);
if ( ! d->IsReadable() )
d->AddCount(inits->length());
d->AddCount(inits.size());
loop_over_list(*inits, i)
for ( size_t i = 0; i < inits.size(); ++i )
{
if ( ! d->IsBinary() && i > 0 )
d->AddSP(",");
(*inits)[i]->Describe(d);
inits[i]->Describe(d);
}
DescribeDone(d);
@ -1700,7 +1692,7 @@ TraversalCode InitStmt::Traverse(TraversalCallback* cb) const
TraversalCode tc = cb->PreStmt(this);
HANDLE_TC_STMT_PRE(tc);
for ( const auto& init : *inits )
for ( const auto& init : inits )
{
tc = init->Traverse(cb);
HANDLE_TC_STMT_PRE(tc);
@ -1749,7 +1741,7 @@ WhenStmt::WhenStmt(IntrusivePtr<Expr> arg_cond,
assert(cond);
assert(s1);
if ( ! cond->IsError() && ! IsBool(cond->Type()->Tag()) )
if ( ! cond->IsError() && ! IsBool(cond->GetType()->Tag()) )
cond->Error("conditional in test must be boolean");
if ( timeout )
@ -1757,7 +1749,7 @@ WhenStmt::WhenStmt(IntrusivePtr<Expr> arg_cond,
if ( timeout->IsError() )
return;
TypeTag bt = timeout->Type()->Tag();
TypeTag bt = timeout->GetType()->Tag();
if ( bt != TYPE_TIME && bt != TYPE_INTERVAL )
cond->Error("when timeout requires a time or time interval");
}

View file

@ -393,20 +393,19 @@ protected:
class InitStmt final : public Stmt {
public:
explicit InitStmt(id_list* arg_inits);
~InitStmt() override;
explicit InitStmt(std::vector<IntrusivePtr<ID>> arg_inits);
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
const id_list* Inits() const { return inits; }
const std::vector<IntrusivePtr<ID>>& Inits() const
{ return inits; }
void Describe(ODesc* d) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
id_list* inits;
std::vector<IntrusivePtr<ID>> inits;
};
class NullStmt final : public Stmt {

View file

@ -4,37 +4,40 @@
#include "Val.h"
#include "IntrusivePtr.h"
Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype)
Tag::Tag(const IntrusivePtr<EnumType>& etype, type_t arg_type, subtype_t arg_subtype)
{
assert(arg_type > 0);
type = arg_type;
subtype = arg_subtype;
int64_t i = (int64_t)(type) | ((int64_t)subtype << 31);
Ref(etype);
val = etype->GetVal(i).release();
val = etype->GetVal(i);
}
Tag::Tag(EnumVal* arg_val)
Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype)
: Tag({NewRef{}, etype}, arg_type, arg_subtype)
{ }
Tag::Tag(IntrusivePtr<EnumVal> arg_val)
{
assert(arg_val);
val = arg_val;
Ref(val);
val = std::move(arg_val);
int64_t i = val->InternalInt();
type = i & 0xffffffff;
subtype = (i >> 31) & 0xffffffff;
}
Tag::Tag(EnumVal* arg_val)
: Tag({NewRef{}, arg_val})
{ }
Tag::Tag(const Tag& other)
{
type = other.type;
subtype = other.subtype;
val = other.val;
if ( val )
Ref(val);
}
Tag::Tag()
@ -44,11 +47,7 @@ Tag::Tag()
val = nullptr;
}
Tag::~Tag()
{
Unref(val);
val = nullptr;
}
Tag::~Tag() = default;
Tag& Tag::operator=(const Tag& other)
{
@ -56,11 +55,7 @@ Tag& Tag::operator=(const Tag& other)
{
type = other.type;
subtype = other.subtype;
Unref(val);
val = other.val;
if ( val )
Ref(val);
}
return *this;
@ -72,26 +67,28 @@ Tag& Tag::operator=(const Tag&& other) noexcept
{
type = other.type;
subtype = other.subtype;
Unref(val);
val = other.val;
other.val = nullptr;
val = std::move(other.val);
}
return *this;
}
EnumVal* Tag::AsEnumVal(EnumType* etype) const
const IntrusivePtr<EnumVal>& Tag::AsVal(const IntrusivePtr<EnumType>& etype) const
{
if ( ! val )
{
assert(type == 0 && subtype == 0);
Ref(etype);
val = etype->GetVal(0).release();
val = etype->GetVal(0);
}
return val;
}
EnumVal* Tag::AsEnumVal(EnumType* etype) const
{
return AsVal({NewRef{}, etype}).get();
}
std::string Tag::AsString() const
{
return fmt("%" PRIu32 "/%" PRIu32, type, subtype);

View file

@ -3,6 +3,7 @@
#pragma once
#include "zeek-config.h"
#include "IntrusivePtr.h"
#include <string>
@ -114,6 +115,9 @@ protected:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal(const IntrusivePtr<EnumType>& etype) const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal(EnumType* etype) const;
/**
@ -127,6 +131,9 @@ protected:
* @param subtype The sub type, which is left to an analyzer for
* interpretation. By default it's set to zero.
*/
Tag(const IntrusivePtr<EnumType>& etype, type_t type, subtype_t subtype = 0);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr& instead.")]]
Tag(EnumType* etype, type_t type, subtype_t subtype = 0);
/**
@ -134,10 +141,13 @@ protected:
*
* @param val An enum value of script type \c Analyzer::Tag.
*/
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit Tag(EnumVal* val);
private:
type_t type; // Main type.
subtype_t subtype; // Subtype.
mutable EnumVal* val; // Script-layer value.
mutable IntrusivePtr<EnumVal> val; // Script-layer value.
};

View file

@ -50,7 +50,8 @@ TraversalCode TriggerTraversalCallback::PreExpr(const Expr* expr)
if ( e->Id()->IsGlobal() )
trigger->Register(e->Id());
Val* v = e->Id()->ID_Val();
Val* v = e->Id()->GetVal().get();
if ( v && v->Modifiable() )
trigger->Register(v);
break;

View file

@ -16,17 +16,17 @@ EncapsulatingConn::EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t)
}
}
RecordVal* EncapsulatingConn::GetRecordVal() const
IntrusivePtr<RecordVal> EncapsulatingConn::ToVal() const
{
RecordVal *rv = new RecordVal(BifType::Record::Tunnel::EncapsulatingConn);
auto rv = make_intrusive<RecordVal>(zeek::BifType::Record::Tunnel::EncapsulatingConn);
auto id_val = make_intrusive<RecordVal>(conn_id);
auto id_val = make_intrusive<RecordVal>(zeek::id::conn_id);
id_val->Assign(0, make_intrusive<AddrVal>(src_addr));
id_val->Assign(1, val_mgr->Port(ntohs(src_port), proto));
id_val->Assign(2, make_intrusive<AddrVal>(dst_addr));
id_val->Assign(3, val_mgr->Port(ntohs(dst_port), proto));
rv->Assign(0, std::move(id_val));
rv->Assign(1, BifType::Enum::Tunnel::Type->GetVal(type));
rv->Assign(1, zeek::BifType::Enum::Tunnel::Type->GetVal(type));
rv->Assign(2, make_intrusive<StringVal>(uid.Base62("C").c_str()));

View file

@ -3,9 +3,10 @@
#pragma once
#include "zeek-config.h"
#include "IntrusivePtr.h"
#include "NetVar.h"
#include "IPAddr.h"
#include "Var.h" // for internal_type()
#include "ID.h"
#include "UID.h"
#include <vector>
@ -79,7 +80,11 @@ public:
/**
* Returns record value of type "EncapsulatingConn" representing the tunnel.
*/
RecordVal* GetRecordVal() const;
IntrusivePtr<RecordVal> ToVal() const;
[[deprecated("Remove in v4.1. Use ToVal() instead.")]]
RecordVal* GetRecordVal() const
{ return ToVal().release(); }
friend bool operator==(const EncapsulatingConn& ec1,
const EncapsulatingConn& ec2)
@ -190,20 +195,24 @@ public:
* Get the value of type "EncapsulatingConnVector" represented by the
* entire encapsulation chain.
*/
VectorVal* GetVectorVal() const
IntrusivePtr<VectorVal> ToVal() const
{
VectorVal* vv = new VectorVal(
internal_type("EncapsulatingConnVector")->AsVectorType());
auto vv = make_intrusive<VectorVal>(
zeek::id::find_type<VectorType>("EncapsulatingConnVector"));
if ( conns )
{
for ( size_t i = 0; i < conns->size(); ++i )
vv->Assign(i, (*conns)[i].GetRecordVal());
vv->Assign(i, (*conns)[i].ToVal());
}
return vv;
}
[[deprecated("Remove in v4.1. Use ToVal() instead.")]]
VectorVal* GetVectorVal() const
{ return ToVal().release(); }
friend bool operator==(const EncapsulationStack& e1,
const EncapsulationStack& e2);

File diff suppressed because it is too large Load diff

View file

@ -141,6 +141,8 @@ const int MATCHES_INDEX_VECTOR = 2;
class BroType : public BroObj {
public:
static inline const IntrusivePtr<BroType> nil;
explicit BroType(TypeTag tag, bool base_type = false);
// Performs a shallow clone operation of the Bro type.
@ -151,7 +153,7 @@ public:
// Clone operations will mostly be implemented in the derived classes;
// in addition cloning will be limited to classes that can be reached by
// the script-level.
virtual BroType* ShallowClone();
virtual IntrusivePtr<BroType> ShallowClone();
TypeTag Tag() const { return tag; }
InternalTypeTag InternalType() const { return internal_tag; }
@ -171,15 +173,22 @@ public:
// Returns the type yielded by this type. For example, if
// this type is a table[string] of port, then returns the "port"
// type. Returns nil if this is not an index type.
virtual BroType* YieldType();
virtual const IntrusivePtr<BroType>& Yield() const;
[[deprecated("Remove in v4.1. Use Yield() instead.")]]
virtual BroType* YieldType()
{ return Yield().get(); }
[[deprecated("Remove in v4.1. Use Yield() instead.")]]
virtual const BroType* YieldType() const
{ return ((BroType*) this)->YieldType(); }
{ return Yield().get(); }
// Returns true if this type is a record and contains the
// given field, false otherwise.
[[deprecated("Remove in v4.1. Use RecordType::HasField() directly.")]]
virtual bool HasField(const char* field) const;
// Returns the type of the given field, or nil if no such field.
[[deprecated("Remove in v4.1. Use RecordType::GetFieldType() directly.")]]
virtual BroType* FieldType(const char* field) const;
#define CHECK_TYPE_TAG(tag_type, func_name) \
@ -305,12 +314,12 @@ public:
bool IsSet() const
{
return tag == TYPE_TABLE && (YieldType() == nullptr);
return tag == TYPE_TABLE && ! Yield();
}
bool IsTable() const
{
return tag == TYPE_TABLE && (YieldType() != nullptr);
return tag == TYPE_TABLE && Yield();
}
BroType* Ref() { ::Ref(this); return this; }
@ -353,22 +362,27 @@ public:
{
}
~TypeList() override;
const type_list* Types() const { return &types; }
type_list* Types() { return &types; }
const std::vector<IntrusivePtr<BroType>>& Types() const
{ return types; }
bool IsPure() const { return pure_type != nullptr; }
// Returns the underlying pure type, or nil if the list
// is not pure or is empty.
const IntrusivePtr<BroType>& GetPureType() const
{ return pure_type; }
[[deprecated("Remove in v4.1. Use GetPureType() instead.")]]
BroType* PureType() { return pure_type.get(); }
[[deprecated("Remove in v4.1. Use GetPureType() instead.")]]
const BroType* PureType() const { return pure_type.get(); }
// True if all of the types match t, false otherwise. If
// is_init is true, then the matching is done in the context
// of an initialization.
bool AllMatch(const BroType* t, bool is_init) const;
bool AllMatch(const IntrusivePtr<BroType>& t, bool is_init) const
{ return AllMatch(t.get(), is_init); }
void Append(IntrusivePtr<BroType> t);
void AppendEvenIfNotPure(IntrusivePtr<BroType> t);
@ -379,17 +393,24 @@ public:
protected:
IntrusivePtr<BroType> pure_type;
type_list types;
std::vector<IntrusivePtr<BroType>> types;
};
class IndexType : public BroType {
public:
int MatchesIndex(ListExpr* index) const override;
const IntrusivePtr<TypeList>& GetIndices() const
{ return indices; }
[[deprecated("Remove in v4.1. Use GetIndices().")]]
TypeList* Indices() const { return indices.get(); }
const type_list* IndexTypes() const { return indices->Types(); }
BroType* YieldType() override;
const BroType* YieldType() const override;
const std::vector<IntrusivePtr<BroType>>& IndexTypes() const
{ return indices->Types(); }
const IntrusivePtr<BroType>& Yield() const override
{ return yield_type; }
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool roles_only = false) const override;
@ -415,14 +436,11 @@ class TableType : public IndexType {
public:
TableType(IntrusivePtr<TypeList> ind, IntrusivePtr<BroType> yield);
TableType* ShallowClone() override;
IntrusivePtr<BroType> ShallowClone() override;
// Returns true if this table type is "unspecified", which is
// what one gets using an empty "set()" or "table()" constructor.
bool IsUnspecifiedTable() const;
protected:
TypeList* ExpandRecordIndex(RecordType* rt) const;
};
class SetType final : public TableType {
@ -430,16 +448,22 @@ public:
SetType(IntrusivePtr<TypeList> ind, IntrusivePtr<ListExpr> arg_elements);
~SetType() override;
SetType* ShallowClone() override;
IntrusivePtr<BroType> ShallowClone() override;
[[deprecated("Remove in v4.1. Use Elements() isntead.")]]
ListExpr* SetElements() const { return elements.get(); }
const IntrusivePtr<ListExpr>& Elements() const
{ return elements; }
protected:
IntrusivePtr<ListExpr> elements;
};
class FuncType final : public BroType {
public:
static inline const IntrusivePtr<FuncType> nil;
/**
* Prototype is only currently used for events and hooks which declare
* multiple signature prototypes that allow users to have handlers
@ -453,13 +477,19 @@ public:
FuncType(IntrusivePtr<RecordType> args, IntrusivePtr<BroType> yield,
function_flavor f);
FuncType* ShallowClone() override;
IntrusivePtr<BroType> ShallowClone() override;
~FuncType() override;
[[deprecated("Remove in v4.1. Use Params().")]]
RecordType* Args() const { return args.get(); }
BroType* YieldType() override;
const BroType* YieldType() const override;
const IntrusivePtr<RecordType>& Params() const
{ return args; }
const IntrusivePtr<BroType>& Yield() const override
{ return yield; }
void SetYieldType(IntrusivePtr<BroType> arg_yield) { yield = std::move(arg_yield); }
function_flavor Flavor() const { return flavor; }
std::string FlavorString() const;
@ -470,9 +500,15 @@ public:
int MatchesIndex(ListExpr* index) const override;
bool CheckArgs(const type_list* args, bool is_init = false) const;
bool CheckArgs(const std::vector<IntrusivePtr<BroType>>& args,
bool is_init = false) const;
[[deprecated("Remove in v4.1. Use ParamList().")]]
TypeList* ArgTypes() const { return arg_types.get(); }
const IntrusivePtr<TypeList>& ParamList() const
{ return arg_types; }
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool roles_only = false) const override;
@ -493,6 +529,8 @@ public:
{ return prototypes; }
protected:
friend IntrusivePtr<FuncType> make_intrusive<FuncType>();
FuncType() : BroType(TYPE_FUNC) { flavor = FUNC_FLAVOR_FUNCTION; }
IntrusivePtr<RecordType> args;
IntrusivePtr<TypeList> arg_types;
@ -504,9 +542,18 @@ protected:
class TypeType final : public BroType {
public:
explicit TypeType(IntrusivePtr<BroType> t) : BroType(TYPE_TYPE), type(std::move(t)) {}
TypeType* ShallowClone() override { return new TypeType(type); }
IntrusivePtr<BroType> ShallowClone() override { return make_intrusive<TypeType>(type); }
const IntrusivePtr<BroType>& GetType() const
{ return type; }
template <class T>
IntrusivePtr<T> GetType() const
{ return cast_intrusive<T>(type); }
[[deprecated("Remove in v4.1. Use GetType().")]]
BroType* Type() { return type.get(); }
[[deprecated("Remove in v4.1. Use GetType().")]]
const BroType* Type() const { return type.get(); }
protected:
@ -515,18 +562,23 @@ protected:
class TypeDecl final {
public:
TypeDecl(IntrusivePtr<BroType> t, const char* i, attr_list* attrs = nullptr, bool in_record = false);
TypeDecl() = default;
TypeDecl(const char* i, IntrusivePtr<BroType> t, IntrusivePtr<Attributes> attrs = nullptr);
TypeDecl(const TypeDecl& other);
~TypeDecl();
[[deprecated("Remove in v4.1. Use GetAttr().")]]
const Attr* FindAttr(attr_tag a) const
{ return attrs ? attrs->FindAttr(a) : nullptr; }
{ return attrs ? attrs->Find(a).get() : nullptr; }
const IntrusivePtr<Attr>& GetAttr(attr_tag a) const
{ return attrs ? attrs->Find(a) : Attr::nil; }
void DescribeReST(ODesc* d, bool roles_only = false) const;
IntrusivePtr<BroType> type;
IntrusivePtr<Attributes> attrs;
const char* id;
const char* id = nullptr;
};
typedef PList<TypeDecl> type_decl_list;
@ -534,13 +586,53 @@ typedef PList<TypeDecl> type_decl_list;
class RecordType final : public BroType {
public:
explicit RecordType(type_decl_list* types);
RecordType* ShallowClone() override;
IntrusivePtr<BroType> ShallowClone() override;
~RecordType() override;
bool HasField(const char* field) const override;
BroType* FieldType(const char* field) const override;
BroType* FieldType(int field) const;
[[deprecated("Remove in v4.1. Use GetFieldType() instead (note it doesn't check for invalid names).")]]
BroType* FieldType(const char* field) const override
{
auto offset = FieldOffset(field);
return offset >= 0 ? GetFieldType(offset).get() : nullptr;
}
[[deprecated("Remove in v4.1. Use GetFieldType() instead.")]]
BroType* FieldType(int field) const
{ return GetFieldType(field).get(); }
/**
* Looks up a field by name and returns its type. No check for invalid
* field name is performed.
*/
const IntrusivePtr<BroType>& GetFieldType(const char* field_name) const
{ return GetFieldType(FieldOffset(field_name)); }
/**
* Looks up a field by name and returns its type as cast to @c T.
* No check for invalid field name is performed.
*/
template <class T>
IntrusivePtr<T> GetFieldType(const char* field_name) const
{ return cast_intrusive<T>(GetFieldType(field_name)); }
/**
* Looks up a field by its index and returns its type. No check for
* invalid field offset is performed.
*/
const IntrusivePtr<BroType>& GetFieldType(int field_index) const
{ return (*types)[field_index]->type; }
/**
* Looks up a field by its index and returns its type as cast to @c T.
* No check for invalid field offset is performed.
*/
template <class T>
IntrusivePtr<T> GetFieldType(int field_index) const
{ return cast_intrusive<T>((*types)[field_index]->type); }
IntrusivePtr<Val> FieldDefault(int field) const;
// A field's offset is its position in the type_decl_list,
@ -565,9 +657,9 @@ public:
*/
IntrusivePtr<TableVal> GetRecordFieldsVal(const RecordVal* rv = nullptr) const;
// Returns 0 if all is ok, otherwise a pointer to an error message.
// Takes ownership of list.
const char* AddFields(type_decl_list* types, attr_list* attr);
// Returns null if all is ok, otherwise a pointer to an error message.
const char* AddFields(const type_decl_list& types,
bool add_log_attr = false);
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool roles_only = false) const override;
@ -577,13 +669,13 @@ public:
bool IsFieldDeprecated(int field) const
{
const TypeDecl* decl = FieldDecl(field);
return decl && decl->FindAttr(ATTR_DEPRECATED) != nullptr;
return decl && decl->GetAttr(ATTR_DEPRECATED) != nullptr;
}
bool FieldHasAttr(int field, attr_tag at) const
{
const TypeDecl* decl = FieldDecl(field);
return decl && decl->FindAttr(at) != nullptr;
return decl && decl->GetAttr(at) != nullptr;
}
std::string GetFieldDeprecationWarning(int field, bool has_check) const;
@ -604,10 +696,11 @@ public:
class FileType final : public BroType {
public:
explicit FileType(IntrusivePtr<BroType> yield_type);
FileType* ShallowClone() override { return new FileType(yield); }
IntrusivePtr<BroType> ShallowClone() override { return make_intrusive<FileType>(yield); }
~FileType() override;
BroType* YieldType() override;
const IntrusivePtr<BroType>& Yield() const override
{ return yield; }
void Describe(ODesc* d) const override;
@ -618,7 +711,7 @@ protected:
class OpaqueType final : public BroType {
public:
explicit OpaqueType(const std::string& name);
OpaqueType* ShallowClone() override { return new OpaqueType(name); }
IntrusivePtr<BroType> ShallowClone() override { return make_intrusive<OpaqueType>(name); }
~OpaqueType() override { };
const std::string& Name() const { return name; }
@ -638,7 +731,7 @@ public:
explicit EnumType(const EnumType* e);
explicit EnumType(const std::string& arg_name);
EnumType* ShallowClone() override;
IntrusivePtr<BroType> ShallowClone() override;
~EnumType() override;
// The value of this name is next internal counter value, starting
@ -660,7 +753,7 @@ public:
void DescribeReST(ODesc* d, bool roles_only = false) const override;
IntrusivePtr<EnumVal> GetVal(bro_int_t i);
const IntrusivePtr<EnumVal>& GetVal(bro_int_t i);
protected:
void AddNameInternal(const std::string& module_name,
@ -688,10 +781,10 @@ protected:
class VectorType final : public BroType {
public:
explicit VectorType(IntrusivePtr<BroType> t);
VectorType* ShallowClone() override;
IntrusivePtr<BroType> ShallowClone() override;
~VectorType() override;
BroType* YieldType() override;
const BroType* YieldType() const override;
const IntrusivePtr<BroType>& Yield() const override;
int MatchesIndex(ListExpr* index) const override;
@ -706,33 +799,46 @@ protected:
IntrusivePtr<BroType> yield_type;
};
extern OpaqueType* md5_type;
extern OpaqueType* sha1_type;
extern OpaqueType* sha256_type;
extern OpaqueType* entropy_type;
extern OpaqueType* cardinality_type;
extern OpaqueType* topk_type;
extern OpaqueType* bloomfilter_type;
extern OpaqueType* x509_opaque_type;
extern OpaqueType* ocsp_resp_opaque_type;
extern OpaqueType* paraglob_type;
extern IntrusivePtr<OpaqueType> md5_type;
extern IntrusivePtr<OpaqueType> sha1_type;
extern IntrusivePtr<OpaqueType> sha256_type;
extern IntrusivePtr<OpaqueType> entropy_type;
extern IntrusivePtr<OpaqueType> cardinality_type;
extern IntrusivePtr<OpaqueType> topk_type;
extern IntrusivePtr<OpaqueType> bloomfilter_type;
extern IntrusivePtr<OpaqueType> x509_opaque_type;
extern IntrusivePtr<OpaqueType> ocsp_resp_opaque_type;
extern IntrusivePtr<OpaqueType> paraglob_type;
// Returns the basic (non-parameterized) type with the given type.
const IntrusivePtr<BroType>& base_type(TypeTag tag);
// Returns the basic (non-parameterized) type with the given type.
// The reference count of the type is not increased.
BroType* base_type_no_ref(TypeTag tag);
// Returns the basic (non-parameterized) type with the given type.
// The caller assumes responsibility for a reference to the type.
inline IntrusivePtr<BroType> base_type(TypeTag tag)
{ return {NewRef{}, base_type_no_ref(tag)}; }
[[deprecated("Remove in v4.1. Use ::base_type() instead")]]
inline BroType* base_type_no_ref(TypeTag tag)
{ return base_type(tag).get(); }
// Returns the basic error type.
inline IntrusivePtr<BroType> error_type() { return base_type(TYPE_ERROR); }
inline const IntrusivePtr<BroType>& error_type() { return base_type(TYPE_ERROR); }
// True if the two types are equivalent. If is_init is true then the test is
// done in the context of an initialization. If match_record_field_names is
// true then for record types the field names have to match, too.
extern bool same_type(const BroType* t1, const BroType* t2, bool is_init=false, bool match_record_field_names=true);
extern bool same_type(const BroType& t1, const BroType& t2,
bool is_init=false, bool match_record_field_names=true);
inline bool same_type(const IntrusivePtr<BroType>& t1, const IntrusivePtr<BroType>& t2,
bool is_init=false, bool match_record_field_names=true)
{ return same_type(*t1, *t2, is_init, match_record_field_names); }
inline bool same_type(const BroType* t1, const BroType* t2,
bool is_init=false, bool match_record_field_names=true)
{ return same_type(*t1, *t2, is_init, match_record_field_names); }
inline bool same_type(const IntrusivePtr<BroType>& t1, const BroType* t2,
bool is_init=false, bool match_record_field_names=true)
{ return same_type(*t1, *t2, is_init, match_record_field_names); }
inline bool same_type(const BroType* t1, const IntrusivePtr<BroType>& t2,
bool is_init=false, bool match_record_field_names=true)
{ return same_type(*t1, *t2, is_init, match_record_field_names); }
// True if the two attribute lists are equivalent.
extern bool same_attrs(const Attributes* a1, const Attributes* a2);
@ -753,7 +859,8 @@ extern TypeTag max_type(TypeTag t1, TypeTag t2);
// Given two types, returns the "merge", in which promotable types
// are promoted to the maximum of the two. Returns nil (and generates
// an error message) if the types are incompatible.
IntrusivePtr<BroType> merge_types(const BroType* t1, const BroType* t2);
IntrusivePtr<BroType> merge_types(const IntrusivePtr<BroType>& t1,
const IntrusivePtr<BroType>& t2);
// Given a list of expressions, returns a (ref'd) type reflecting
// a merged type consistent across all of them, or nil if this
@ -764,10 +871,16 @@ IntrusivePtr<BroType> merge_type_list(ListExpr* elements);
IntrusivePtr<BroType> init_type(Expr* init);
// Returns true if argument is an atomic type.
bool is_atomic_type(const BroType* t);
bool is_atomic_type(const BroType& t);
inline bool is_atomic_type(const BroType* t)
{ return is_atomic_type(*t); }
inline bool is_atomic_type(const IntrusivePtr<BroType>& t)
{ return is_atomic_type(*t); }
// True if the given type tag corresponds to type that can be assigned to.
extern bool is_assignable(BroType* t);
extern bool is_assignable(TypeTag t);
inline bool is_assignable(BroType* t)
{ return ::is_assignable(t->Tag()); }
// True if the given type tag corresponds to an integral type.
inline bool IsIntegral(TypeTag t) { return (t == TYPE_INT || t == TYPE_COUNT || t == TYPE_COUNTER); }

File diff suppressed because it is too large Load diff

516
src/Val.h
View file

@ -80,9 +80,8 @@ union BroValUnion {
BroFile* file_val;
RE_Matcher* re_val;
PDict<TableEntryVal>* table_val;
val_list* val_list_val;
std::vector<Val*>* vector_val;
std::vector<IntrusivePtr<Val>>* record_val;
std::vector<IntrusivePtr<Val>>* vector_val;
BroValUnion() = default;
@ -115,37 +114,38 @@ union BroValUnion {
constexpr BroValUnion(PDict<TableEntryVal>* value) noexcept
: table_val(value) {}
constexpr BroValUnion(val_list* value) noexcept
: val_list_val(value) {}
constexpr BroValUnion(std::vector<Val*> *value) noexcept
: vector_val(value) {}
};
class Val : public BroObj {
public:
static inline const IntrusivePtr<Val> nil;
Val(double d, TypeTag t)
: val(d), type(base_type(t).release())
{
}
: val(d), type(base_type(t))
{}
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit Val(Func* f);
explicit Val(IntrusivePtr<Func> f);
// Note, will unref 'f' when it's done, closing it unless
// class has ref'd it.
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit Val(BroFile* f);
// Note, the file will be closed after this Val is destructed if there's
// no other remaining references.
explicit Val(IntrusivePtr<BroFile> f);
// Extra arg to differentiate from protected version.
Val(BroType* t, bool type_type)
: type(new TypeType({NewRef{}, t}))
{
}
Val(IntrusivePtr<BroType> t, bool type_type)
: type(make_intrusive<TypeType>(std::move(t)))
{}
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
Val(BroType* t, bool type_type) : Val({NewRef{}, t}, type_type)
{}
Val()
: val(bro_int_t(0)), type(base_type(TYPE_ERROR).release())
{
}
: val(bro_int_t(0)), type(base_type(TYPE_ERROR))
{}
~Val() override;
@ -179,8 +179,17 @@ public:
// Remove this value from the given value (if appropriate).
virtual bool RemoveFrom(Val* v) const;
BroType* Type() { return type; }
const BroType* Type() const { return type; }
[[deprecated("Remove in v4.1. Use GetType().")]]
BroType* Type() { return type.get(); }
[[deprecated("Remove in v4.1. Use GetType().")]]
const BroType* Type() const { return type.get(); }
const IntrusivePtr<BroType>& GetType() const
{ return type; }
template <class T>
IntrusivePtr<T> GetType() const
{ return cast_intrusive<T>(type); }
#define CONST_ACCESSOR(tag, ctype, accessor, name) \
const ctype name() const \
@ -208,10 +217,10 @@ public:
CONST_ACCESSOR(TYPE_STRING, BroString*, string_val, AsString)
CONST_ACCESSOR(TYPE_FUNC, Func*, func_val, AsFunc)
CONST_ACCESSOR(TYPE_TABLE, PDict<TableEntryVal>*, table_val, AsTable)
CONST_ACCESSOR(TYPE_RECORD, val_list*, val_list_val, AsRecord)
CONST_ACCESSOR(TYPE_RECORD, std::vector<IntrusivePtr<Val>>*, record_val, AsRecord)
CONST_ACCESSOR(TYPE_FILE, BroFile*, file_val, AsFile)
CONST_ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
CONST_ACCESSOR(TYPE_VECTOR, std::vector<Val*>*, vector_val, AsVector)
CONST_ACCESSOR(TYPE_VECTOR, std::vector<IntrusivePtr<Val>>*, vector_val, AsVector)
const IPPrefix& AsSubNet() const
{
@ -222,7 +231,7 @@ public:
BroType* AsType() const
{
CHECK_TAG(type->Tag(), TYPE_TYPE, "Val::Type", type_name)
return type;
return type.get();
}
const IPAddr& AsAddr() const
@ -245,7 +254,9 @@ public:
ACCESSOR(TYPE_FUNC, Func*, func_val, AsFunc)
ACCESSOR(TYPE_FILE, BroFile*, file_val, AsFile)
ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
ACCESSOR(TYPE_VECTOR, std::vector<Val*>*, vector_val, AsVector)
ACCESSOR(TYPE_VECTOR, std::vector<IntrusivePtr<Val>>*, vector_val, AsVector)
IntrusivePtr<Func> AsFuncPtr() const;
const IPPrefix& AsSubNet()
{
@ -340,24 +351,21 @@ protected:
static IntrusivePtr<Val> MakeCount(bro_uint_t u);
template<typename V>
Val(V &&v, TypeTag t) noexcept
: val(std::forward<V>(v)), type(base_type(t).release())
{
}
Val(V&& v, TypeTag t) noexcept
: val(std::forward<V>(v)), type(base_type(t))
{}
template<typename V>
Val(V &&v, BroType* t) noexcept
: val(std::forward<V>(v)), type(t->Ref())
{
}
Val(V&& v, IntrusivePtr<BroType> t) noexcept
: val(std::forward<V>(v)), type(std::move(t))
{}
explicit Val(BroType* t)
: type(t->Ref())
{
}
explicit Val(IntrusivePtr<BroType> t) noexcept
: type(std::move(t))
{}
ACCESSOR(TYPE_TABLE, PDict<TableEntryVal>*, table_val, AsNonConstTable)
ACCESSOR(TYPE_RECORD, val_list*, val_list_val, AsNonConstRecord)
ACCESSOR(TYPE_RECORD, std::vector<IntrusivePtr<Val>>*, record_val, AsNonConstRecord)
// For internal use by the Val::Clone() methods.
struct CloneState {
@ -373,7 +381,7 @@ protected:
virtual IntrusivePtr<Val> DoClone(CloneState* state);
BroValUnion val;
BroType* type;
IntrusivePtr<BroType> type;
#ifdef DEBUG
// For debugging, we keep the name of the ID to which a Val is bound.
@ -593,7 +601,12 @@ public:
unsigned int MemoryAllocation() const override;
IntrusivePtr<StringVal> Substitute(RE_Matcher* re, StringVal* repl, bool do_all);
IntrusivePtr<StringVal> Replace(RE_Matcher* re, const BroString& repl,
bool do_all);
[[deprecated("Remove in v4.1. Use Replace().")]]
Val* Substitute(RE_Matcher* re, StringVal* repl, bool do_all)
{ return Replace(re, *repl->AsString(), do_all).release(); }
protected:
void ValDescribe(ODesc* d) const override;
@ -627,9 +640,14 @@ public:
IntrusivePtr<Val> SizeVal() const override;
int Length() const { return vals.length(); }
Val* Index(const int n) { return vals[n]; }
const Val* Index(const int n) const { return vals[n]; }
int Length() const { return vals.size(); }
const IntrusivePtr<Val>& Idx(size_t i) const { return vals[i]; }
[[deprecated("Remove in v4.1. Use Idx() instead")]]
Val* Index(const int n) { return vals[n].get(); }
[[deprecated("Remove in v4.1. Use Idx() instead")]]
const Val* Index(const int n) const { return vals[n].get(); }
// Returns an RE_Matcher() that will match any string that
// includes embedded within it one of the patterns listed
@ -641,13 +659,22 @@ public:
// The return RE_Matcher has not yet been compiled.
RE_Matcher* BuildRE() const;
/**
* Appends a value to the list.
* @param v the value to append.
*/
void Append(IntrusivePtr<Val> v);
[[deprecated("Remove in v4.1. Use Append(IntrusivePtr) instead.")]]
void Append(Val* v);
// Returns a Set representation of the list (which must be homogeneous).
IntrusivePtr<TableVal> ToSetVal() const;
[[deprecated("Remove in v4.1. Use ToSetVal() instead.")]]
TableVal* ConvertToSet() const;
const val_list* Vals() const { return &vals; }
val_list* Vals() { return &vals; }
const std::vector<IntrusivePtr<Val>>& Vals() const { return vals; }
void Describe(ODesc* d) const override;
@ -656,7 +683,7 @@ public:
protected:
IntrusivePtr<Val> DoClone(CloneState* state) override;
val_list vals;
std::vector<IntrusivePtr<Val>> vals;
TypeTag tag;
};
@ -664,9 +691,8 @@ extern double bro_start_network_time;
class TableEntryVal {
public:
template<typename V>
explicit TableEntryVal(V&& v)
: val(std::forward<V>(v))
explicit TableEntryVal(IntrusivePtr<Val> v)
: val(std::move(v))
{
last_access_time = network_time;
expire_access_time =
@ -675,8 +701,12 @@ public:
TableEntryVal* Clone(Val::CloneState* state);
[[deprecated("Remove in v4.1. Use GetVal().")]]
Val* Value() { return val.get(); }
const IntrusivePtr<Val>& GetVal() const
{ return val; }
// Returns/sets time of last expiration relevant access to this value.
double ExpireAccessTime() const
{ return bro_start_network_time + expire_access_time; }
@ -715,16 +745,45 @@ class Frame;
class TableVal final : public Val, public notifier::Modifiable {
public:
explicit TableVal(IntrusivePtr<TableType> t, IntrusivePtr<Attributes> attrs = nullptr);
[[deprecated("Remove in v4.1. Construct from IntrusivePtrs instead.")]]
explicit TableVal(TableType* t, Attributes* attrs = nullptr)
: TableVal({NewRef{}, t}, {NewRef{}, attrs})
{}
~TableVal() override;
/**
* Assigns a value at an associated index in the table (or in the
* case of a set, just adds the index).
* @param index The key to assign.
* @param new_val The value to assign at the index. For a set, this
* must be nullptr.
* @return True if the assignment type-checked.
*/
bool Assign(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val);
/**
* Assigns a value at an associated index in the table (or in the
* case of a set, just adds the index).
* @param index The key to assign. For tables, this is allowed to be null
* (if needed, the index val can be recovered from the hash key).
* @param k A precomputed hash key to use.
* @param new_val The value to assign at the index. For a set, this
* must be nullptr.
* @return True if the assignment type-checked.
*/
bool Assign(IntrusivePtr<Val> index, std::unique_ptr<HashKey> k,
IntrusivePtr<Val> new_val);
// Returns true if the assignment typechecked, false if not. The
// methods take ownership of new_val, but not of the index. Second
// version takes a HashKey and Unref()'s it when done. If we're a
// set, new_val has to be nil. If we aren't a set, index may be nil
// in the second version.
bool Assign(Val* index, IntrusivePtr<Val> new_val);
// methods take ownership of new_val, but not of the index. If we're
// a set, new_val has to be nil.
[[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]]
bool Assign(Val* index, Val* new_val);
bool Assign(Val* index, HashKey* k, IntrusivePtr<Val> new_val);
// Same as other Assign() method, but takes a precomuted HashKey and
// deletes it when done.
[[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]]
bool Assign(Val* index, HashKey* k, Val* new_val);
IntrusivePtr<Val> SizeVal() const override;
@ -747,30 +806,68 @@ public:
// Returns true if the addition typechecked, false if not.
bool RemoveFrom(Val* v) const override;
// Returns a new table that is the intersection of this
// table and the given table. Intersection is just done
// on index, not on yield value, so this really only makes
// sense for sets.
TableVal* Intersect(const TableVal* v) const;
/**
* Returns a new table that is the intersection of this table
* and the given table. Intersection is done only on index, not on
* yield value, so this generally makes most sense to use for sets,
* not tables.
* @param v The intersecting table.
* @return The intersection of this table and the given one.
*/
IntrusivePtr<TableVal> Intersection(const TableVal& v) const;
[[deprecated("Remove in v4.1. Use Intersection() instead.")]]
TableVal* Intersect(const TableVal* v) const
{ return Intersection(*v).release(); }
// Returns true if this set contains the same members as the
// given set. Note that comparisons are done using hash keys,
// so errors can arise for compound sets such as sets-of-sets.
// See https://bro-tracker.atlassian.net/browse/BIT-1949.
bool EqualTo(const TableVal* v) const;
bool EqualTo(const TableVal& v) const;
[[deprecated("Remove in v4.1. Pass TableVal& instead.")]]
bool EqualTo(const TableVal* v) const
{ return EqualTo(*v); }
// Returns true if this set is a subset (not necessarily proper)
// of the given set.
bool IsSubsetOf(const TableVal* v) const;
bool IsSubsetOf(const TableVal& v) const;
[[deprecated("Remove in v4.1. Pass TableVal& instead.")]]
bool IsSubsetOf(const TableVal* v) const
{ return IsSubsetOf(*v); }
// Expands any lists in the index into multiple initializations.
// Returns true if the initializations typecheck, false if not.
bool ExpandAndInit(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val);
/**
* Finds an index in the table and returns its associated value.
* @param index The index to lookup in the table.
* @return The value associated with the index. If the index doesn't
* exist, this is a nullptr. For sets that don't really contain associated
* values, a placeholder value is returned to differentiate it from
* non-existent index (nullptr), but otherwise has no meaning in relation
* to the set's contents.
*/
const IntrusivePtr<Val>& Find(const IntrusivePtr<Val>& index);
/**
* Finds an index in the table and returns its associated value or else
* the &default value.
* @param index The index to lookup in the table.
* @return The value associated with the index. If the index doesn't
* exist, instead returns the &default value. If there's no &default
* attribute, then nullptr is still returned for non-existent index.
*/
IntrusivePtr<Val> FindOrDefault(const IntrusivePtr<Val>& index);
// Returns the element's value if it exists in the table,
// nil otherwise. Note, "index" is not const because we
// need to Ref/Unref it when calling the default function.
IntrusivePtr<Val> Lookup(Val* index, bool use_default_val = true);
[[deprecated("Remove in v4.1. Use Find() or FindOrDefault().")]]
Val* Lookup(Val* index, bool use_default_val = true);
// For a table[subnet]/set[subnet], return all subnets that cover
// the given subnet.
@ -786,21 +883,66 @@ public:
// Returns false if index does not exist.
bool UpdateTimestamp(Val* index);
// Returns the index corresponding to the given HashKey.
IntrusivePtr<ListVal> RecoverIndex(const HashKey* k) const;
/**
* @return The index corresponding to the given HashKey.
*/
IntrusivePtr<ListVal> RecreateIndex(const HashKey& k) const;
// Returns the element if it was in the table, false otherwise.
IntrusivePtr<Val> Delete(const Val* index);
IntrusivePtr<Val> Delete(const HashKey* k);
[[deprecated("Remove in v4.1. Use RecreateIndex().")]]
ListVal* RecoverIndex(const HashKey* k) const
{ return RecreateIndex(*k).release(); }
/**
* Remove an element from the table and return it.
* @param index The index to remove.
* @return The value associated with the index if it exists, else nullptr.
* For a sets that don't really contain associated values, a placeholder
* value is returned to differentiate it from non-existent index (nullptr),
* but otherwise has no meaning in relation to the set's contents.
*/
IntrusivePtr<Val> Remove(const Val& index);
/**
* Same as Remove(const Val&), but uses a precomputed hash key.
* @param k The hash key to lookup.
* @return Same as Remove(const Val&).
*/
IntrusivePtr<Val> Remove(const HashKey& k);
[[deprecated("Remove in v4.1. Use Remove().")]]
Val* Delete(const Val* index)
{ return Remove(*index).release(); }
[[deprecated("Remove in v4.1. Use Remove().")]]
Val* Delete(const HashKey* k)
{ return Remove(*k).release(); }
// Returns a ListVal representation of the table (which must be a set).
IntrusivePtr<ListVal> ToListVal(TypeTag t = TYPE_ANY) const;
// Returns a ListVal representation of the table (which must be a set
// with non-composite index type).
IntrusivePtr<ListVal> ToPureListVal() const;
[[deprecated("Remove in v4.1. Use ToListVal() instead.")]]
ListVal* ConvertToList(TypeTag t=TYPE_ANY) const;
[[deprecated("Remove in v4.1. Use ToPureListVal() instead.")]]
ListVal* ConvertToPureList() const; // must be single index type
void SetAttrs(IntrusivePtr<Attributes> attrs);
Attr* FindAttr(attr_tag t) const;
[[deprecated("Remove in v4.1. Use GetAttr().")]]
Attr* FindAttr(attr_tag t) const
{ return GetAttr(t).get(); }
const IntrusivePtr<Attr>& GetAttr(attr_tag t) const;
[[deprecated("Remove in v4.1. Use GetAttrs().")]]
Attributes* Attrs() { return attrs.get(); }
const IntrusivePtr<Attributes>& GetAttrs() const
{ return attrs; }
// Returns the size of the table.
int Size() const;
int RecursiveSize() const;
@ -828,6 +970,14 @@ public:
timer = nullptr;
}
/**
* @param The index value to hash.
* @return The hash of the index value or nullptr if
* type-checking failed.
*/
std::unique_ptr<HashKey> MakeHashKey(const Val& index) const;
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
HashKey* ComputeHash(const Val* index) const;
notifier::Modifiable* Modifiable() override { return this; }
@ -857,11 +1007,11 @@ protected:
void RebuildTable(ParseTimeTableState ptts);
void CheckExpireAttr(attr_tag at);
bool ExpandCompoundAndInit(val_list* vl, int k, IntrusivePtr<Val> new_val);
bool CheckAndAssign(Val* index, IntrusivePtr<Val> new_val);
bool ExpandCompoundAndInit(ListVal* lv, int k, IntrusivePtr<Val> new_val);
bool CheckAndAssign(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val);
// Calculates default value for index. Returns 0 if none.
IntrusivePtr<Val> Default(Val* index);
// Calculates default value for index. Returns nullptr if none.
IntrusivePtr<Val> Default(const IntrusivePtr<Val>& index);
// Returns true if item expiration is enabled.
bool ExpirationEnabled() { return expire_time != nullptr; }
@ -878,7 +1028,8 @@ protected:
enum OnChangeType { ELEMENT_NEW, ELEMENT_CHANGED, ELEMENT_REMOVED, ELEMENT_EXPIRED };
// Calls &change_func. Does not take ownership of values. (Refs if needed).
void CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe);
void CallChangeFunc(const Val* index, const IntrusivePtr<Val>& old_value,
OnChangeType tpe);
// Sends data on to backing Broker Store
void SendToStore(const Val* index, const Val* new_value, OnChangeType tpe);
@ -905,15 +1056,112 @@ protected:
class RecordVal final : public Val, public notifier::Modifiable {
public:
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit RecordVal(RecordType* t, bool init_fields = true);
explicit RecordVal(IntrusivePtr<RecordType> t, bool init_fields = true);
~RecordVal() override;
IntrusivePtr<Val> SizeVal() const override;
/**
* Assign a value to a record field.
* @param field The field index to assign.
* @param new_val The value to assign.
*/
void Assign(int field, IntrusivePtr<Val> new_val);
/**
* Assign a value of type @c T to a record field, as constructed from
* the provided arguments.
* @param field The field index to assign.
* @param args A variable number of arguments to pass to constructor of
* type @c T.
*/
template <class T, class... Ts>
void Assign(int field, Ts&&... args)
{ Assign(field, make_intrusive<T>(std::forward<Ts>(args)...)); }
[[deprecated("Remove in v4.1. Assign an IntrusivePtr instead.")]]
void Assign(int field, Val* new_val);
Val* Lookup(int field) const; // Does not Ref() value.
IntrusivePtr<Val> LookupWithDefault(int field) const;
// Note: the following nullptr method can also go upon removing the above.
void Assign(int field, std::nullptr_t)
{ Assign(field, IntrusivePtr<Val>{}); }
[[deprecated("Remove in v4.1. Use GetField().")]]
Val* Lookup(int field) const // Does not Ref() value.
{ return (*AsRecord())[field].get(); }
/**
* Returns the value of a given field index.
* @param field The field index to retrieve.
* @return The value at the given field index.
*/
const IntrusivePtr<Val>& GetField(int field) const
{ return (*AsRecord())[field]; }
/**
* Returns the value of a given field index as cast to type @c T.
* @param field The field index to retrieve.
* @return The value at the given field index cast to type @c T.
*/
template <class T>
IntrusivePtr<T> GetField(int field) const
{ return cast_intrusive<T>(GetField(field)); }
/**
* Returns the value of a given field index if it's previously been
* assigned, * or else returns the value created from evaluating the
* record field's &default expression.
* @param field The field index to retrieve.
* @return The value at the given field index or the default value if
* the field hasn't been assigned yet.
*/
IntrusivePtr<Val> GetFieldOrDefault(int field) const;
[[deprecated("Remove in v4.1. Use GetFieldOrDefault().")]]
Val* LookupWithDefault(int field) const
{ return GetFieldOrDefault(field).release(); }
/**
* Returns the value of a given field name.
* @param field The name of a field to retrieve.
* @return The value of the given field. If no such field name exists,
* a fatal error occurs.
*/
const IntrusivePtr<Val>& GetField(const char* field) const;
/**
* Returns the value of a given field name as cast to type @c T.
* @param field The name of a field to retrieve.
* @return The value of the given field cast to type @c T. If no such
* field name exists, a fatal error occurs.
*/
template <class T>
IntrusivePtr<T> GetField(const char* field) const
{ return cast_intrusive<T>(GetField(field)); }
/**
* Returns the value of a given field name if it's previously been
* assigned, or else returns the value created from evaluating the record
* fields' &default expression.
* @param field The name of a field to retrieve.
* @return The value of the given field. or the default value
* if the field hasn't been assigned yet. If no such field name exists,
* a fatal error occurs.
*/
IntrusivePtr<Val> GetFieldOrDefault(const char* field) const;
/**
* Returns the value of a given field name or its default value
* as cast to type @c T.
* @param field The name of a field to retrieve.
* @return The value of the given field or its default value cast to
* type @c T. If no such field name exists, a fatal error occurs.
*/
template <class T>
IntrusivePtr<T> GetFieldOrDefault(const char* field) const
{ return cast_intrusive<T>(GetField(field)); }
/**
* Looks up the value of a field by field name. If the field doesn't
@ -923,7 +1171,9 @@ public:
* the field has yet to be initialized.
* @return the value in field \a field.
*/
IntrusivePtr<Val> Lookup(const char* field, bool with_default = false) const;
[[deprecated("Remove in v4.1. Use GetField() or GetFieldOrDefault().")]]
Val* Lookup(const char* field, bool with_default = false) const
{ return with_default ? GetFieldOrDefault(field).release() : GetField(field).get(); }
void Describe(ODesc* d) const override;
@ -948,8 +1198,11 @@ public:
//
// The *allow_orphaning* parameter allows for a record to be demoted
// down to a record type that contains less fields.
IntrusivePtr<RecordVal> CoerceTo(const RecordType* other, Val* aggr, bool allow_orphaning = false) const;
IntrusivePtr<RecordVal> CoerceTo(RecordType* other, bool allow_orphaning = false);
IntrusivePtr<RecordVal> CoerceTo(IntrusivePtr<RecordType> other,
IntrusivePtr<RecordVal> aggr,
bool allow_orphaning = false) const;
IntrusivePtr<RecordVal> CoerceTo(IntrusivePtr<RecordType> other,
bool allow_orphaning = false);
unsigned int MemoryAllocation() const override;
void DescribeReST(ODesc* d) const override;
@ -980,9 +1233,11 @@ protected:
friend class Val;
friend class EnumType;
EnumVal(EnumType* t, int i) : Val(bro_int_t(i), t)
{
}
template<class T, class... Ts>
friend IntrusivePtr<T> make_intrusive(Ts&&... args);
EnumVal(IntrusivePtr<EnumType> t, int i) : Val(bro_int_t(i), std::move(t))
{}
void ValDescribe(ODesc* d) const override;
IntrusivePtr<Val> DoClone(CloneState* state) override;
@ -991,43 +1246,73 @@ protected:
class VectorVal final : public Val, public notifier::Modifiable {
public:
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit VectorVal(VectorType* t);
explicit VectorVal(IntrusivePtr<VectorType> t);
~VectorVal() override;
IntrusivePtr<Val> SizeVal() const override;
// Returns false if the type of the argument was wrong.
// The vector will automatically grow to accomodate the index.
//
/**
* Assigns an element to a given vector index.
* @param index The index to assign.
* @param element The element value to assign.
* @return True if the element was successfully assigned, or false if
* the element was the wrong type.
*/
bool Assign(unsigned int index, IntrusivePtr<Val> element);
// Note: does NOT Ref() the element! Remember to do so unless
// the element was just created and thus has refcount 1.
//
bool Assign(unsigned int index, IntrusivePtr<Val> element);
bool Assign(unsigned int index, Val* element);
[[deprecated("Remove in v4.1. Assign an IntrusivePtr instead.")]]
bool Assign(unsigned int index, Val* element)
{ return Assign(index, {AdoptRef{}, element}); }
// Note: the following nullptr method can also go upon removing the above.
void Assign(unsigned int index, std::nullptr_t)
{ Assign(index, IntrusivePtr<Val>{}); }
template<typename E>
bool Assign(Val* index, E&& element)
[[deprecated("Remove in v4.1. Assign using integer index and IntrusivePtr element.")]]
bool Assign(Val* index, Val* element)
{
return Assign(index->AsListVal()->Index(0)->CoerceToUnsigned(),
std::forward<E>(element));
return Assign(index->AsListVal()->Idx(0)->CoerceToUnsigned(),
{AdoptRef{}, element});
}
// Assigns the value to how_many locations starting at index.
/**
* Assigns a given value to multiple indices in the vector.
* @param index The starting index to assign to.
* @param how_many The number of indices to assign, counting from *index*.
* @return True if the elements were successfully assigned, or false if
* the element was the wrong type.
*/
bool AssignRepeat(unsigned int index, unsigned int how_many,
Val* element);
IntrusivePtr<Val> element);
[[deprecated("Remove in v4.1. Assign an IntrusivePtr instead.")]]
bool AssignRepeat(unsigned int index, unsigned int how_many, Val* element)
{ return AssignRepeat(index, how_many, {NewRef{}, element}); }
// Add this value to the given value (if appropriate).
// Returns true if succcessful.
bool AddTo(Val* v, bool is_first_init) const override;
// Returns nil if no element was at that value.
// Lookup does NOT grow the vector to this size.
// The Val* variant assumes that the index Val* has been type-checked.
Val* Lookup(unsigned int index) const;
/**
* Returns the element at a given index or nullptr if it does not exist.
* @param index The position in the vector of the element to return.
* @return The element at the given index or nullptr if the index
* does not exist (it's greater than or equal to vector's current size).
*/
const IntrusivePtr<Val>& At(unsigned int index) const;
[[deprecated("Remove in v4.1. Use At().")]]
Val* Lookup(unsigned int index) const
{ return At(index).get(); }
[[deprecated("Remove in v4.1. Use At().")]]
Val* Lookup(Val* index)
{
bro_uint_t i = index->AsListVal()->Index(0)->CoerceToUnsigned();
return Lookup(static_cast<unsigned int>(i));
bro_uint_t i = index->AsListVal()->Idx(0)->CoerceToUnsigned();
return At(static_cast<unsigned int>(i)).get();
}
unsigned int Size() const { return val.vector_val->size(); }
@ -1041,8 +1326,19 @@ public:
notifier::Modifiable* Modifiable() override { return this; }
// Insert an element at a specific position into the underlying vector.
bool Insert(unsigned int index, Val* element);
/**
* Inserts an element at the given position in the vector. All elements
* at that original position and higher are shifted up by one.
* @param index The index to insert the element at.
* @param element The value to insert into the vector.
* @return True if the element was inserted or false if the element was
* the wrong type.
*/
bool Insert(unsigned int index, IntrusivePtr<Val> element);
[[deprecated("Remove in v4.1. Insert an IntrusivePtr instead.")]]
bool Insert(unsigned int index, Val* element)
{ return Insert(index, {AdoptRef{}, element}); }
// Removes an element at a specific position.
bool Remove(unsigned int index);
@ -1050,15 +1346,12 @@ public:
protected:
void ValDescribe(ODesc* d) const override;
IntrusivePtr<Val> DoClone(CloneState* state) override;
VectorType* vector_type;
};
// Checks the given value for consistency with the given type. If an
// exact match, returns it. If promotable, returns the promoted version,
// Unref()'ing the original. If not a match, generates an error message
// and returns nil, also Unref()'ing v. If is_init is true, then
// the checking is done in the context of an initialization.
// exact match, returns it. If promotable, returns the promoted version.
// If not a match, generates an error message and return nil. If is_init is
// true, then the checking is done in the context of an initialization.
extern IntrusivePtr<Val> check_and_promote(IntrusivePtr<Val> v,
const BroType* t, bool is_init,
const Location* expr_location = nullptr);
@ -1072,7 +1365,8 @@ extern void describe_vals(const std::vector<IntrusivePtr<Val>>& vals,
extern void delete_vals(val_list* vals);
// True if the given Val* has a vector type.
inline bool is_vector(Val* v) { return v->Type()->Tag() == TYPE_VECTOR; }
inline bool is_vector(Val* v) { return v->GetType()->Tag() == TYPE_VECTOR; }
inline bool is_vector(const IntrusivePtr<Val>& v) { return is_vector(v.get()); }
// Returns v casted to type T if the type supports that. Returns null if not.
//

View file

@ -15,6 +15,7 @@
#include "EventRegistry.h"
#include "Traverse.h"
#include "module_util.h"
#include "ID.h"
static IntrusivePtr<Val> init_val(Expr* init, const BroType* t,
IntrusivePtr<Val> aggr)
@ -29,19 +30,20 @@ static IntrusivePtr<Val> init_val(Expr* init, const BroType* t,
}
}
static bool add_prototype(ID* id, BroType* t, attr_list* attrs,
static bool add_prototype(const IntrusivePtr<ID>& id, BroType* t,
std::vector<IntrusivePtr<Attr>>* attrs,
const IntrusivePtr<Expr>& init)
{
if ( ! IsFunc(id->Type()->Tag()) )
if ( ! IsFunc(id->GetType()->Tag()) )
return false;
if ( ! IsFunc(t->Tag()) )
{
t->Error("type incompatible with previous definition", id);
t->Error("type incompatible with previous definition", id.get());
return false;
}
auto canon_ft = id->Type()->AsFuncType();
auto canon_ft = id->GetType()->AsFuncType();
auto alt_ft = t->AsFuncType();
if ( canon_ft->Flavor() != alt_ft->Flavor() )
@ -62,8 +64,8 @@ static bool add_prototype(ID* id, BroType* t, attr_list* attrs,
return false;
}
auto canon_args = canon_ft->Args();
auto alt_args = alt_ft->Args();
const auto& canon_args = canon_ft->Params();
const auto& alt_args = alt_ft->Params();
if ( auto p = canon_ft->FindPrototype(*alt_args); p )
{
@ -101,18 +103,20 @@ static bool add_prototype(ID* id, BroType* t, attr_list* attrs,
if ( a->Tag() == ATTR_DEPRECATED )
deprecated = true;
FuncType::Prototype p{deprecated, {NewRef{}, alt_args}, std::move(offsets)};
FuncType::Prototype p{deprecated, alt_args, std::move(offsets)};
canon_ft->AddPrototype(std::move(p));
return true;
}
static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt,
static void make_var(const IntrusivePtr<ID>& id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt,
bool do_init)
{
if ( id->Type() )
if ( id->GetType() )
{
if ( id->IsRedefinable() || (! init && attr && ! IsFunc(id->Type()->Tag())) )
if ( id->IsRedefinable() || (! init && attr && ! IsFunc(id->GetType()->Tag())) )
{
BroObj* redef_obj = init ? (BroObj*) init.get() : (BroObj*) t.get();
if ( dt != VAR_REDEF )
@ -121,8 +125,8 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
else if ( dt != VAR_REDEF || init || ! attr )
{
if ( IsFunc(id->Type()->Tag()) )
add_prototype(id, t.get(), attr, init);
if ( IsFunc(id->GetType()->Tag()) )
add_prototype(id, t.get(), attr.get(), init);
else
id->Error("already defined", init.get());
@ -132,17 +136,17 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
if ( dt == VAR_REDEF )
{
if ( ! id->Type() )
if ( ! id->GetType() )
{
id->Error("\"redef\" used but not previously defined");
return;
}
if ( ! t )
t = {NewRef{}, id->Type()};
t = id->GetType();
}
if ( id->Type() && id->Type()->Tag() != TYPE_ERROR )
if ( id->GetType() && id->GetType()->Tag() != TYPE_ERROR )
{
if ( dt != VAR_REDEF &&
(! init || ! do_init || (! t && ! (t = init_type(init.get())))) )
@ -152,7 +156,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
}
// Allow redeclaration in order to initialize.
if ( ! same_type(t.get(), id->Type()) )
if ( ! same_type(t, id->GetType()) )
{
id->Error("redefinition changes type", init.get());
return;
@ -162,7 +166,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
if ( t && t->IsSet() )
{ // Check for set with explicit elements.
SetType* st = t->AsTableType()->AsSetType();
ListExpr* elements = st->SetElements();
const auto& elements = st->Elements();
if ( elements )
{
@ -172,7 +176,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
return;
}
init = {NewRef{}, elements};
init = elements;
}
}
@ -195,7 +199,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
id->SetType(t);
if ( attr )
id->AddAttrs(make_intrusive<Attributes>(attr, t, false, id->IsGlobal()));
id->AddAttrs(make_intrusive<Attributes>(std::move(*attr), t, false, id->IsGlobal()));
if ( init )
{
@ -203,16 +207,16 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
case EXPR_TABLE_CONSTRUCTOR:
{
TableConstructorExpr* ctor = (TableConstructorExpr*) init.get();
if ( ctor->Attrs() )
id->AddAttrs({NewRef{}, ctor->Attrs()});
if ( ctor->GetAttrs() )
id->AddAttrs(ctor->GetAttrs());
}
break;
case EXPR_SET_CONSTRUCTOR:
{
SetConstructorExpr* ctor = (SetConstructorExpr*) init.get();
if ( ctor->Attrs() )
id->AddAttrs({NewRef{}, ctor->Attrs()});
if ( ctor->GetAttrs() )
id->AddAttrs(ctor->GetAttrs());
}
break;
@ -229,8 +233,8 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
// intention clearly isn't to overwrite entire existing table val.
c = INIT_EXTRA;
if ( init && ((c == INIT_EXTRA && id->FindAttr(ATTR_ADD_FUNC)) ||
(c == INIT_REMOVE && id->FindAttr(ATTR_DEL_FUNC)) ))
if ( init && ((c == INIT_EXTRA && id->GetAttr(ATTR_ADD_FUNC)) ||
(c == INIT_REMOVE && id->GetAttr(ATTR_DEL_FUNC)) ))
// Just apply the function.
id->SetVal(init, c);
@ -240,7 +244,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
if ( t->Tag() == TYPE_RECORD )
{
aggr = make_intrusive<RecordVal>(t->AsRecordType());
aggr = make_intrusive<RecordVal>(cast_intrusive<RecordType>(t));
if ( init && t )
// Have an initialization and type is not deduced.
@ -249,11 +253,11 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
}
else if ( t->Tag() == TYPE_TABLE )
aggr = make_intrusive<TableVal>(IntrusivePtr{NewRef{}, t->AsTableType()},
IntrusivePtr{NewRef{}, id->Attrs()});
aggr = make_intrusive<TableVal>(cast_intrusive<TableType>(t),
id->GetAttrs());
else if ( t->Tag() == TYPE_VECTOR )
aggr = make_intrusive<VectorVal>(t->AsVectorType());
aggr = make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
IntrusivePtr<Val> v;
@ -297,23 +301,27 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
// For events, add a function value (without any body) here so that
// we can later access the ID even if no implementations have been
// defined.
Func* f = new BroFunc(id, nullptr, nullptr, 0, 0);
id->SetVal(make_intrusive<Val>(f));
std::vector<IntrusivePtr<ID>> inits;
auto f = make_intrusive<BroFunc>(id, nullptr, inits, 0, 0);
id->SetVal(make_intrusive<Val>(std::move(f)));
}
}
void add_global(ID* id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt)
void add_global(const IntrusivePtr<ID>& id, IntrusivePtr<BroType> t,
init_class c, IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt)
{
make_var(id, std::move(t), c, std::move(init), attr, dt, true);
make_var(id, std::move(t), c, std::move(init), std::move(attr), dt, true);
}
IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
init_class c, IntrusivePtr<Expr> init,
attr_list* attr, decl_type dt)
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt)
{
make_var(id.get(), std::move(t), c, init, attr, dt, false);
make_var(id, std::move(t), c, init, std::move(attr), dt, false);
if ( init )
{
@ -325,10 +333,9 @@ IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
*init->GetLocationInfo() : no_location;
auto name_expr = make_intrusive<NameExpr>(id, dt == VAR_CONST);
auto attrs = id->Attrs() ? id->Attrs()->Attrs() : nullptr;
auto assign_expr = make_intrusive<AssignExpr>(std::move(name_expr),
std::move(init), 0,
nullptr, attrs);
nullptr, id->GetAttrs());
auto stmt = make_intrusive<ExprStmt>(std::move(assign_expr));
stmt->SetLocationInfo(&location);
return stmt;
@ -345,13 +352,14 @@ extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
IntrusivePtr<Expr> init,
IntrusivePtr<Val> val)
{
make_var(id.get(), nullptr, INIT_FULL, init, nullptr, VAR_REGULAR, false);
make_var(id, nullptr, INIT_FULL, init, nullptr, VAR_REGULAR, false);
auto name_expr = make_intrusive<NameExpr>(std::move(id));
return make_intrusive<AssignExpr>(std::move(name_expr), std::move(init),
false, std::move(val));
}
void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
void add_type(ID* id, IntrusivePtr<BroType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr)
{
std::string new_type_name = id->Name();
std::string old_type_name = t->GetName();
@ -363,7 +371,7 @@ void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
tnew = std::move(t);
else
// Clone the type to preserve type name aliasing.
tnew = {AdoptRef{}, t->ShallowClone()};
tnew = t->ShallowClone();
BroType::AddAlias(new_type_name, tnew.get());
@ -376,7 +384,7 @@ void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
id->MakeType();
if ( attr )
id->SetAttrs(make_intrusive<Attributes>(attr, tnew, false, false));
id->SetAttrs(make_intrusive<Attributes>(std::move(*attr), tnew, false, false));
}
static void transfer_arg_defaults(RecordType* args, RecordType* recv)
@ -386,39 +394,36 @@ static void transfer_arg_defaults(RecordType* args, RecordType* recv)
TypeDecl* args_i = args->FieldDecl(i);
TypeDecl* recv_i = recv->FieldDecl(i);
Attr* def = args_i->attrs ? args_i->attrs->FindAttr(ATTR_DEFAULT) : nullptr;
const auto& def = args_i->attrs ? args_i->attrs->Find(ATTR_DEFAULT) : nullptr;
if ( ! def )
continue;
if ( ! recv_i->attrs )
{
attr_list* a = new attr_list{def};
recv_i->attrs = make_intrusive<Attributes>(a, recv_i->type, true, false);
std::vector<IntrusivePtr<Attr>> a{def};
recv_i->attrs = make_intrusive<Attributes>(std::move(a),
recv_i->type,
true, false);
}
else if ( ! recv_i->attrs->FindAttr(ATTR_DEFAULT) )
recv_i->attrs->AddAttr({NewRef{}, def});
else if ( ! recv_i->attrs->Find(ATTR_DEFAULT) )
recv_i->attrs->AddAttr(def);
}
}
static Attr* find_attr(const attr_list* al, attr_tag tag)
static Attr* find_attr(const std::vector<IntrusivePtr<Attr>>* al, attr_tag tag)
{
if ( ! al )
return nullptr;
for ( int i = 0; i < al->length(); ++i )
for ( size_t i = 0; i < al->size(); ++i )
if ( (*al)[i]->Tag() == tag )
return (*al)[i];
return (*al)[i].get();
return nullptr;
}
static bool has_attr(const attr_list* al, attr_tag tag)
{
return find_attr(al, tag) != nullptr;
}
static std::optional<FuncType::Prototype> func_type_check(const FuncType* decl, const FuncType* impl)
{
if ( decl->Flavor() != impl->Flavor() )
@ -436,30 +441,32 @@ static std::optional<FuncType::Prototype> func_type_check(const FuncType* decl,
return {};
}
return decl->FindPrototype(*impl->Args());
return decl->FindPrototype(*impl->Params());
}
static bool canonical_arg_types_match(const FuncType* decl, const FuncType* impl)
{
auto canon_args = decl->Args();
auto impl_args = impl->Args();
const auto& canon_args = decl->Params();
const auto& impl_args = impl->Params();
if ( canon_args->NumFields() != impl_args->NumFields() )
return false;
for ( auto i = 0; i < canon_args->NumFields(); ++i )
if ( ! same_type(canon_args->FieldType(i), impl_args->FieldType(i)) )
if ( ! same_type(canon_args->GetFieldType(i), impl_args->GetFieldType(i)) )
return false;
return true;
}
void begin_func(ID* id, const char* module_name, function_flavor flavor,
bool is_redef, IntrusivePtr<FuncType> t, attr_list* attrs)
void begin_func(IntrusivePtr<ID> id, const char* module_name,
function_flavor flavor, bool is_redef,
IntrusivePtr<FuncType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs)
{
if ( flavor == FUNC_FLAVOR_EVENT )
{
const BroType* yt = t->YieldType();
const auto& yt = t->Yield();
if ( yt && yt->Tag() != TYPE_VOID )
id->Error("event cannot yield a value", t.get());
@ -469,9 +476,9 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
std::optional<FuncType::Prototype> prototype;
if ( id->Type() )
if ( id->GetType() )
{
auto decl = id->Type()->AsFuncType();
auto decl = id->GetType()->AsFuncType();
prototype = func_type_check(decl, t.get());
if ( prototype )
@ -482,20 +489,20 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
// params, automatically transfer any that are missing
// (convenience so that implementations don't need to specify
// the &default expression again).
transfer_arg_defaults(prototype->args.get(), t->Args());
transfer_arg_defaults(prototype->args.get(), t->Params().get());
}
else
{
// Warn for trying to use &default parameters in hook/event
// handler body when it already has a declaration since only
// &default in the declaration has any effect.
auto args = t->Args();
const auto& args = t->Params();
for ( int i = 0; i < args->NumFields(); ++i )
{
auto f = args->FieldDecl(i);
if ( f->attrs && f->attrs->FindAttr(ATTR_DEFAULT) )
if ( f->attrs && f->attrs->Find(ATTR_DEFAULT) )
{
reporter->PushLocation(args->GetLocationInfo());
reporter->Warning(
@ -507,7 +514,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
}
if ( prototype->deprecated )
t->Warn("use of deprecated prototype", id);
t->Warn("use of deprecated prototype", id.get());
}
else
{
@ -516,7 +523,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
if ( canonical_arg_types_match(decl, t.get()) )
prototype = decl->Prototypes()[0];
else
t->Error("use of undeclared alternate prototype", id);
t->Error("use of undeclared alternate prototype", id.get());
}
}
@ -525,7 +532,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
if ( id->HasVal() )
{
function_flavor id_flavor = id->ID_Val()->AsFunc()->Flavor();
function_flavor id_flavor = id->GetVal()->AsFunc()->Flavor();
if ( id_flavor != flavor )
id->Error("inconsistent function flavor", t.get());
@ -552,9 +559,9 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
else
id->SetType(t);
push_scope({NewRef{}, id}, attrs);
push_scope(std::move(id), std::move(attrs));
RecordType* args = t->Args();
const auto& args = t->Params();
int num_args = args->NumFields();
for ( int i = 0; i < num_args; ++i )
@ -572,8 +579,9 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
arg_id->SetOffset(prototype->offsets[i]);
}
if ( Attr* depr_attr = find_attr(attrs, ATTR_DEPRECATED) )
id->MakeDeprecated({NewRef{}, depr_attr->AttrExpr()});
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(),
ATTR_DEPRECATED) )
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
}
class OuterIDBindingFinder : public TraversalCallback {
@ -608,7 +616,7 @@ TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr)
return TC_CONTINUE;
for ( const auto& scope : scopes )
if ( scope->Lookup(e->Id()->Name()) )
if ( scope->Find(e->Id()->Name()) )
// Shadowing is not allowed, so if it's found at inner scope, it's
// not something we have to worry about also being at outer scope.
return TC_CONTINUE;
@ -630,25 +638,25 @@ void end_func(IntrusivePtr<Stmt> body)
auto ingredients = std::make_unique<function_ingredients>(pop_scope(), std::move(body));
if ( ingredients->id->HasVal() )
ingredients->id->ID_Val()->AsFunc()->AddBody(
ingredients->id->GetVal()->AsFunc()->AddBody(
ingredients->body,
ingredients->inits,
ingredients->frame_size,
ingredients->priority);
else
{
Func* f = new BroFunc(
ingredients->id.get(),
auto f = make_intrusive<BroFunc>(
ingredients->id,
ingredients->body,
ingredients->inits,
ingredients->frame_size,
ingredients->priority);
ingredients->id->SetVal(make_intrusive<Val>(f));
ingredients->id->SetVal(make_intrusive<Val>(std::move(f)));
ingredients->id->SetConst();
}
ingredients->id->ID_Val()->AsFunc()->SetScope(ingredients->scope);
ingredients->id->GetVal()->AsFunc()->SetScope(ingredients->scope);
// Note: ideally, something would take ownership of this memory until the
// end of script execution, but that's essentially the same as the
// lifetime of the process at the moment, so ok to "leak" it.
@ -657,12 +665,7 @@ void end_func(IntrusivePtr<Stmt> body)
Val* internal_val(const char* name)
{
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id )
reporter->InternalError("internal variable %s missing", name);
return id->ID_Val();
return zeek::id::find_val(name).get();
}
id_list gather_outer_ids(Scope* scope, Stmt* body)
@ -687,70 +690,73 @@ id_list gather_outer_ids(Scope* scope, Stmt* body)
Val* internal_const_val(const char* name)
{
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id )
reporter->InternalError("internal variable %s missing", name);
if ( ! id->IsConst() )
reporter->InternalError("internal variable %s is not constant", name);
return id->ID_Val();
return zeek::id::find_const(name).get();
}
Val* opt_internal_val(const char* name)
{
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
return id ? id->ID_Val() : nullptr;
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
return id ? id->GetVal().get() : nullptr;
}
double opt_internal_double(const char* name)
{
Val* v = opt_internal_val(name);
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id ) return 0.0;
const auto& v = id->GetVal();
return v ? v->InternalDouble() : 0.0;
}
bro_int_t opt_internal_int(const char* name)
{
Val* v = opt_internal_val(name);
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id ) return 0;
const auto& v = id->GetVal();
return v ? v->InternalInt() : 0;
}
bro_uint_t opt_internal_unsigned(const char* name)
{
Val* v = opt_internal_val(name);
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id ) return 0;
const auto& v = id->GetVal();
return v ? v->InternalUnsigned() : 0;
}
StringVal* opt_internal_string(const char* name)
{
Val* v = opt_internal_val(name);
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id ) return nullptr;
const auto& v = id->GetVal();
return v ? v->AsStringVal() : nullptr;
}
TableVal* opt_internal_table(const char* name)
{
Val* v = opt_internal_val(name);
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id ) return nullptr;
const auto& v = id->GetVal();
return v ? v->AsTableVal() : nullptr;
}
ListVal* internal_list_val(const char* name)
{
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
const auto& id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id )
return nullptr;
Val* v = id->ID_Val();
Val* v = id->GetVal().get();
if ( v )
{
if ( v->Type()->Tag() == TYPE_LIST )
if ( v->GetType()->Tag() == TYPE_LIST )
return (ListVal*) v;
else if ( v->Type()->IsSet() )
else if ( v->GetType()->IsSet() )
{
TableVal* tv = v->AsTableVal();
ListVal* lv = tv->ConvertToPureList();
return lv;
auto lv = tv->ToPureListVal();
return lv.release();
}
else
@ -762,16 +768,13 @@ ListVal* internal_list_val(const char* name)
BroType* internal_type(const char* name)
{
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
if ( ! id )
reporter->InternalError("internal type %s missing", name);
return id->Type();
return zeek::id::find_type(name).get();
}
Func* internal_func(const char* name)
{
Val* v = internal_val(name);
const auto& v = zeek::id::find_val(name);
if ( v )
return v->AsFunc();
else
@ -780,19 +783,5 @@ Func* internal_func(const char* name)
EventHandlerPtr internal_handler(const char* name)
{
// If there already is an entry in the registry, we have a
// local handler on the script layer.
EventHandler* h = event_registry->Lookup(name);
if ( h )
{
h->SetUsed();
return h;
}
h = new EventHandler(name);
event_registry->Register(h);
h->SetUsed();
return h;
return event_registry->Register(name);
}

View file

@ -17,40 +17,69 @@ class ListVal;
typedef enum { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, } decl_type;
extern void add_global(ID* id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt);
extern void add_global(const IntrusivePtr<ID>& id,
IntrusivePtr<BroType> t,
init_class c,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt);
extern IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id,
IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr,
IntrusivePtr<BroType> t,
init_class c,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt);
extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
IntrusivePtr<Expr> init,
IntrusivePtr<Val> val = nullptr);
extern void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr);
extern void add_type(ID* id, IntrusivePtr<BroType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr);
extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
bool is_redef, IntrusivePtr<FuncType> t,
attr_list* attrs = nullptr);
extern void begin_func(IntrusivePtr<ID> id, const char* module_name,
function_flavor flavor, bool is_redef,
IntrusivePtr<FuncType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs = nullptr);
extern void end_func(IntrusivePtr<Stmt> body);
// Gather all IDs referenced inside a body that aren't part of a given scope.
extern id_list gather_outer_ids(Scope* scope, Stmt* body);
[[deprecated("Remove in v4.1. Use zeek::id::find_val().")]]
extern Val* internal_val(const char* name);
extern Val* internal_const_val(const char* name); // internal error if not const
extern Val* opt_internal_val(const char* name); // returns nil if not defined
extern double opt_internal_double(const char* name);
extern bro_int_t opt_internal_int(const char* name);
extern bro_uint_t opt_internal_unsigned(const char* name);
extern StringVal* opt_internal_string(const char* name);
extern TableVal* opt_internal_table(const char* name); // nil if not defined
extern ListVal* internal_list_val(const char* name);
extern BroType* internal_type(const char* name);
extern Func* internal_func(const char* name);
extern EventHandlerPtr internal_handler(const char* name);
extern int signal_val; // 0 if no signal pending
[[deprecated("Remove in v4.1. Use zeek::id::find_const().")]]
extern Val* internal_const_val(const char* name); // internal error if not const
[[deprecated("Remove in v4.1. Use zeek::id::find() or zeek::id::find_val().")]]
extern Val* opt_internal_val(const char* name); // returns nil if not defined
[[deprecated("Remove in v4.1. Use zeek::id::find() or zeek::id::find_val().")]]
extern double opt_internal_double(const char* name);
[[deprecated("Remove in v4.1. Use zeek::id::find() or zeek::id::find_val().")]]
extern bro_int_t opt_internal_int(const char* name);
[[deprecated("Remove in v4.1. Use zeek::id::find() or zeek::id::find_val().")]]
extern bro_uint_t opt_internal_unsigned(const char* name);
[[deprecated("Remove in v4.1. Use zeek::id::find() or zeek::id::find_val().")]]
extern StringVal* opt_internal_string(const char* name);
[[deprecated("Remove in v4.1. Use zeek::id::find() or zeek::id::find_val().")]]
extern TableVal* opt_internal_table(const char* name); // nil if not defined
[[deprecated("Remove in v4.1. Use zeek::id::find(), zeek::id::find_val(), and/or TableVal::ToPureListVal().")]]
extern ListVal* internal_list_val(const char* name);
[[deprecated("Remove in v4.1. Use zeek::id::find_type().")]]
extern BroType* internal_type(const char* name);
[[deprecated("Remove in v4.1. Use zeek::id::find_func().")]]
extern Func* internal_func(const char* name);
[[deprecated("Remove in v4.1. Use event_registry->Register().")]]
extern EventHandlerPtr internal_handler(const char* name);

View file

@ -687,13 +687,8 @@ void Analyzer::ProtocolConfirmation(Tag arg_tag)
if ( ! protocol_confirmation )
return;
EnumVal* tval = arg_tag ? arg_tag.AsEnumVal() : tag.AsEnumVal();
mgr.Enqueue(protocol_confirmation,
ConnVal(),
IntrusivePtr{NewRef{}, tval},
val_mgr->Count(id)
);
const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal();
mgr.Enqueue(protocol_confirmation, ConnVal(), tval, val_mgr->Count(id));
}
void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
@ -701,27 +696,21 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
if ( ! protocol_violation )
return;
StringVal* r;
IntrusivePtr<StringVal> r;
if ( data && len )
{
const char *tmp = copy_string(reason);
r = new StringVal(fmt("%s [%s%s]", tmp,
r = make_intrusive<StringVal>(fmt("%s [%s%s]", tmp,
fmt_bytes(data, min(40, len)),
len > 40 ? "..." : ""));
delete [] tmp;
}
else
r = new StringVal(reason);
r = make_intrusive<StringVal>(reason);
EnumVal* tval = tag.AsEnumVal();
mgr.Enqueue(protocol_violation,
ConnVal(),
IntrusivePtr{NewRef{}, tval},
val_mgr->Count(id),
IntrusivePtr{AdoptRef{}, r}
);
const auto& tval = tag.AsVal();
mgr.Enqueue(protocol_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r));
}
void Analyzer::AddTimer(analyzer_timer_func timer, double t,
@ -923,12 +912,12 @@ void TransportLayerAnalyzer::Done()
}
void TransportLayerAnalyzer::SetContentsFile(unsigned int /* direction */,
BroFile* /* f */)
IntrusivePtr<BroFile> /* f */)
{
reporter->Error("analyzer type does not support writing to a contents file");
}
BroFile* TransportLayerAnalyzer::GetContentsFile(unsigned int /* direction */) const
IntrusivePtr<BroFile> TransportLayerAnalyzer::GetContentsFile(unsigned int /* direction */) const
{
reporter->Error("analyzer type does not support writing to a contents file");
return nullptr;

View file

@ -911,7 +911,7 @@ public:
* @param f The file to record to.
*
*/
virtual void SetContentsFile(unsigned int direction, BroFile* f);
virtual void SetContentsFile(unsigned int direction, IntrusivePtr<BroFile> f);
/**
* Returns an associated contents file, if any. This must only be
@ -921,7 +921,7 @@ public:
* @param direction One of the CONTENTS_* constants indicating which
* direction the query is for.
*/
virtual BroFile* GetContentsFile(unsigned int direction) const;
virtual IntrusivePtr<BroFile> GetContentsFile(unsigned int direction) const;
/**
* Associates a PIA with this analyzer. A PIA takes the

View file

@ -90,18 +90,16 @@ void Manager::InitPreScript()
void Manager::InitPostScript()
{
auto id = global_scope()->Lookup("Tunnel::vxlan_ports");
const auto& id = global_scope()->Find("Tunnel::vxlan_ports");
if ( ! (id && id->ID_Val()) )
if ( ! (id && id->GetVal()) )
reporter->FatalError("Tunnel::vxlan_ports not defined");
auto table_val = id->ID_Val()->AsTableVal();
auto port_list = table_val->ConvertToPureList();
auto table_val = id->GetVal()->AsTableVal();
auto port_list = table_val->ToPureListVal();
for ( auto i = 0; i < port_list->Length(); ++i )
vxlan_ports.emplace_back(port_list->Index(i)->AsPortVal()->Port());
Unref(port_list);
vxlan_ports.emplace_back(port_list->Idx(i)->AsPortVal()->Port());
}
void Manager::DumpDebug()
@ -440,13 +438,15 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
if ( tcp_contents && ! reass )
{
static auto tcp_content_delivery_ports_orig = zeek::id::find_val<TableVal>("tcp_content_delivery_ports_orig");
static auto tcp_content_delivery_ports_resp = zeek::id::find_val<TableVal>("tcp_content_delivery_ports_resp");
const auto& dport = val_mgr->Port(ntohs(conn->RespPort()), TRANSPORT_TCP);
if ( ! reass )
reass = (bool)tcp_content_delivery_ports_orig->Lookup(dport.get());
reass = (bool)tcp_content_delivery_ports_orig->FindOrDefault(dport);
if ( ! reass )
reass = (bool)tcp_content_delivery_ports_resp->Lookup(dport.get());
reass = (bool)tcp_content_delivery_ports_resp->FindOrDefault(dport);
}
if ( reass )
@ -462,8 +462,10 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
uint16_t resp_port = ntohs(conn->RespPort());
if ( resp_port == 22 || resp_port == 23 || resp_port == 513 )
{
AddrVal src(conn->OrigAddr());
if ( ! stp_skip_src->Lookup(&src) )
static auto stp_skip_src = zeek::id::find_val<TableVal>("stp_skip_src");
auto src = make_intrusive<AddrVal>(conn->OrigAddr());
if ( ! stp_skip_src->FindOrDefault(src) )
tcp->AddChildAnalyzer(new stepping_stone::SteppingStone_Analyzer(conn), false);
}
}
@ -574,8 +576,9 @@ void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp,
void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p,
Val* analyzer, double timeout)
{
EnumVal* ev = analyzer->AsEnumVal();
return ScheduleAnalyzer(orig, resp, resp_p->Port(), resp_p->PortType(), Tag(ev), timeout);
IntrusivePtr<EnumVal> ev{NewRef{}, analyzer->AsEnumVal()};
return ScheduleAnalyzer(orig, resp, resp_p->Port(), resp_p->PortType(),
Tag(std::move(ev)), timeout);
}
Manager::tag_set Manager::GetScheduled(const Connection* conn)
@ -626,8 +629,7 @@ bool Manager::ApplyScheduledAnalyzers(Connection* conn, bool init, TransportLaye
if ( scheduled_analyzer_applied )
conn->EnqueueEvent(scheduled_analyzer_applied, nullptr,
conn->ConnVal(),
IntrusivePtr{NewRef{}, it->AsEnumVal()});
conn->ConnVal(), it->AsVal());
DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled",
analyzer_mgr->GetComponentName(*it).c_str());

View file

@ -6,7 +6,7 @@
const analyzer::Tag analyzer::Tag::Error;
analyzer::Tag::Tag(type_t type, subtype_t subtype)
: ::Tag(analyzer_mgr->GetTagEnumType(), type, subtype)
: ::Tag(analyzer_mgr->GetTagType(), type, subtype)
{
}
@ -16,7 +16,20 @@ analyzer::Tag& analyzer::Tag::operator=(const analyzer::Tag& other)
return *this;
}
const IntrusivePtr<EnumVal>& analyzer::Tag::AsVal() const
{
return ::Tag::AsVal(analyzer_mgr->GetTagType());
}
EnumVal* analyzer::Tag::AsEnumVal() const
{
return ::Tag::AsEnumVal(analyzer_mgr->GetTagEnumType());
return AsVal().get();
}
analyzer::Tag::Tag(IntrusivePtr<EnumVal> val)
: ::Tag(std::move(val))
{ }
analyzer::Tag::Tag(EnumVal* val)
: ::Tag({NewRef{}, val})
{ }

View file

@ -83,6 +83,9 @@ public:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal() const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal() const;
static const Tag Error;
@ -109,7 +112,10 @@ protected:
*
* @param val An enum value of script type \c Analyzer::Tag.
*/
explicit Tag(EnumVal* val) : ::Tag(val) {}
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead")]]
explicit Tag(EnumVal* val);
};
}

View file

@ -41,11 +41,12 @@ function Analyzer::__schedule_analyzer%(orig: addr, resp: addr, resp_p: port,
function __name%(atype: Analyzer::Tag%) : string
%{
return make_intrusive<StringVal>(analyzer_mgr->GetComponentName(atype));
const auto& n = analyzer_mgr->GetComponentName(IntrusivePtr{NewRef{}, atype->AsEnumVal()});
return make_intrusive<StringVal>(n);
%}
function __tag%(name: string%) : Analyzer::Tag
%{
analyzer::Tag t = analyzer_mgr->GetComponentTag(name->CheckString());
return IntrusivePtr{NewRef{}, t.AsEnumVal()};
return t.AsVal();
%}

View file

@ -192,10 +192,10 @@ void ARP_Analyzer::BadARP(const struct arp_pkthdr* hdr, const char* msg)
return;
mgr.Enqueue(bad_arp,
IntrusivePtr{AdoptRef{}, ConstructAddrVal(ar_spa(hdr))},
IntrusivePtr{AdoptRef{}, EthAddrToStr((const u_char*) ar_sha(hdr))},
IntrusivePtr{AdoptRef{}, ConstructAddrVal(ar_tpa(hdr))},
IntrusivePtr{AdoptRef{}, EthAddrToStr((const u_char*) ar_tha(hdr))},
ToAddrVal(ar_spa(hdr)),
ToEthAddrStr((const u_char*) ar_sha(hdr)),
ToAddrVal(ar_tpa(hdr)),
ToEthAddrStr((const u_char*) ar_tha(hdr)),
make_intrusive<StringVal>(msg)
);
}
@ -214,25 +214,31 @@ void ARP_Analyzer::RREvent(EventHandlerPtr e,
return;
mgr.Enqueue(e,
IntrusivePtr{AdoptRef{}, EthAddrToStr(src)},
IntrusivePtr{AdoptRef{}, EthAddrToStr(dst)},
IntrusivePtr{AdoptRef{}, ConstructAddrVal(spa)},
IntrusivePtr{AdoptRef{}, EthAddrToStr((const u_char*) sha)},
IntrusivePtr{AdoptRef{}, ConstructAddrVal(tpa)},
IntrusivePtr{AdoptRef{}, EthAddrToStr((const u_char*) tha)}
ToEthAddrStr(src),
ToEthAddrStr(dst),
ToAddrVal(spa),
ToEthAddrStr((const u_char*) sha),
ToAddrVal(tpa),
ToEthAddrStr((const u_char*) tha)
);
}
AddrVal* ARP_Analyzer::ConstructAddrVal(const void* addr)
{ return ToAddrVal(addr).release(); }
IntrusivePtr<AddrVal> ARP_Analyzer::ToAddrVal(const void* addr)
{
// ### For now, we only handle IPv4 addresses.
return new AddrVal(*(const uint32_t*) addr);
return make_intrusive<AddrVal>(*(const uint32_t*) addr);
}
StringVal* ARP_Analyzer::EthAddrToStr(const u_char* addr)
{ return ToEthAddrStr(addr).release(); }
IntrusivePtr<StringVal> ARP_Analyzer::ToEthAddrStr(const u_char* addr)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
return new StringVal(buf);
return make_intrusive<StringVal>(buf);
}

View file

@ -45,8 +45,14 @@ public:
const char* tpa, const char* tha);
protected:
[[deprecated("Remove in v4.1. Use ToAddrVal().")]]
AddrVal* ConstructAddrVal(const void* addr);
[[deprecated("Remove in v4.1. Use ToEthAddrStr().")]]
StringVal* EthAddrToStr(const u_char* addr);
IntrusivePtr<AddrVal> ToAddrVal(const void* addr);
IntrusivePtr<StringVal> ToEthAddrStr(const u_char* addr);
void BadARP(const struct arp_pkthdr* hdr, const char* string);
void Corrupted(const char* string);
};

View file

@ -3,12 +3,12 @@
%}
%header{
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t);
StringVal* asn1_oid_to_val(const ASN1Encoding* oid);
StringVal* asn1_oid_to_val(const ASN1ObjectIdentifier* oid);
StringVal* asn1_octet_string_to_val(const ASN1Encoding* s);
StringVal* asn1_octet_string_to_val(const ASN1OctetString* s);
IntrusivePtr<Val> asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
IntrusivePtr<Val> asn1_integer_to_val(const ASN1Integer* i, TypeTag t);
IntrusivePtr<StringVal> asn1_oid_to_val(const ASN1Encoding* oid);
IntrusivePtr<StringVal> asn1_oid_to_val(const ASN1ObjectIdentifier* oid);
IntrusivePtr<StringVal> asn1_octet_string_to_val(const ASN1Encoding* s);
IntrusivePtr<StringVal> asn1_octet_string_to_val(const ASN1OctetString* s);
%}
############################## ASN.1 Encodings
@ -102,35 +102,35 @@ function binary_to_int64(bs: bytestring): int64
%code{
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t)
IntrusivePtr<Val> asn1_integer_to_val(const ASN1Integer* i, TypeTag t)
{
return asn1_integer_to_val(i->encoding(), t);
}
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t)
IntrusivePtr<Val> asn1_integer_to_val(const ASN1Encoding* i, TypeTag t)
{
auto v = binary_to_int64(i->content());
switch ( t ) {
case TYPE_BOOL:
return val_mgr->Bool(v)->Ref();
return val_mgr->Bool(v);
case TYPE_INT:
return val_mgr->Int(v).release();
return val_mgr->Int(v);
case TYPE_COUNT:
case TYPE_COUNTER:
return val_mgr->Count(v).release();
return val_mgr->Count(v);
default:
reporter->Error("bad asn1_integer_to_val tag: %s", type_name(t));
return val_mgr->Count(v).release();
return val_mgr->Count(v);
}
}
StringVal* asn1_oid_to_val(const ASN1ObjectIdentifier* oid)
IntrusivePtr<StringVal> asn1_oid_to_val(const ASN1ObjectIdentifier* oid)
{
return asn1_oid_to_val(oid->encoding());
}
StringVal* asn1_oid_to_val(const ASN1Encoding* oid)
IntrusivePtr<StringVal> asn1_oid_to_val(const ASN1Encoding* oid)
{
vector<uint64> oid_components;
vector<vector<uint8> > subidentifiers;
@ -152,7 +152,7 @@ StringVal* asn1_oid_to_val(const ASN1Encoding* oid)
if ( ! subidentifier.empty() || subidentifiers.size() < 1 )
// Underflow.
return val_mgr->EmptyString()->Ref()->AsStringVal();
return val_mgr->EmptyString();
for ( size_t i = 0; i < subidentifiers.size(); ++i )
{
@ -191,17 +191,17 @@ StringVal* asn1_oid_to_val(const ASN1Encoding* oid)
}
}
return new StringVal(rval);
return make_intrusive<StringVal>(rval);
}
StringVal* asn1_octet_string_to_val(const ASN1OctetString* s)
IntrusivePtr<StringVal> asn1_octet_string_to_val(const ASN1OctetString* s)
{
return asn1_octet_string_to_val(s->encoding());
}
StringVal* asn1_octet_string_to_val(const ASN1Encoding* s)
IntrusivePtr<StringVal> asn1_octet_string_to_val(const ASN1Encoding* s)
{
bytestring const& bs = s->content();
return new StringVal(bs.length(), reinterpret_cast<const char*>(bs.data()));
return make_intrusive<StringVal>(bs.length(), reinterpret_cast<const char*>(bs.data()));
}
%}

View file

@ -18,7 +18,7 @@ flow AYIYA_Flow
Connection *c = connection()->bro_analyzer()->Conn();
const EncapsulationStack* e = c->GetEncapsulation();
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
if ( e && e->Depth() >= zeek::BifConst::Tunnel::max_depth )
{
reporter->Weird(c, "tunnel_depth");
return false;

View file

@ -15,11 +15,11 @@
using namespace analyzer::bittorrent;
static TableType* bt_tracker_headers = nullptr;
static RecordType* bittorrent_peer;
static TableType* bittorrent_peer_set;
static RecordType* bittorrent_benc_value;
static TableType* bittorrent_benc_dir;
static IntrusivePtr<TableType> bt_tracker_headers;
static IntrusivePtr<RecordType> bittorrent_peer;
static IntrusivePtr<TableType> bittorrent_peer_set;
static IntrusivePtr<RecordType> bittorrent_benc_value;
static IntrusivePtr<TableType> bittorrent_benc_dir;
BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c)
: tcp::TCP_ApplicationAnalyzer("BITTORRENTTRACKER", c)
@ -27,15 +27,15 @@ BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c)
if ( ! bt_tracker_headers )
{
bt_tracker_headers =
internal_type("bt_tracker_headers")->AsTableType();
zeek::id::find_type<TableType>("bt_tracker_headers");
bittorrent_peer =
internal_type("bittorrent_peer")->AsRecordType();
zeek::id::find_type<RecordType>("bittorrent_peer");
bittorrent_peer_set =
internal_type("bittorrent_peer_set")->AsTableType();
zeek::id::find_type<TableType>("bittorrent_peer_set");
bittorrent_benc_value =
internal_type("bittorrent_benc_value")->AsRecordType();
zeek::id::find_type<RecordType>("bittorrent_benc_value");
bittorrent_benc_dir =
internal_type("bittorrent_benc_dir")->AsTableType();
zeek::id::find_type<TableType>("bittorrent_benc_dir");
}
keep_alive = false;
@ -45,7 +45,7 @@ BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c)
req_buf_pos = req_buf;
req_buf_len = 0;
req_val_uri = nullptr;
req_val_headers = new TableVal({NewRef{}, bt_tracker_headers});
req_val_headers = new TableVal(bt_tracker_headers);
res_state = BTT_RES_STATUS;
res_allow_blank_line = false;
@ -53,9 +53,9 @@ BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c)
res_buf_pos = res_buf;
res_buf_len = 0;
res_status = 0;
res_val_headers = new TableVal({NewRef{}, bt_tracker_headers});
res_val_peers = new TableVal({NewRef{}, bittorrent_peer_set});
res_val_benc = new TableVal({NewRef{}, bittorrent_benc_dir});
res_val_headers = new TableVal(bt_tracker_headers);
res_val_peers = new TableVal(bittorrent_peer_set);
res_val_benc = new TableVal(bittorrent_benc_dir);
InitBencParser();
@ -136,8 +136,7 @@ void BitTorrentTracker_Analyzer::ClientRequest(int len, const u_char* data)
req_buf_len -= (req_buf_pos - req_buf);
memmove(req_buf, req_buf_pos, req_buf_len);
req_buf_pos = req_buf;
req_val_headers =
new TableVal({NewRef{}, bt_tracker_headers});
req_val_headers = new TableVal(bt_tracker_headers);
}
}
}
@ -199,9 +198,9 @@ void BitTorrentTracker_Analyzer::ServerReply(int len, const u_char* data)
res_buf_pos = res_buf;
res_status = 0;
res_val_headers = new TableVal({NewRef{}, bt_tracker_headers});
res_val_peers = new TableVal({NewRef{}, bittorrent_peer_set});
res_val_benc = new TableVal({NewRef{}, bittorrent_benc_dir});
res_val_headers = new TableVal(bt_tracker_headers);
res_val_peers = new TableVal(bittorrent_peer_set);
res_val_benc = new TableVal(bittorrent_benc_dir);
InitBencParser();
}
@ -478,35 +477,29 @@ void BitTorrentTracker_Analyzer::ResponseBenc(int name_len, char* name,
uint32_t ad = extract_uint32((u_char*) value);
uint16_t pt = ntohs((value[4] << 8) | value[5]);
RecordVal* peer = new RecordVal(bittorrent_peer);
auto peer = make_intrusive<RecordVal>(bittorrent_peer);
peer->Assign(0, make_intrusive<AddrVal>(ad));
peer->Assign(1, val_mgr->Port(pt, TRANSPORT_TCP));
res_val_peers->Assign(peer, nullptr);
Unref(peer);
res_val_peers->Assign(std::move(peer), nullptr);
}
}
else
{
StringVal* name_ = new StringVal(name_len, name);
auto name_ = make_intrusive<StringVal>(name_len, name);
auto benc_value = make_intrusive<RecordVal>(bittorrent_benc_value);
benc_value->Assign(type, make_intrusive<StringVal>(value_len, value));
res_val_benc->Assign(name_, std::move(benc_value));
Unref(name_);
res_val_benc->Assign(std::move(name_), std::move(benc_value));
}
}
void BitTorrentTracker_Analyzer::ResponseBenc(int name_len, char* name,
enum btt_benc_types type, bro_int_t value)
{
RecordVal* benc_value = new RecordVal(bittorrent_benc_value);
StringVal* name_ = new StringVal(name_len, name);
auto benc_value = make_intrusive<RecordVal>(bittorrent_benc_value);
auto name_ = make_intrusive<StringVal>(name_len, name);
benc_value->Assign(type, val_mgr->Int(value));
res_val_benc->Assign(name_, benc_value);
Unref(name_);
res_val_benc->Assign(std::move(name_), std::move(benc_value));
}
void BitTorrentTracker_Analyzer::ResponseBody(void)

View file

@ -61,7 +61,7 @@ flow BitTorrent_Flow(is_orig: bool) {
handshake_ok = true;
if ( ::bittorrent_peer_handshake )
{
BifEvent::enqueue_bittorrent_peer_handshake(
zeek::BifEvent::enqueue_bittorrent_peer_handshake(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -79,7 +79,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_keep_alive )
{
BifEvent::enqueue_bittorrent_peer_keep_alive(
zeek::BifEvent::enqueue_bittorrent_peer_keep_alive(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig());
@ -92,7 +92,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_choke )
{
BifEvent::enqueue_bittorrent_peer_choke(
zeek::BifEvent::enqueue_bittorrent_peer_choke(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig());
@ -105,7 +105,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_unchoke )
{
BifEvent::enqueue_bittorrent_peer_unchoke(
zeek::BifEvent::enqueue_bittorrent_peer_unchoke(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig());
@ -118,7 +118,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_interested )
{
BifEvent::enqueue_bittorrent_peer_interested(
zeek::BifEvent::enqueue_bittorrent_peer_interested(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig());
@ -131,7 +131,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_not_interested )
{
BifEvent::enqueue_bittorrent_peer_not_interested(
zeek::BifEvent::enqueue_bittorrent_peer_not_interested(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig());
@ -144,7 +144,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_have )
{
BifEvent::enqueue_bittorrent_peer_have(
zeek::BifEvent::enqueue_bittorrent_peer_have(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -158,7 +158,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_bitfield )
{
BifEvent::enqueue_bittorrent_peer_bitfield(
zeek::BifEvent::enqueue_bittorrent_peer_bitfield(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -173,7 +173,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_request )
{
BifEvent::enqueue_bittorrent_peer_request(
zeek::BifEvent::enqueue_bittorrent_peer_request(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -188,7 +188,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_piece )
{
BifEvent::enqueue_bittorrent_peer_piece(
zeek::BifEvent::enqueue_bittorrent_peer_piece(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -203,7 +203,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_cancel )
{
BifEvent::enqueue_bittorrent_peer_cancel(
zeek::BifEvent::enqueue_bittorrent_peer_cancel(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -217,7 +217,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_port )
{
BifEvent::enqueue_bittorrent_peer_port(
zeek::BifEvent::enqueue_bittorrent_peer_port(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),
@ -231,7 +231,7 @@ flow BitTorrent_Flow(is_orig: bool) {
%{
if ( ::bittorrent_peer_unknown )
{
BifEvent::enqueue_bittorrent_peer_unknown(
zeek::BifEvent::enqueue_bittorrent_peer_unknown(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
is_orig(),

View file

@ -170,12 +170,12 @@ void ConnSize_Analyzer::SetDurationThreshold(double duration)
void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val)
{
// RecordType *connection_type is decleared in NetVar.h
RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal();
RecordVal* orig_endp = conn_val->GetField("orig")->AsRecordVal();
RecordVal* resp_endp = conn_val->GetField("resp")->AsRecordVal();
// endpoint is the RecordType from NetVar.h
int pktidx = endpoint->FieldOffset("num_pkts");
int bytesidx = endpoint->FieldOffset("num_bytes_ip");
int pktidx = zeek::id::endpoint->FieldOffset("num_pkts");
int bytesidx = zeek::id::endpoint->FieldOffset("num_bytes_ip");
if ( pktidx < 0 )
reporter->InternalError("'endpoint' record missing 'num_pkts' field");

View file

@ -37,12 +37,12 @@ refine connection DCE_RPC_Conn += {
%{
if ( dce_rpc_message )
{
BifEvent::enqueue_dce_rpc_message(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_message(bro_analyzer(),
bro_analyzer()->Conn(),
${header.is_orig},
fid,
${header.PTYPE},
BifType::Enum::DCE_RPC::PType->GetVal(${header.PTYPE}));
zeek::BifType::Enum::DCE_RPC::PType->GetVal(${header.PTYPE}));
}
return true;
%}
@ -51,7 +51,7 @@ refine connection DCE_RPC_Conn += {
%{
if ( dce_rpc_bind )
{
BifEvent::enqueue_dce_rpc_bind(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_bind(bro_analyzer(),
bro_analyzer()->Conn(),
fid,
${req.id},
@ -67,7 +67,7 @@ refine connection DCE_RPC_Conn += {
%{
if ( dce_rpc_alter_context )
{
BifEvent::enqueue_dce_rpc_alter_context(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_alter_context(bro_analyzer(),
bro_analyzer()->Conn(),
fid,
${req.id},
@ -92,7 +92,7 @@ refine connection DCE_RPC_Conn += {
else
sec_addr = make_intrusive<StringVal>(${bind.sec_addr}.length(), (const char*) ${bind.sec_addr}.begin());
BifEvent::enqueue_dce_rpc_bind_ack(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_bind_ack(bro_analyzer(),
bro_analyzer()->Conn(),
fid,
std::move(sec_addr));
@ -104,7 +104,7 @@ refine connection DCE_RPC_Conn += {
%{
if ( dce_rpc_alter_context_resp )
{
BifEvent::enqueue_dce_rpc_alter_context_resp(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_alter_context_resp(bro_analyzer(),
bro_analyzer()->Conn(),
fid);
}
@ -115,7 +115,7 @@ refine connection DCE_RPC_Conn += {
%{
if ( dce_rpc_request )
{
BifEvent::enqueue_dce_rpc_request(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_request(bro_analyzer(),
bro_analyzer()->Conn(),
fid,
${req.context_id},
@ -132,7 +132,7 @@ refine connection DCE_RPC_Conn += {
%{
if ( dce_rpc_response )
{
BifEvent::enqueue_dce_rpc_response(bro_analyzer(),
zeek::BifEvent::enqueue_dce_rpc_response(bro_analyzer(),
bro_analyzer()->Conn(),
fid,
${resp.context_id},

View file

@ -210,14 +210,14 @@ flow DCE_RPC_Flow(is_orig: bool) {
flowbuf->NewFrame(0, true);
flowbuf->BufferData(frag.begin(), frag.end());
if ( fb.size() > BifConst::DCE_RPC::max_cmd_reassembly )
if ( fb.size() > zeek::BifConst::DCE_RPC::max_cmd_reassembly )
{
reporter->Weird(connection()->bro_analyzer()->Conn(),
"too_many_dce_rpc_msgs_in_reassembly");
connection()->bro_analyzer()->SetSkip(true);
}
if ( flowbuf->data_length() > (int)BifConst::DCE_RPC::max_frag_data )
if ( flowbuf->data_length() > (int)zeek::BifConst::DCE_RPC::max_frag_data )
{
reporter->Weird(connection()->bro_analyzer()->Conn(),
"too_much_dce_rpc_fragment_data");
@ -233,7 +233,7 @@ flow DCE_RPC_Flow(is_orig: bool) {
auto& flowbuf = it->second;
flowbuf->BufferData(frag.begin(), frag.end());
if ( flowbuf->data_length() > (int)BifConst::DCE_RPC::max_frag_data )
if ( flowbuf->data_length() > (int)zeek::BifConst::DCE_RPC::max_frag_data )
{
reporter->Weird(connection()->bro_analyzer()->Conn(),
"too_much_dce_rpc_fragment_data");

View file

@ -19,8 +19,8 @@ refine flow DHCP_Flow += {
%{
if ( ! options )
{
options = make_intrusive<RecordVal>(BifType::Record::DHCP::Options);
all_options = make_intrusive<VectorVal>(index_vec);
options = make_intrusive<RecordVal>(zeek::BifType::Record::DHCP::Options);
all_options = make_intrusive<VectorVal>(zeek::id::index_vec);
options->Assign(0, all_options);
}
@ -53,7 +53,7 @@ refine flow DHCP_Flow += {
std::string mac_str = fmt_mac(${msg.chaddr}.data(), ${msg.chaddr}.length());
double secs = static_cast<double>(${msg.secs});
auto dhcp_msg_val = make_intrusive<RecordVal>(BifType::Record::DHCP::Msg);
auto dhcp_msg_val = make_intrusive<RecordVal>(zeek::BifType::Record::DHCP::Msg);
dhcp_msg_val->Assign(0, val_mgr->Count(${msg.op}));
dhcp_msg_val->Assign(1, val_mgr->Count(${msg.type}));
dhcp_msg_val->Assign(2, val_mgr->Count(${msg.xid}));
@ -91,7 +91,7 @@ refine flow DHCP_Flow += {
init_options();
BifEvent::enqueue_dhcp_message(connection()->bro_analyzer(),
zeek::BifEvent::enqueue_dhcp_message(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
${msg.is_orig},
std::move(dhcp_msg_val),

View file

@ -57,7 +57,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_router_option(v: OptionValue): bool
%{
VectorVal* router_list = new VectorVal(BifType::Vector::DHCP::Addrs);
auto router_list = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::Addrs);
int num_routers = ${v.router_list}->size();
vector<uint32>* rlist = ${v.router_list};
@ -67,7 +67,7 @@ refine flow DHCP_Flow += {
router_list->Assign(i, make_intrusive<AddrVal>(htonl(raddr)));
}
${context.flow}->options->Assign(2, router_list);
${context.flow}->options->Assign(2, std::move(router_list));
return true;
%}
@ -91,7 +91,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_timeserver_option(v: OptionValue): bool
%{
VectorVal* timeserver_list = new VectorVal(BifType::Vector::DHCP::Addrs);
auto timeserver_list = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::Addrs);
int num_servers = ${v.timeserver_list}->size();
vector<uint32>* rlist = ${v.timeserver_list};
@ -101,7 +101,7 @@ refine flow DHCP_Flow += {
timeserver_list->Assign(i, make_intrusive<AddrVal>(htonl(raddr)));
}
${context.flow}->options->Assign(26, timeserver_list);
${context.flow}->options->Assign(26, std::move(timeserver_list));
return true;
%}
@ -125,7 +125,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_nameserver_option(v: OptionValue): bool
%{
VectorVal* nameserver_list = new VectorVal(BifType::Vector::DHCP::Addrs);
auto nameserver_list = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::Addrs);
int num_servers = ${v.nameserver_list}->size();
vector<uint32>* rlist = ${v.nameserver_list};
@ -135,7 +135,7 @@ refine flow DHCP_Flow += {
nameserver_list->Assign(i, make_intrusive<AddrVal>(htonl(raddr)));
}
${context.flow}->options->Assign(27, nameserver_list);
${context.flow}->options->Assign(27, std::move(nameserver_list));
return true;
%}
@ -159,7 +159,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_dns_server_option(v: OptionValue): bool
%{
VectorVal* server_list = new VectorVal(BifType::Vector::DHCP::Addrs);
auto server_list = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::Addrs);
int num_servers = ${v.dns_server_list}->size();
vector<uint32>* rlist = ${v.dns_server_list};
@ -169,7 +169,7 @@ refine flow DHCP_Flow += {
server_list->Assign(i, make_intrusive<AddrVal>(htonl(raddr)));
}
${context.flow}->options->Assign(3, server_list);
${context.flow}->options->Assign(3, std::move(server_list));
return true;
%}
};
@ -298,7 +298,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_ntpserver_option(v: OptionValue): bool
%{
VectorVal* ntpserver_list = new VectorVal(BifType::Vector::DHCP::Addrs);
auto ntpserver_list = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::Addrs);
int num_servers = ${v.ntpserver_list}->size();
vector<uint32>* rlist = ${v.ntpserver_list};
@ -308,7 +308,7 @@ refine flow DHCP_Flow += {
ntpserver_list->Assign(i, make_intrusive<AddrVal>(htonl(raddr)));
}
${context.flow}->options->Assign(28, ntpserver_list);
${context.flow}->options->Assign(28, std::move(ntpserver_list));
return true;
%}
@ -356,7 +356,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_nbns_option(v: OptionValue): bool
%{
VectorVal* server_list = new VectorVal(BifType::Vector::DHCP::Addrs);
auto server_list = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::Addrs);
int num_servers = ${v.nbns}->size();
vector<uint32>* rlist = ${v.nbns};
@ -366,7 +366,7 @@ refine flow DHCP_Flow += {
server_list->Assign(i, make_intrusive<AddrVal>(htonl(raddr)));
}
${context.flow}->options->Assign(9, server_list);
${context.flow}->options->Assign(9, std::move(server_list));
return true;
%}
};
@ -462,7 +462,7 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_par_req_list_option(v: OptionValue): bool
%{
VectorVal* params = new VectorVal(index_vec);
auto params = make_intrusive<VectorVal>(zeek::id::index_vec);
int num_parms = ${v.par_req_list}->size();
vector<uint8>* plist = ${v.par_req_list};
@ -472,7 +472,7 @@ refine flow DHCP_Flow += {
params->Assign(i, val_mgr->Count(param));
}
${context.flow}->options->Assign(13, params);
${context.flow}->options->Assign(13, std::move(params));
return true;
%}
@ -625,11 +625,11 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_client_id_option(v: OptionValue): bool
%{
RecordVal* client_id = new RecordVal(BifType::Record::DHCP::ClientID);
auto client_id = make_intrusive<RecordVal>(zeek::BifType::Record::DHCP::ClientID);
client_id->Assign(0, val_mgr->Count(${v.client_id.hwtype}));
client_id->Assign(1, make_intrusive<StringVal>(fmt_mac(${v.client_id.hwaddr}.begin(), ${v.client_id.hwaddr}.length())));
${context.flow}->options->Assign(19, client_id);
${context.flow}->options->Assign(19, std::move(client_id));
return true;
%}
@ -685,14 +685,14 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += {
function process_client_fqdn_option(v: OptionValue): bool
%{
RecordVal* client_fqdn = new RecordVal(BifType::Record::DHCP::ClientFQDN);
auto client_fqdn = make_intrusive<RecordVal>(zeek::BifType::Record::DHCP::ClientFQDN);
client_fqdn->Assign(0, val_mgr->Count(${v.client_fqdn.flags}));
client_fqdn->Assign(1, val_mgr->Count(${v.client_fqdn.rcode1}));
client_fqdn->Assign(2, val_mgr->Count(${v.client_fqdn.rcode2}));
const char* domain_name = reinterpret_cast<const char*>(${v.client_fqdn.domain_name}.begin());
client_fqdn->Assign(3, make_intrusive<StringVal>(${v.client_fqdn.domain_name}.length(), domain_name));
${context.flow}->options->Assign(21, client_fqdn);
${context.flow}->options->Assign(21, std::move(client_fqdn));
return true;
%}
@ -743,22 +743,22 @@ refine flow DHCP_Flow += {
function process_relay_agent_inf_option(v: OptionValue): bool
%{
VectorVal* relay_agent_sub_opt = new VectorVal(BifType::Vector::DHCP::SubOpts);
auto relay_agent_sub_opt = make_intrusive<VectorVal>(zeek::BifType::Vector::DHCP::SubOpts);
uint16 i = 0;
for ( auto ptrsubopt = ${v.relay_agent_inf}->begin();
ptrsubopt != ${v.relay_agent_inf}->end(); ++ptrsubopt )
{
auto r = new RecordVal(BifType::Record::DHCP::SubOpt);
auto r = make_intrusive<RecordVal>(zeek::BifType::Record::DHCP::SubOpt);
r->Assign(0, val_mgr->Count((*ptrsubopt)->code()));
r->Assign(1, to_stringval((*ptrsubopt)->value()));
relay_agent_sub_opt->Assign(i, r);
relay_agent_sub_opt->Assign(i, std::move(r));
++i;
}
${context.flow}->options->Assign(22, relay_agent_sub_opt);
${context.flow}->options->Assign(22, std::move(relay_agent_sub_opt));
return true;
%}
};

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