mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00

Added ConnectionEventFast() and QueueEventFast() methods to avoid redundant event handler existence checks. It's common practice for caller to already check for event handler existence before doing all the work of constructing the arguments, so it's desirable to not have to check for existence again. E.g. going through ConnectionEvent() means 3 existence checks: one you do yourself before calling it, one in ConnectionEvent(), and then another in QueueEvent(). The existence check itself can be more than a few operations sometimes as it needs to check a few flags that determine if it's enabled, has a local body, or has any remote receivers in the old comm. system or has been flagged as something to publish in the new comm. system.
88 lines
2.1 KiB
C++
88 lines
2.1 KiB
C++
#include <algorithm>
|
|
|
|
#include "File.h"
|
|
|
|
#include "file_analysis/Manager.h"
|
|
#include "RuleMatcher.h"
|
|
#include "Reporter.h"
|
|
#include "util.h"
|
|
|
|
#include "events.bif.h"
|
|
|
|
using namespace analyzer::file;
|
|
|
|
File_Analyzer::File_Analyzer(const char* name, Connection* conn)
|
|
: TCP_ApplicationAnalyzer(name, conn)
|
|
{
|
|
buffer_len = 0;
|
|
}
|
|
|
|
void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
|
|
{
|
|
tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
|
|
|
int n = min(len, BUFFER_SIZE - buffer_len);
|
|
|
|
if ( n )
|
|
{
|
|
strncpy(buffer + buffer_len, (const char*) data, n);
|
|
buffer_len += n;
|
|
|
|
if ( buffer_len == BUFFER_SIZE )
|
|
Identify();
|
|
}
|
|
|
|
if ( orig )
|
|
file_id_orig = file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(),
|
|
orig, file_id_orig);
|
|
else
|
|
file_id_resp = file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(),
|
|
orig, file_id_resp);
|
|
}
|
|
|
|
void File_Analyzer::Undelivered(uint64 seq, int len, bool orig)
|
|
{
|
|
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
|
|
|
if ( orig )
|
|
file_id_orig = file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig,
|
|
file_id_orig);
|
|
else
|
|
file_id_resp = file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig,
|
|
file_id_resp);
|
|
}
|
|
|
|
void File_Analyzer::Done()
|
|
{
|
|
tcp::TCP_ApplicationAnalyzer::Done();
|
|
|
|
if ( buffer_len && buffer_len != BUFFER_SIZE )
|
|
Identify();
|
|
|
|
if ( ! file_id_orig.empty() )
|
|
file_mgr->EndOfFile(file_id_orig);
|
|
else
|
|
file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), true);
|
|
|
|
if ( ! file_id_resp.empty() )
|
|
file_mgr->EndOfFile(file_id_resp);
|
|
else
|
|
file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), false);
|
|
}
|
|
|
|
void File_Analyzer::Identify()
|
|
{
|
|
RuleMatcher::MIME_Matches matches;
|
|
file_mgr->DetectMIME(reinterpret_cast<const u_char*>(buffer), buffer_len,
|
|
&matches);
|
|
string match = matches.empty() ? "<unknown>"
|
|
: *(matches.begin()->second.begin());
|
|
|
|
if ( file_transferred )
|
|
ConnectionEventFast(file_transferred, {
|
|
BuildConnVal(),
|
|
new StringVal(buffer_len, buffer),
|
|
new StringVal("<unknown>"),
|
|
new StringVal(match),
|
|
});
|
|
}
|