Add get_tags_by_category BIF method

This commit is contained in:
bhaskarbhar 2025-06-03 22:06:14 +05:30 committed by Tim Wojtulewicz
parent 4db7d40894
commit 04d6fa3cb7
8 changed files with 120 additions and 3 deletions

10
NEWS
View file

@ -6,7 +6,8 @@ release. For an exhaustive list of changes, see the ``CHANGES`` file
Zeek 8.0.0
==========
We would like to thank ... for their contributions to this release.
We would like to thank Bhaskar Bhar (@bhaskarbhar) for their contributions to this
release.
Breaking Changes
----------------
@ -124,6 +125,13 @@ New Functionality
- The DNS analyzer was extended to support NAPTR RRs (RFC 2915, RFC 3403).
A corresponding ``dns_NAPTR_reply`` event was added.
- A new ``get_tags_by_category`` BIF method was added that returns a list of tags for a
specified plugin category. This can be used in lieu of calling ``zeek -NN`` and
parsing the output. For example, this will return the list of all analyzer plugins
currently loaded:
get_tags_by_category("ANALYZER");
Changed Functionality
---------------------

View file

@ -373,6 +373,18 @@ type endpoint_stats: record {
endian_type: count;
};
## Record containing information about a tag.
##
## .. zeek:see:: get_tags_by_category
type tag_component: record {
name: string;
canonical_name: string;
tag: string;
enabled: bool;
};
type tag_component_vec : vector of tag_component;
## Arguments given to Zeek from the command line. In order to use this, Zeek
## must use a ``--`` command line argument immediately followed by a script
## file and additional arguments after that. For example::

View file

@ -317,6 +317,7 @@ static std::unordered_map<std::string, unsigned int> func_attrs = {
{"global_ids", ATTR_IDEMPOTENT},
{"global_options", ATTR_IDEMPOTENT},
{"gsub", ATTR_FOLDABLE},
{"get_tags_by_category", ATTR_NO_ZEEK_SIDE_EFFECTS},
{"has_event_group", ATTR_NO_ZEEK_SIDE_EFFECTS},
{"has_module_events", ATTR_NO_ZEEK_SIDE_EFFECTS},
{"have_spicy", ATTR_IDEMPOTENT},

View file

@ -9,7 +9,7 @@
%%{ // C++ segment
#include <sys/stat.h>
#include <string>
#include <algorithm>
#include <cinttypes>
#include <cmath>
@ -32,6 +32,9 @@
#include "zeek/Hash.h"
#include "zeek/CompHash.h"
#include "zeek/packet_analysis/Manager.h"
#include "zeek/plugin/Manager.h"
#include "zeek/plugin/Plugin.h"
#include "zeek/plugin/Component.h"
using namespace std;
@ -338,6 +341,34 @@ zeek::RecordValPtr zeek::detail::build_dummy_conn_record()
return c;
}
//List of components
static zeek::plugin::component::Type CategoryStringToEnum(const std::string& category)
{
static const std::unordered_map<std::string, zeek::plugin::component::Type> type_map = {
{"READER", zeek::plugin::component::READER},
{"WRITER", zeek::plugin::component::WRITER},
{"ANALYZER", zeek::plugin::component::ANALYZER},
{"PACKET_ANALYZER", zeek::plugin::component::PACKET_ANALYZER},
{"FILE_ANALYZER", zeek::plugin::component::FILE_ANALYZER},
{"IOSOURCE", zeek::plugin::component::IOSOURCE},
{"PKTSRC", zeek::plugin::component::PKTSRC},
{"PKTDUMPER", zeek::plugin::component::PKTDUMPER},
{"SESSION_ADAPTER", zeek::plugin::component::SESSION_ADAPTER},
{"CLUSTER_BACKEND", zeek::plugin::component::CLUSTER_BACKEND},
{"EVENT_SERIALIZER", zeek::plugin::component::EVENT_SERIALIZER},
{"LOG_SERIALIZER", zeek::plugin::component::LOG_SERIALIZER},
{"STORAGE_BACKEND", zeek::plugin::component::STORAGE_BACKEND},
{"STORAGE_SERIALIZER", zeek::plugin::component::STORAGE_SERIALIZER},
};
auto it = type_map.find(category);
if ( it != type_map.end() )
return it->second;
return static_cast<zeek::plugin::component::Type>(-1); // Invalid
}
%%}
# ===========================================================================
@ -5615,3 +5646,50 @@ function find_in_zeekpath%(p: string%): string
return zeek::make_intrusive<zeek::StringVal>(resolved.c_str());
%}
## Get a list of tags available for a plugin category.
##
## category: The plugin category to request tags for.
##
## Returns: A vector of records containing the tags of all plugin components
## that belong to the specified category.
function get_tags_by_category%(category: string%): tag_component_vec
%{
std::string cat = category->CheckString();
auto type = CategoryStringToEnum(cat);
if ( type == static_cast<plugin::component::Type>(-1) )
{
reporter->Error("Unknown category type: %s", cat.c_str());
return nullptr;
}
static auto vec_type = zeek::id::find_type<zeek::VectorType>("tag_component_vec");
static auto rec_type = zeek::id::find_type<zeek::RecordType>("tag_component");
if ( ! vec_type || ! rec_type )
{
reporter->Error("Required types not found (tag_component or component_vec)");
return nullptr;
}
auto result = zeek::make_intrusive<zeek::VectorVal>(vec_type);
auto all_components = plugin_mgr->Components<plugin::Component>();
for ( auto* component : all_components )
{
if ( component->Type() == type )
{
auto rec = zeek::make_intrusive<zeek::RecordVal>(rec_type);
rec->Assign(0, zeek::make_intrusive<zeek::StringVal>(component->Name()));
rec->Assign(1, zeek::make_intrusive<zeek::StringVal>(component->CanonicalName()));
rec->Assign(2, zeek::make_intrusive<zeek::StringVal>(cat + "_" + component->CanonicalName()));
rec->Assign(3, zeek::make_intrusive<zeek::BoolVal>(component->Enabled()));
result->Append(std::move(rec));
}
}
return result;
%}

View file

@ -0,0 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
[name=FTP, canonical_name=FTP, tag=ANALYZER_FTP, enabled=T]

View file

@ -1,2 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
563 seen BiFs, 0 unseen BiFs (), 0 new BiFs ()
564 seen BiFs, 0 unseen BiFs (), 0 new BiFs ()

View file

@ -0,0 +1,15 @@
#
# @TEST-EXEC: zeek -b %INPUT >out
# @TEST-EXEC: btest-diff out
event zeek_init()
{
local result = get_tags_by_category("ANALYZER");
for (i in result)
{
local rec = result[i];
if ( rec$name == "FTP" )
print rec;
}
}

View file

@ -345,6 +345,7 @@ global known_BiFs = set(
"get_reporter_stats",
"get_resp_seq",
"get_script_comments",
"get_tags_by_category",
"get_thread_stats",
"get_timer_stats",
"getenv",