From 75aa6588fe659b9e6e1a8b88a6e6fe1ff568d767 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 21 May 2025 16:48:47 +0200 Subject: [PATCH] Event/zeek.bif: Add EventMetadata current() and current_values() accessors ...and basic smoke testing. --- src/Event.cc | 34 ++++++++++++++ src/Event.h | 12 +++++ src/zeek.bif | 44 +++++++++++++++++++ .../.stderr | 1 + .../.stdout | 1 + .../with_ts.out | 2 + .../without_ts.out | 2 + .../core.event-metadata.non-event/.stderr | 1 + .../core.event-metadata.non-event/.stdout | 1 + .../core.event-metadata.register/.stderr | 1 + .../core.event-metadata.register/.stdout | 1 + .../event-metadata/network-timestamp.zeek | 17 +++++++ .../btest/core/event-metadata/non-event.zeek | 8 ++++ .../btest/core/event-metadata/register.zeek | 30 +++++++++++++ 14 files changed, 155 insertions(+) create mode 100644 testing/btest/Baseline/core.event-metadata.network-timestamp/.stderr create mode 100644 testing/btest/Baseline/core.event-metadata.network-timestamp/.stdout create mode 100644 testing/btest/Baseline/core.event-metadata.network-timestamp/with_ts.out create mode 100644 testing/btest/Baseline/core.event-metadata.network-timestamp/without_ts.out create mode 100644 testing/btest/Baseline/core.event-metadata.non-event/.stderr create mode 100644 testing/btest/Baseline/core.event-metadata.non-event/.stdout create mode 100644 testing/btest/Baseline/core.event-metadata.register/.stderr create mode 100644 testing/btest/Baseline/core.event-metadata.register/.stdout create mode 100644 testing/btest/core/event-metadata/network-timestamp.zeek create mode 100644 testing/btest/core/event-metadata/non-event.zeek create mode 100644 testing/btest/core/event-metadata/register.zeek diff --git a/src/Event.cc b/src/Event.cc index 7465fff410..e74936b1c8 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -66,6 +66,40 @@ Event::Event(detail::EventMetadataVectorPtr arg_meta, const EventHandlerPtr& arg Ref(obj); } +zeek::VectorValPtr Event::MetadataValues(const EnumValPtr& id) const { + static const auto& any_vec_t = zeek::id::find_type("any_vec"); + auto result = zeek::make_intrusive(any_vec_t); + + if ( ! meta ) + return result; + + auto id_int = id->Get(); + if ( id_int < 0 ) + zeek::reporter->InternalError("Negative enum value %s: %" PRId64, obj_desc_short(id.get()).c_str(), id_int); + + zeek_uint_t uintid = static_cast(id_int); + const auto* desc = event_registry->LookupMetadata(uintid); + if ( ! desc ) + return result; + + for ( const auto& entry : *meta ) { + if ( entry.Id() != uintid ) + continue; + + // Sanity check the type. + if ( ! same_type(desc->Type(), entry.Val()->GetType()) ) { + zeek::reporter->InternalWarning("metadata has unexpected type %s, wanted %s", + obj_desc_short(entry.Val()->GetType().get()).c_str(), + obj_desc_short(desc->Type().get()).c_str()); + continue; + } + + result->Append(entry.Val()); + } + + return result; +} + double Event::Time() const { if ( ! meta ) return 0.0; diff --git a/src/Event.h b/src/Event.h index 1edda36bc3..0826b251c6 100644 --- a/src/Event.h +++ b/src/Event.h @@ -66,6 +66,18 @@ public: const zeek::Args& Args() const { return args; } double Time() const; + /** + * @return a pointer to the MetadataVector of this event or a nullptr. + */ + const detail::EventMetadataVector* Metadata() const { return meta.get(); } + + /** + * @return a vector of values for metadata matching identifier \a id. + * + * @param id The metadata identifier as an enum value. + */ + VectorValPtr MetadataValues(const EnumValPtr& id) const; + void Describe(ODesc* d) const override; private: diff --git a/src/zeek.bif b/src/zeek.bif index 5807ee80c7..93f9569850 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -428,6 +428,50 @@ function EventMetadata::register%(id: EventMetadata::ID, t: any%): bool return zeek::val_mgr->Bool(r); %} +## Query the current event's metadata with identifier *id*. +## +## id: The metadata identifier, e.g. ``EventMetadata::NETWORK_TIMESTAMP``. +## +## Returns: A vector of values. The vector is empty if no metadata with +## the given identifier is attached to this event, otherwise a +## vector whose elements are of the type used during registration. +## +## .. zeek:see:: EventMetadata::register EventMetadata::current_all +function EventMetadata::current%(id: EventMetadata::ID%): any_vec + %{ + static const auto& vt = zeek::id::find_type("any_vec"); + + const auto* event = zeek::event_mgr.CurrentEvent(); + if ( ! event ) + return zeek::make_intrusive(vt); + + return event->MetadataValues({zeek::NewRef{}, id->AsEnumVal()}); + %} + +## Query all of the current event's metadata. +## +## Returns: A vector :zeek:see:`EventMetadata::Entry` elements holding all +## the metadata attached to this event. +## +## .. zeek:see:: EventMetadata::register EventMetadata::current +function EventMetadata::current_all%(%): event_metadata_vec + %{ + static const auto& vt = zeek::id::find_type("event_metadata_vec"); + auto result = zeek::make_intrusive(vt); + + const auto* event = zeek::event_mgr.CurrentEvent(); + if ( ! event ) + return result; + + if ( const auto* mdv = event->Metadata() ) { + for ( const auto& entry : *mdv ) + result->Append(entry.BuildVal()); + + } + + return result; + %} + ## Returns a system environment variable. ## ## var: The name of the variable whose value to request. diff --git a/testing/btest/Baseline/core.event-metadata.network-timestamp/.stderr b/testing/btest/Baseline/core.event-metadata.network-timestamp/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.network-timestamp/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/core.event-metadata.network-timestamp/.stdout b/testing/btest/Baseline/core.event-metadata.network-timestamp/.stdout new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.network-timestamp/.stdout @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/core.event-metadata.network-timestamp/with_ts.out b/testing/btest/Baseline/core.event-metadata.network-timestamp/with_ts.out new file mode 100644 index 0000000000..01ede881c4 --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.network-timestamp/with_ts.out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +new_connection CHhAvVGS1DHFjwGM9 all=[[id=EventMetadata::NETWORK_TIMESTAMP, val=1362692526.869344]] network_timestamp=[1362692526.869344] diff --git a/testing/btest/Baseline/core.event-metadata.network-timestamp/without_ts.out b/testing/btest/Baseline/core.event-metadata.network-timestamp/without_ts.out new file mode 100644 index 0000000000..9c9414d530 --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.network-timestamp/without_ts.out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +new_connection CHhAvVGS1DHFjwGM9 all=[] network_timestamp=[] diff --git a/testing/btest/Baseline/core.event-metadata.non-event/.stderr b/testing/btest/Baseline/core.event-metadata.non-event/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.non-event/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/core.event-metadata.non-event/.stdout b/testing/btest/Baseline/core.event-metadata.non-event/.stdout new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.non-event/.stdout @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/core.event-metadata.register/.stderr b/testing/btest/Baseline/core.event-metadata.register/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.register/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/core.event-metadata.register/.stdout b/testing/btest/Baseline/core.event-metadata.register/.stdout new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/core.event-metadata.register/.stdout @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/core/event-metadata/network-timestamp.zeek b/testing/btest/core/event-metadata/network-timestamp.zeek new file mode 100644 index 0000000000..2d90f3c71f --- /dev/null +++ b/testing/btest/core/event-metadata/network-timestamp.zeek @@ -0,0 +1,17 @@ +# @TEST-DOC: Check network timestamp available if opt-in. +# +# @TEST-EXEC: zeek -r $TRACES/http/get.trace %INPUT EventMetadata::add_network_timestamp=T > with_ts.out +# @TEST-EXEC: zeek -r $TRACES/http/get.trace %INPUT EventMetadata::add_network_timestamp=F > without_ts.out +# +# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff with_ts.out +# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff without_ts.out +# @TEST-EXEC: btest-diff .stderr + + +event new_connection(c: connection) + { + print fmt("new_connection %s all=%s network_timestamp=%s", + c$uid, + EventMetadata::current_all(), + EventMetadata::current(EventMetadata::NETWORK_TIMESTAMP)); + } diff --git a/testing/btest/core/event-metadata/non-event.zeek b/testing/btest/core/event-metadata/non-event.zeek new file mode 100644 index 0000000000..acf80e941c --- /dev/null +++ b/testing/btest/core/event-metadata/non-event.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Ensure EventMetadata::current() and EventMetadata::current_all() in non-event context returns empty vectors. +# +# @TEST-EXEC: zeek -b %INPUT +# @TEST-EXEC: btest-diff .stdout +# @TEST-EXEC: btest-diff .stderr + +assert |EventMetadata::current(EventMetadata::NETWORK_TIMESTAMP)| == 0; +assert |EventMetadata::current_all()| == 0; diff --git a/testing/btest/core/event-metadata/register.zeek b/testing/btest/core/event-metadata/register.zeek new file mode 100644 index 0000000000..ae90712b6f --- /dev/null +++ b/testing/btest/core/event-metadata/register.zeek @@ -0,0 +1,30 @@ +# @TEST-DOC: Very basic registration of event metadata identifiers. +# +# @TEST-EXEC: zeek -b %INPUT +# @TEST-EXEC: btest-diff .stdout +# @TEST-EXEC: btest-diff .stderr + +module App; + +export { + redef enum EventMetadata::ID += { + MY_STRING = 1000, + MY_COUNT = 1001, + MY_TABLE = 1002, + }; +} + +event zeek_init() + { + assert EventMetadata::register(MY_STRING, string); + assert EventMetadata::register(MY_STRING, string); # double register is okay + assert EventMetadata::register(MY_COUNT, count); + assert EventMetadata::register(MY_COUNT, count); + assert EventMetadata::register(MY_TABLE, table[string] of count); + assert EventMetadata::register(MY_TABLE, table[string] of count); + + # Type mismatch all return F, but no output on stderr. + assert ! EventMetadata::register(MY_STRING, count); + assert ! EventMetadata::register(MY_COUNT, string); + assert ! EventMetadata::register(MY_TABLE, table[count] of string); + }