Merge remote-tracking branch 'origin/topic/bbannier/issue-3094'

* origin/topic/bbannier/issue-3094:
  Simplify code generated for Spicy analyzer port ranges.
This commit is contained in:
Tim Wojtulewicz 2023-05-31 09:50:46 +02:00
commit 1cfe0e3ee7
8 changed files with 85 additions and 37 deletions

View file

@ -8,12 +8,15 @@ import hilti;
public type Val = __library_type("::zeek::ValPtr");
public type BroType = __library_type("::zeek::TypePtr");
public type EventHandlerPtr = __library_type("::zeek::EventHandlerPtr");
public type PortRange = __library_type("::zeek::spicy::rt::PortRange");
declare public PortRange make_port_range(port begin_, port end_) &cxxname="zeek::spicy::rt::make_port_range" &have_prototype;
type ZeekTypeTag = enum {
Addr, Any, Bool, Count, Double, Enum, Error, File, Func, Int, Interval, List, Opaque, Pattern, Port, Record, String, Subnet, Table, Time, Type, Vector, Void
} &cxxname="::zeek::spicy::rt::ZeekTypeTag";
declare public void register_protocol_analyzer(string name, hilti::Protocol protocol, vector<port> ports, string parser_orig, string parser_resp, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_protocol_analyzer" &have_prototype;
declare public void register_protocol_analyzer(string name, hilti::Protocol protocol, vector<PortRange> ports, string parser_orig, string parser_resp, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_protocol_analyzer" &have_prototype;
declare public void register_file_analyzer(string name, vector<string> mime_types, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_file_analyzer" &have_prototype;
declare public void register_packet_analyzer(string name, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_packet_analyzer" &have_prototype;
declare public void register_type(string ns, string id, BroType t) &cxxname="zeek::spicy::rt::register_type" &have_prototype;

View file

@ -6,6 +6,7 @@
#include <glob.h>
#include <exception>
#include <limits>
#include <utility>
#include <hilti/rt/configuration.h>
@ -47,9 +48,9 @@ static std::pair<std::string, std::string> parseID(const std::string& s) {
Manager::~Manager() {}
void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto,
const hilti::rt::Vector<hilti::rt::Port>& ports, const std::string& parser_orig,
const std::string& parser_resp, const std::string& replaces,
const std::string& linker_scope) {
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
const std::string& parser_orig, const std::string& parser_resp,
const std::string& replaces, const std::string& linker_scope) {
SPICY_DEBUG(hilti::rt::fmt("Have Spicy protocol analyzer %s", name));
ProtocolAnalyzerInfo info;
@ -683,9 +684,19 @@ void Manager::InitPostScript() {
if ( ! tag )
reporter->InternalError("cannot get analyzer tag for '%s'", p.name_analyzer.c_str());
for ( auto port : p.ports ) {
SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port));
analyzer_mgr->RegisterAnalyzerForPort(tag, transport_protocol(port), port.port());
for ( const auto& ports : p.ports ) {
const auto proto = ports.begin.protocol();
// Port ranges are closed intervals.
for ( auto port = ports.begin.port(); port <= ports.end.port(); ++port ) {
const auto port_ = hilti::rt::Port(port, proto);
SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port_));
analyzer_mgr->RegisterAnalyzerForPort(tag, transport_protocol(port_), port);
// Explicitly prevent overflow.
if ( port == std::numeric_limits<decltype(port)>::max() )
break;
}
}
if ( p.parser_resp ) {

View file

@ -17,6 +17,7 @@
#include "zeek/Tag.h"
#include "zeek/plugin/Component.h"
#include "zeek/plugin/Plugin.h"
#include "zeek/spicy/port-range.h"
#include "zeek/spicy/spicyz/config.h" // include for Spicy version
// Macro helper to report Spicy debug messages. This forwards to
@ -81,9 +82,9 @@ public:
* registration
*/
void registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto,
const hilti::rt::Vector<hilti::rt::Port>& ports, const std::string& parser_orig,
const std::string& parser_resp, const std::string& replaces,
const std::string& linker_scope);
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
const std::string& parser_orig, const std::string& parser_resp,
const std::string& replaces, const std::string& linker_scope);
/**
* Runtime method to register a file analyzer with its Zeek-side
@ -325,7 +326,7 @@ private:
std::string name_parser_resp;
std::string name_replaces;
hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef;
hilti::rt::Vector<hilti::rt::Port> ports;
hilti::rt::Vector<::zeek::spicy::rt::PortRange> ports;
std::string linker_scope;
// Computed and available once the analyzer has been registered.

32
src/spicy/port-range.h Normal file
View file

@ -0,0 +1,32 @@
// See the file "COPYING" in the main distribution directory for copyright.
#pragma once
#include <cassert>
#include <tuple>
#include <hilti/rt/types/port.h>
namespace zeek::spicy::rt {
/** A closed ranged of ports. */
struct PortRange {
PortRange() = default;
PortRange(hilti::rt::Port begin_, hilti::rt::Port end_) : begin(begin_), end(end_) {
assert(begin.port() <= end.port());
assert(begin.protocol() == end.protocol());
}
hilti::rt::Port begin; /**< first port in the range */
hilti::rt::Port end; /**< last port in the range */
};
inline bool operator==(const PortRange& a, const PortRange& b) {
return std::tie(a.begin, a.end) == std::tie(b.begin, b.end);
}
inline bool operator!=(const PortRange& a, const PortRange& b) { return ! (a == b); }
inline PortRange make_port_range(hilti::rt::Port begin, hilti::rt::Port end) { return PortRange(begin, end); }
} // namespace zeek::spicy::rt

View file

@ -21,9 +21,9 @@ using namespace zeek;
using namespace zeek::spicy;
void rt::register_protocol_analyzer(const std::string& name, hilti::rt::Protocol proto,
const hilti::rt::Vector<hilti::rt::Port>& ports, const std::string& parser_orig,
const std::string& parser_resp, const std::string& replaces,
const std::string& linker_scope) {
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
const std::string& parser_orig, const std::string& parser_resp,
const std::string& replaces, const std::string& linker_scope) {
auto _ = hilti::rt::profiler::start("zeek/rt/register_protocol_analyzer");
spicy_mgr->registerProtocolAnalyzer(name, proto, ports, parser_orig, parser_resp, replaces, linker_scope);
}

View file

@ -23,6 +23,7 @@
#include "zeek/Desc.h"
#include "zeek/spicy/cookie.h"
#include "zeek/spicy/manager.h"
#include "zeek/spicy/port-range.h"
namespace zeek::spicy::rt {
@ -93,9 +94,9 @@ public:
* plugin's runtime.
*/
void register_protocol_analyzer(const std::string& name, hilti::rt::Protocol proto,
const hilti::rt::Vector<hilti::rt::Port>& ports, const std::string& parser_orig,
const std::string& parser_resp, const std::string& replaces,
const std::string& linker_scope);
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
const std::string& parser_orig, const std::string& parser_resp,
const std::string& replaces, const std::string& linker_scope);
/**
* Registers a Spicy file analyzer with its EVT meta information with the

View file

@ -16,6 +16,7 @@
#include <spicy/global.h>
#include "config.h"
#include "zeek/spicy/port-range.h"
using namespace zeek::spicy;
@ -279,7 +280,7 @@ static hilti::rt::Port extract_port(const std::string& chunk, size_t* i) {
return {static_cast<uint16_t>(port), proto};
}
static std::vector<hilti::rt::Port> extract_ports(const std::string& chunk, size_t* i) {
static ::zeek::spicy::rt::PortRange extract_port_range(const std::string& chunk, size_t* i) {
auto start = extract_port(chunk, i);
auto end = std::optional<hilti::rt::Port>();
@ -296,16 +297,11 @@ static std::vector<hilti::rt::Port> extract_ports(const std::string& chunk, size
throw ParseError("start of port range cannot be after its end");
}
std::vector<hilti::rt::Port> result;
if ( ! end )
// EVT port ranges are a closed interval, but rt are half-closed.
end = hilti::rt::Port(start.port() + 1, start.protocol());
// Port ranges are a closed interval.
for ( auto port = start.port(); ! end || port <= end->port(); ++port ) {
result.emplace_back(port, start.protocol());
if ( ! end )
break;
}
return result;
return {start, *end};
}
void GlueCompiler::Init(Driver* driver, int zeek_version) {
@ -609,8 +605,7 @@ glue::ProtocolAnalyzer GlueCompiler::parseProtocolAnalyzer(const std::string& ch
eat_token(chunk, &i, "{");
while ( true ) {
auto ports = extract_ports(chunk, &i);
a.ports.insert(a.ports.end(), ports.begin(), ports.end());
a.ports.push_back(extract_port_range(chunk, &i));
if ( looking_at(chunk, i, "}") ) {
eat_token(chunk, &i, "}");
@ -623,8 +618,7 @@ glue::ProtocolAnalyzer GlueCompiler::parseProtocolAnalyzer(const std::string& ch
else if ( looking_at(chunk, i, "port") ) {
eat_token(chunk, &i, "port");
auto ports = extract_ports(chunk, &i);
a.ports.insert(a.ports.end(), ports.begin(), ports.end());
a.ports.push_back(extract_port_range(chunk, &i));
}
else if ( looking_at(chunk, i, "replaces") ) {
@ -855,11 +849,16 @@ bool GlueCompiler::compile() {
default: hilti::logger().internalError("unexpected protocol");
}
preinit_body.addCall("zeek_rt::register_protocol_analyzer",
{builder::string(a.name), builder::id(protocol),
builder::vector(hilti::util::transform(a.ports, [](auto p) { return builder::port(p); })),
builder::string(a.unit_name_orig), builder::string(a.unit_name_resp),
builder::string(a.replaces), _linker_scope()});
preinit_body.addCall(
"zeek_rt::register_protocol_analyzer",
{builder::string(a.name), builder::id(protocol),
builder::vector(hilti::util::transform(
a.ports,
[](const auto& p) {
return builder::call("zeek_rt::make_port_range", {builder::port(p.begin), builder::port(p.end)});
})),
builder::string(a.unit_name_orig), builder::string(a.unit_name_resp), builder::string(a.replaces),
_linker_scope()});
}
for ( auto& a : _file_analyzers ) {

View file

@ -27,6 +27,7 @@
#include <spicy/ast/types/unit.h>
#include "driver.h"
#include "zeek/spicy/port-range.h"
namespace spicy::rt {
struct Parser;
@ -42,7 +43,7 @@ struct ProtocolAnalyzer {
hilti::Location location; /**< Location where the analyzer was defined. */
hilti::ID name; /**< Name of the analyzer. */
hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef; /**< The transport layer the analyzer uses. */
std::vector<hilti::rt::Port> ports; /**< The ports associated with the analyzer. */
std::vector<::zeek::spicy::rt::PortRange> ports; /**< The ports associated with the analyzer. */
hilti::ID unit_name_orig; /**< The fully-qualified name of the unit type to parse the originator
side. */
hilti::ID unit_name_resp; /**< The fully-qualified name of the unit type to parse the originator