btest/tap-analyzer: Update existing test and add new one for UpdateConnVal()

This also changes the output of connection UIDs from the tap analyzer to be
prefixed with C for easier correlation with other logs.

Relates to #4337 #4725 #4734 #4737
This commit is contained in:
Arne Welzel 2025-08-06 17:03:50 +02:00
parent bdff2935a4
commit f98508bbb0
8 changed files with 671 additions and 59 deletions

View file

@ -0,0 +1,74 @@
#include "Plugin.h"
#include <cstdio>
#include <cstring>
#include "zeek/ID.h"
#include "zeek/Reporter.h"
#include "zeek/analyzer/Analyzer.h"
#include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/protocol/tcp/TCP.h"
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
namespace {
class MyTapAnalyzer : public zeek::packet_analysis::TapAnalyzer {
public:
MyTapAnalyzer(zeek::Connection* conn) : conn(conn) {}
void TapPacket(const zeek::Packet& pkt, zeek::packet_analysis::PacketAction action,
const zeek::packet_analysis::SkipReason skip_reason) override {
std::printf("Packet(len=%d orig=%d, action=%d skip_reason=%d) uid=C%s\n", pkt.len, pkt.is_orig,
static_cast<int>(action), static_cast<int>(skip_reason), conn->GetUID().Base62().c_str());
if ( action == zeek::packet_analysis::PacketAction::Deliver )
++deliver;
else if ( action == zeek::packet_analysis::PacketAction::Skip )
++skip;
else
zeek::reporter->FatalError("Unknown action %d", static_cast<int>(action));
}
void UpdateConnVal(zeek::RecordVal* conn_val) override {
// Set some fields on connection that are added in the zeek script.
static auto tap_deliver_offset = zeek::id::connection->FieldOffset("tap_deliver");
static auto tap_skip_offset = zeek::id::connection->FieldOffset("tap_skip");
conn_val->Assign(tap_deliver_offset, zeek::val_mgr->Count(deliver));
conn_val->Assign(tap_skip_offset, zeek::val_mgr->Count(skip));
}
private:
zeek::Connection* conn = nullptr;
zeek_uint_t deliver = 0;
zeek_uint_t skip = 0;
};
} // namespace
namespace btest::plugin::Demo_TapAnalyzer {
Plugin plugin;
zeek::plugin::Configuration Plugin::Configure() {
EnableHook(zeek::plugin::HOOK_SETUP_ANALYZER_TREE);
zeek::plugin::Configuration config;
config.name = "Demo::TapAnalyzer";
config.description = "Testing the TapAnalyzer";
config.version = {1, 0, 0};
return config;
}
void Plugin::HookSetupAnalyzerTree(zeek::Connection* conn) {
// Init the uid for GetUID()
conn->GetVal();
auto analyzer = std::make_unique<MyTapAnalyzer>(conn);
auto* adapter = conn->GetSessionAdapter();
adapter->AddTapAnalyzer(std::move(analyzer));
std::printf("Analyzer added to uid=C%s\n", conn->GetUID().Base62().c_str());
}
} // namespace btest::plugin::Demo_TapAnalyzer

View file

@ -0,0 +1,18 @@
#pragma once
#include "zeek/plugin/Plugin.h"
namespace btest::plugin::Demo_TapAnalyzer {
class Plugin : public zeek::plugin::Plugin {
protected:
void HookSetupAnalyzerTree(zeek::Connection* conn) override;
// Overridden from zeek::plugin::Plugin.
zeek::plugin::Configuration Configure() override;
};
extern Plugin plugin;
} // namespace btest::plugin::Demo_TapAnalyzer

View file

@ -0,0 +1,50 @@
# @TEST-DOC: A plugin hooking HookSetupAnalyzerTree() to attach a TapAnalyzer to every connection.
#
# @TEST-EXEC: ${DIST}/auxil/zeek-aux/plugin-support/init-plugin -u . Demo TapAnalyzer
# @TEST-EXEC: cp -r %DIR/tap-analyzer-conn-val-plugin/* .
# @TEST-EXEC: ./configure --zeek-dist=${DIST} && make
#
#
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::TapAnalyzer" ZEEK_PLUGIN_PATH=`pwd` zeek -b -r $TRACES/http/get.trace %INPUT >>output
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::TapAnalyzer" ZEEK_PLUGIN_PATH=`pwd` zeek -b -r $TRACES/http/get.trace %INPUT http_skip_further_processing=T >>output
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::TapAnalyzer" ZEEK_PLUGIN_PATH=`pwd` zeek -b -r $TRACES/wikipedia.trace %INPUT >>output
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::TapAnalyzer" ZEEK_PLUGIN_PATH=`pwd` zeek -b -r $TRACES/wikipedia.trace %INPUT http_skip_further_processing=T >>output
#
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output
@load base/protocols/http
redef record connection += {
tap_deliver: count &default=0;
tap_skip: count &default=0;
};
event zeek_init()
{
print packet_source()$path;
}
event zeek_done()
{
print "===";
}
global http_skip_further_processing = F &redef;
event http_request(c: connection, method: string, original_URI: string, unescaped_URI: string, version: string)
{
print fmt("http_request: uid=%s deliver=%s skip=%s", c$uid, c$tap_deliver, c$tap_skip);
if ( http_skip_further_processing )
{
print fmt("skip_further_processing uid=%s", c$uid);
skip_further_processing(c$id);
}
}
event connection_state_remove(c: connection)
{
print fmt("connection_state_remove: %s deliver=%s skip=%s", c$uid, c$tap_deliver, c$tap_skip);
}

View file

@ -16,13 +16,13 @@ public:
void TapPacket(const zeek::Packet& pkt, zeek::packet_analysis::PacketAction action,
const zeek::packet_analysis::SkipReason skip_reason) override {
std::printf("Packet(len=%d orig=%d, action=%d skip_reason=%d) uid=%s\n", pkt.len, pkt.is_orig,
std::printf("Packet(len=%d orig=%d, action=%d skip_reason=%d) uid=C%s\n", pkt.len, pkt.is_orig,
static_cast<int>(action), static_cast<int>(skip_reason), conn->GetUID().Base62().c_str());
}
void Init() override { std::printf("Init() uid=%s\n", conn->GetUID().Base62().c_str()); }
void Init() override { std::printf("Init() uid=C%s\n", conn->GetUID().Base62().c_str()); }
void Done() override { std::printf("Done() uid=%s\n", conn->GetUID().Base62().c_str()); }
void Done() override { std::printf("Done() uid=C%s\n", conn->GetUID().Base62().c_str()); }
private:
zeek::Connection* conn = nullptr;

View file

@ -36,6 +36,11 @@ global http_skip_further_processing = F &redef;
event http_request(c: connection, method: string, original_URI: string, unescaped_URI: string, version: string)
{
print fmt("http_request: uid=%s", c$uid);
if ( http_skip_further_processing )
{
print fmt("skip_further_processing uid=%s", c$uid);
skip_further_processing(c$id);
}
}