How to make errors of zeek::protocol_begin non fatal?

I’m using zeek::protocol_begin in a spicy parser to pass the payload to another analyzer (which I am also developing). This works well.
However, the plugin only works if the other plugin is also loaded. So you can’t use it on its own.

What is particularly problematic for me, however, is that test cases with traces no longer work.

Is there an easy way to make an error of zeek::protocol_begin not fatal?

I assume you are using the overload of zeek::protocol_begin with a child name to forward to a particular named analyzer,

function zeek::protocol_begin(
    analyzer: optional<string>,
    protocol: spicy::Protocol = spicy::Protocol::TCP);

If your downstream analyzer supports DPD you could instead use the overload forwarding into DPD so a child analyzer is picked based on content.

function zeek::protocol_begin(protocol: spicy::Protocol = spicy::Protocol::TCP);

If the child analyzer does not support DPD (e.g., because you pass additional data to it in band like discsussed in How to push status information from a spicy parser to an cpp parser?), you need to explicitly keep track whether the child analyzer is loaded. You could do that by querying that from the Zeek side and persisting the result, and then access that information from your Spicy code, e.g.,

# e.g., in your parent analyzer's `main.zeek`
const HAS_MY_CHILD_ANALYZER = Analyzer::has_tag("MY_CHILD_ANALYZER");

and then in your Spicy code

global HAS_MY_CHILD_ANALYZER = zeek::get_bool("HAS_MY_CHILD_ANALYZER"); # Semantically const.

...

zeek::protocol_begin(); # Adds DPD as a child analyzer.

...

# Guard at least the forwarding, maybe also the `protocol_begin`.
if (HAS_MY_CHILD_ANALYZER) {
    zeek::protocol_data_in(is_orig, $$); # Forward data to DPD.
}

I didn’t even think of combining zeek and spicy via get_value. It works much better with your solution. But it still has a limitation: If the zeek script is not loaded, then get_bool gives a fatal error. So there is no longer a dependency on the other analyzer, but on the zeek script within the same analyzer.

I therefore used johanna’s solution in the post How to push status information from a spicy parser to an cpp parser? and added a very simple C++ function to the spicy parser that queries the analyzer_mgr directly. Now there is no dependency on a zeek scripts anymore.

Nevertheless, your suggestion has helped me a lot. Thanks for that!

You could do that by querying that from the Zeek side and persisting the result, and then access that information from your Spicy code, e.g.,

Would protocol_handle_get_or_create not be an option? Are users able to handle the errors if the requested analyzer doesn’t exist?

Controlling Zeek from Spicy

This function will return an error if:
not called from a protocol analyzer, or
the requested child protocol analyzer is of unknown type or not support by the requested transport protocol, or
creation of a child analyzer of the requested type was prevented by a previous call of disable_analyzer with prevent=T

I also thought at first that the function protocol_handle_get_or_create could be used. But it is the reason for the problem. In fact begin_protocol also calls it. The function creates the analyzer as follows:

auto child = analyzer_mgr->InstantiateAnalyzer(analyzer.c_str(), c->analyzer->Conn());
if ( ! child )
    throw ZeekError(::hilti::rt::fmt("unknown analyzer '%s' requested", analyzer));

Ah, gotcha. Seems a protocol_handle_try_get_or_create returning an optional would be a good improvement, assuming this is a regular use-case. Neither writing C++, nor offloading to Zeek script seems great if the Spicy/Zeek integration technically has all that information.

Would you be up for creating a feature request at GitHub - zeek/spicy: C++ parser generator for dissecting protocols & files.?

In fact, I would prefer it if there was a new function is_analyzer_available (or similar), which could then be used to protect the other functions (e.g. begin_prococol). If you have no objections, I would submit a feature request tomorrow.

1 Like

Issues are always welcome, and there is no need to ask for permission!

I did create Improve UX around forwarding to non-existing protocol analyzers from Spicy · Issue #4481 · zeek/zeek · GitHub capturing both what you and @awelzel mentioned since they seem like worthwhile additions.