From a89694b32dec749bb065f4a43409d01e900b7759 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 18 Sep 2023 12:00:37 +0200 Subject: [PATCH] Zeekygen: Merge in Spicy analyzer documentation. This now merges information on analyzers from both plugins and Spicy. Closes #3306. --- src/spicy/manager.cc | 2 +- src/zeekygen/Target.cc | 71 +++++++++++++++---- testing/btest/Baseline/spicy.zeekygen/output2 | 25 +++++++ testing/btest/spicy/zeekygen.zeek | 16 ++++- 4 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 testing/btest/Baseline/spicy.zeekygen/output2 diff --git a/src/spicy/manager.cc b/src/spicy/manager.cc index bf38466108..14a01a4cdc 100644 --- a/src/spicy/manager.cc +++ b/src/spicy/manager.cc @@ -545,7 +545,7 @@ void Manager::analyzerError(packet_analysis::Analyzer* a, const std::string& msg plugin::Configuration Manager::Configure() { ::zeek::plugin::Configuration config; config.name = "Zeek::Spicy"; - config.description = "Support for Spicy parsers (*.hlto)"; + config.description = "Support for Spicy parsers (.hlto)"; EnableHook(::zeek::plugin::HOOK_LOAD_FILE); diff --git a/src/zeekygen/Target.cc b/src/zeekygen/Target.cc index 785c0588e2..046977ef06 100644 --- a/src/zeekygen/Target.cc +++ b/src/zeekygen/Target.cc @@ -19,6 +19,7 @@ #include "zeek/zeekygen/Manager.h" #include "zeek/zeekygen/PackageInfo.h" #include "zeek/zeekygen/ScriptInfo.h" +#include "zeek/zeekygen/SpicyModuleInfo.h" using namespace std; @@ -284,22 +285,66 @@ void AnalyzerTarget::DoGenerate() const void AnalyzerTarget::WriteAnalyzerElements(FILE* f, plugin::component::Type type, bool match_empty) const { - plugin::Manager::plugin_list plugins = plugin_mgr->ActivePlugins(); - plugin::Manager::plugin_list::const_iterator it; + // Create a union of the joint sets of all names provided by plugins and + // Spicy analyzers. - for ( it = plugins.begin(); it != plugins.end(); ++it ) + struct IgnoreCase { - if ( ! ComponentsMatch((*it)->Components(), type, match_empty) ) - continue; + bool operator()(const std::string& a, const std::string& b) const + { + return util::strtolower(a) < util::strtolower(b); + } + }; - write_plugin_section_heading(f, (*it)->Name(), (*it)->Description()); - write_plugin_components(f, (*it)->Components()); - write_plugin_bif_items(f, (*it)->BifItems(), plugin::BifItem::CONSTANT, - "Options/Constants"); - write_plugin_bif_items(f, (*it)->BifItems(), plugin::BifItem::GLOBAL, "Globals"); - write_plugin_bif_items(f, (*it)->BifItems(), plugin::BifItem::TYPE, "Types"); - write_plugin_bif_items(f, (*it)->BifItems(), plugin::BifItem::EVENT, "Events"); - write_plugin_bif_items(f, (*it)->BifItems(), plugin::BifItem::FUNCTION, "Functions"); + std::set names; + std::map plugins; + + for ( auto p : plugin_mgr->ActivePlugins() ) + { + if ( ComponentsMatch(p->Components(), type, match_empty) ) + { + names.insert(p->Name()); + plugins[p->Name()] = p; + } + } + + auto spicy_modules = zeek::detail::zeekygen_mgr->SpicyModules(); + for ( const auto& [name, m] : spicy_modules ) + { + if ( ComponentsMatch(m->Components(), type, match_empty) ) + names.insert(name); + } + + // Now output the information associated with each name in sorted order. + for ( const auto& name : names ) + { + plugin::Plugin::bif_item_list bif_items; + + if ( auto i = plugins.find(name); i != plugins.end() ) // prefer built-in plugins over Spicy + // analyzer in case of name collision + { + auto plugin = i->second; + write_plugin_section_heading(f, plugin->Name(), plugin->Description()); + + if ( name != "Zeek::Spicy" ) // skip components (which are the available Spicy analyzers + // documented separately). + write_plugin_components(f, plugin->Components()); + + bif_items = plugin->BifItems(); + } + else + { + auto module = spicy_modules[name]; + write_plugin_section_heading(f, module->Name(), module->Description()); + write_plugin_components(f, module->Components()); + bif_items = module->BifItems(); + } + + write_plugin_bif_items(f, bif_items, plugin::BifItem::CONSTANT, "Options/Constants"); + write_plugin_bif_items(f, bif_items, plugin::BifItem::GLOBAL, "Globals"); + write_plugin_bif_items(f, bif_items, plugin::BifItem::TYPE, "Types"); + write_plugin_bif_items(f, bif_items, plugin::BifItem::EVENT, "Events"); + write_plugin_bif_items(f, bif_items, plugin::BifItem::FUNCTION, "Functions"); } } diff --git a/testing/btest/Baseline/spicy.zeekygen/output2 b/testing/btest/Baseline/spicy.zeekygen/output2 new file mode 100644 index 0000000000..c6321a8ffd --- /dev/null +++ b/testing/btest/Baseline/spicy.zeekygen/output2 @@ -0,0 +1,25 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +.. _plugin-foo-bar: + +Foo::Bar +-------- + +Just a "test" analyzer.h + +Components +++++++++++ + +:zeek:enum:`Analyzer::ANALYZER_SPICY_SSH` + +Events +++++++ + +.. zeek:id:: ssh::banner + :source-code: <...>/zeekygen.zeek 17 17 + + :Type: :zeek:type:`event` (c: :zeek:type:`connection`, facility: :zeek:type:`count`, severity: :zeek:type:`count`, msg: :zeek:type:`string`) + + Test event. + + Really, just a test ... + diff --git a/testing/btest/spicy/zeekygen.zeek b/testing/btest/spicy/zeekygen.zeek index 9f67ba5c2f..7e2fa5ed1d 100644 --- a/testing/btest/spicy/zeekygen.zeek +++ b/testing/btest/spicy/zeekygen.zeek @@ -4,7 +4,17 @@ # @TEST-EXEC: cat output | grep 'module.s documentation' >output1 # @TEST-EXEC: btest-diff output1 # -# @TEST-DOC: Check that Spicy's tells Zeeygen about its analyzers. (TODO: Test only partially implemented right now) +# @TEST-EXEC: unset ZEEK_DISABLE_ZEEKYGEN && zeek -X zeekygen.conf test.hlto %INPUT +# @TEST-EXEC: cat protocol.rst | sed -n '/_plugin-foo-bar/,/_plugin/p' | sed '$d' >output2 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output2 +# +# @TEST-DOC: Check that Spicy tells Zeekygen about its analyzers. + +## Test event. +## +## Really, just a test ... + +global ssh::banner: event(c: connection, facility: count, severity: count, msg: string); # @TEST-START-FILE doc.spicy @@ -33,3 +43,7 @@ protocol analyzer spicy::SSH over TCP: on SSH::Banner -> event ssh::banner((1, self.software)); # @TEST-END-FILE + +# @TEST-START-FILE zeekygen.conf +proto_analyzer * protocol.rst +