GH-1221: Add unknown_protocols.log for logging packet analyzer lookup failures

This commit is contained in:
Tim Wojtulewicz 2020-10-23 14:45:24 -07:00 committed by Tim Wojtulewicz
parent efe42bc67b
commit c3cf36e135
19 changed files with 222 additions and 31 deletions

View file

@ -43,6 +43,14 @@ void Manager::InitPostScript()
pkt_profiler = new detail::PacketProfiler(detail::pkt_profile_mode,
detail::pkt_profile_freq,
pkt_profile_file->AsFile());
if ( unknown_protocol )
{
unknown_sampling_rate = id::find_val("UnknownProtocol::sampling_rate")->AsCount();
unknown_sampling_threshold = id::find_val("UnknownProtocol::sampling_threshold")->AsCount();
unknown_sampling_duration = id::find_val("UnknownProtocol::sampling_duration")->AsInterval();
unknown_first_bytes_count = id::find_val("UnknownProtocol::first_bytes_count")->AsCount();
}
}
void Manager::Done()
@ -171,3 +179,62 @@ void Manager::DumpPacket(const Packet *pkt, int len)
run_state::detail::pkt_dumper->Dump(pkt);
}
class UnknownProtocolTimer final : public zeek::detail::Timer {
public:
// Represents a combination of an analyzer name and protocol identifier, where the identifier was
// reported as unknown by the analyzer.
using UnknownProtocolPair = std::pair<std::string, uint32_t>;
UnknownProtocolTimer(double t, UnknownProtocolPair p, double timeout)
: zeek::detail::Timer(t + timeout, zeek::detail::TIMER_UNKNOWN_PROTOCOL_EXPIRE),
unknown_protocol(std::move(p))
{}
void Dispatch(double t, bool is_expire) override
{ zeek::packet_mgr->ResetUnknownProtocolTimer(unknown_protocol.first, unknown_protocol.second); }
UnknownProtocolPair unknown_protocol;
};
void Manager::ResetUnknownProtocolTimer(const std::string& analyzer, uint32_t protocol)
{
unknown_protocols.erase(std::make_pair(analyzer, protocol));
}
bool Manager::PermitUnknownProtocol(const std::string& analyzer, uint32_t protocol)
{
auto p = std::make_pair(analyzer, protocol);
uint64_t& count = unknown_protocols[p];
++count;
if ( count == 1 )
detail::timer_mgr->Add(new UnknownProtocolTimer(run_state::network_time, p,
unknown_sampling_duration));
if ( count < unknown_sampling_threshold )
return true;
auto num_above_threshold = count - unknown_sampling_threshold;
if ( unknown_sampling_rate )
return num_above_threshold % unknown_sampling_rate == 0;
return false;
}
void Manager::ReportUnknownProtocol(const std::string& analyzer, uint32_t protocol,
const uint8_t* data, size_t len)
{
if ( unknown_protocol )
{
if ( PermitUnknownProtocol(analyzer, protocol ) )
{
int bytes_len = std::min(unknown_first_bytes_count, static_cast<uint64_t>(len));
event_mgr.Enqueue(unknown_protocol,
make_intrusive<StringVal>(analyzer),
val_mgr->Count(protocol),
make_intrusive<StringVal>(bytes_len, (const char*) data));
}
}
}