zeek/src/file_analysis/Analyzer.cc
2025-06-06 11:43:06 -07:00

94 lines
2.9 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/file_analysis/Analyzer.h"
#include "zeek/Event.h"
#include "zeek/Val.h"
#include "zeek/file_analysis/File.h"
#include "zeek/file_analysis/Manager.h"
#include "const.bif.netvar_h" // for max_analyzer_violations
#include "event.bif.netvar_h" // for analyzer_violation_info
namespace zeek::file_analysis {
ID Analyzer::id_counter = 0;
Analyzer::~Analyzer() {
DBG_LOG(DBG_FILE_ANALYSIS, "Destroy file analyzer %s", file_mgr->GetComponentName(tag).c_str());
}
void Analyzer::SetAnalyzerTag(const zeek::Tag& arg_tag) {
assert(! tag || tag == arg_tag);
tag = arg_tag;
}
Analyzer::Analyzer(zeek::Tag arg_tag, RecordValPtr arg_args, File* arg_file)
: tag(std::move(arg_tag)),
args(std::move(arg_args)),
file(arg_file),
got_stream_delivery(false),
skip(false),
analyzer_confirmed(false) {
id = ++id_counter;
}
Analyzer::Analyzer(RecordValPtr arg_args, File* arg_file) : Analyzer({}, std::move(arg_args), arg_file) {}
const char* Analyzer::GetAnalyzerName() const {
assert(tag);
return file_mgr->GetComponentName(tag).c_str();
}
void Analyzer::AnalyzerConfirmation(zeek::Tag arg_tag) {
if ( analyzer_confirmed )
return;
analyzer_confirmed = true;
if ( ! analyzer_confirmation_info )
return;
static auto info_type = zeek::id::find_type<RecordType>("AnalyzerConfirmationInfo");
static auto info_f_idx = info_type->FieldOffset("f");
auto info = zeek::make_intrusive<RecordVal>(info_type);
info->Assign(info_f_idx, GetFile()->ToVal());
const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal();
event_mgr.Enqueue(analyzer_confirmation_info, tval, info);
}
void Analyzer::AnalyzerViolation(const char* reason, const char* data, int len, zeek::Tag arg_tag) {
++analyzer_violations;
if ( analyzer_violations > BifConst::max_analyzer_violations ) {
if ( analyzer_violations == BifConst::max_analyzer_violations + 1 )
Weird("too_many_analyzer_violations");
return;
}
if ( ! analyzer_violation_info )
return;
static auto info_type = zeek::id::find_type<RecordType>("AnalyzerViolationInfo");
static auto info_reason_idx = info_type->FieldOffset("reason");
static auto info_f_idx = info_type->FieldOffset("f");
static auto info_data_idx = info_type->FieldOffset("data");
auto info = zeek::make_intrusive<RecordVal>(info_type);
info->Assign(info_reason_idx, make_intrusive<StringVal>(reason));
info->Assign(info_f_idx, GetFile()->ToVal());
if ( data && len )
info->Assign(info_data_idx, make_intrusive<StringVal>(len, data));
const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal();
event_mgr.Enqueue(analyzer_violation_info, tval, info);
}
void Analyzer::Weird(const char* name, const char* addl) {
zeek::reporter->Weird(GetFile(), name, addl, GetAnalyzerName());
}
} // namespace zeek::file_analysis