mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add packet analyzer history
This commit is contained in:
parent
f943366e8e
commit
29bc84e1d6
5 changed files with 45 additions and 3 deletions
|
@ -25,16 +25,23 @@ export {
|
||||||
## A certain number of bytes at the start of the unknown protocol's
|
## A certain number of bytes at the start of the unknown protocol's
|
||||||
## header.
|
## header.
|
||||||
first_bytes: string &log;
|
first_bytes: string &log;
|
||||||
|
|
||||||
|
## The chain of packet analyzers that processed the packet up to this
|
||||||
|
## point. This includes the history of encapsulating packets in case
|
||||||
|
## of tunneling.
|
||||||
|
analyzer_history: vector of string &log;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
event unknown_protocol(analyzer_name: string, protocol: count, first_bytes: string)
|
event unknown_protocol(analyzer_name: string, protocol: count, first_bytes: string,
|
||||||
|
analyzer_history: string_vec)
|
||||||
{
|
{
|
||||||
local info : Info;
|
local info : Info;
|
||||||
info$ts = network_time();
|
info$ts = network_time();
|
||||||
info$analyzer = analyzer_name;
|
info$analyzer = analyzer_name;
|
||||||
info$protocol_id = fmt("0x%x", protocol);
|
info$protocol_id = fmt("0x%x", protocol);
|
||||||
info$first_bytes = bytestring_to_hexstr(first_bytes);
|
info$first_bytes = bytestring_to_hexstr(first_bytes);
|
||||||
|
info$analyzer_history = analyzer_history;
|
||||||
|
|
||||||
Log::write(LOG, info);
|
Log::write(LOG, info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -885,8 +885,12 @@ event Pcap::file_done%(path: string%);
|
||||||
##
|
##
|
||||||
## first_bytes: A certain number of bytes at the start of the unknown protocol's header.
|
## first_bytes: A certain number of bytes at the start of the unknown protocol's header.
|
||||||
##
|
##
|
||||||
|
## analyzer_history: The chain of packet analyzers that processed the packet up to this
|
||||||
|
## point. This includes the history of encapsulating packets in case
|
||||||
|
## of tunneling.
|
||||||
|
##
|
||||||
## .. zeek:see:: UnknownProtocol::first_bytes_count
|
## .. zeek:see:: UnknownProtocol::first_bytes_count
|
||||||
event unknown_protocol%(analyzer_name: string, protocol: count, first_bytes: string%);
|
event unknown_protocol%(analyzer_name: string, protocol: count, first_bytes: string, analyzer_history: string_vec%);
|
||||||
|
|
||||||
## An event for handling packets that reached the end of processing without
|
## An event for handling packets that reached the end of processing without
|
||||||
## being marked as processed. Note that this event may lead to unpredictable
|
## being marked as processed. Note that this event may lead to unpredictable
|
||||||
|
|
|
@ -114,6 +114,7 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet, ui
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.", GetAnalyzerName(),
|
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.", GetAnalyzerName(),
|
||||||
identifier);
|
identifier);
|
||||||
|
|
||||||
|
packet_mgr->TrackAnalyzer(inner_analyzer);
|
||||||
return inner_analyzer->AnalyzePacket(len, data, packet);
|
return inner_analyzer->AnalyzePacket(len, data, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet) co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packet_mgr->TrackAnalyzer(inner_analyzer);
|
||||||
return inner_analyzer->AnalyzePacket(len, data, packet);
|
return inner_analyzer->AnalyzePacket(len, data, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ void Manager::ProcessPacket(Packet* packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start packet analysis
|
// Start packet analysis
|
||||||
|
analyzer_stack.clear();
|
||||||
root_analyzer->ForwardPacket(packet->cap_len, packet->data, packet, packet->link_type);
|
root_analyzer->ForwardPacket(packet->cap_len, packet->data, packet, packet->link_type);
|
||||||
|
|
||||||
if ( ! packet->processed ) {
|
if ( ! packet->processed ) {
|
||||||
|
@ -227,13 +228,24 @@ bool Manager::PermitUnknownProtocol(const std::string& analyzer, uint32_t protoc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zeek::VectorValPtr Manager::BuildAnalyzerHistory() const {
|
||||||
|
auto history = zeek::make_intrusive<zeek::VectorVal>(zeek::id::string_vec);
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < analyzer_stack.size(); i++ ) {
|
||||||
|
auto analyzer_name = analyzer_stack[i]->GetAnalyzerName();
|
||||||
|
history->Assign(i, make_intrusive<StringVal>(analyzer_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::ReportUnknownProtocol(const std::string& analyzer, uint32_t protocol, const uint8_t* data, size_t len) {
|
void Manager::ReportUnknownProtocol(const std::string& analyzer, uint32_t protocol, const uint8_t* data, size_t len) {
|
||||||
if ( unknown_protocol ) {
|
if ( unknown_protocol ) {
|
||||||
if ( PermitUnknownProtocol(analyzer, protocol) ) {
|
if ( PermitUnknownProtocol(analyzer, protocol) ) {
|
||||||
int bytes_len = std::min(unknown_first_bytes_count, static_cast<uint64_t>(len));
|
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),
|
event_mgr.Enqueue(unknown_protocol, make_intrusive<StringVal>(analyzer), val_mgr->Count(protocol),
|
||||||
make_intrusive<StringVal>(bytes_len, (const char*)data));
|
make_intrusive<StringVal>(bytes_len, (const char*)data), BuildAnalyzerHistory());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,13 @@ public:
|
||||||
*/
|
*/
|
||||||
uint64_t GetUnprocessedCount() const { return total_not_processed; }
|
uint64_t GetUnprocessedCount() const { return total_not_processed; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks the given analyzer for the current packet's analyzer history.
|
||||||
|
* The packet analyzer history is implemented in form of a stack, which is reset on a
|
||||||
|
* call to ProcessPacket() but maintained throughout calls to ProcessInnerPacket().
|
||||||
|
*/
|
||||||
|
void TrackAnalyzer(AnalyzerPtr analyzer) { analyzer_stack.push_back(std::move(analyzer)); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Instantiates a new analyzer instance.
|
* Instantiates a new analyzer instance.
|
||||||
|
@ -197,6 +204,14 @@ private:
|
||||||
*/
|
*/
|
||||||
AnalyzerPtr InstantiateAnalyzer(const std::string& name);
|
AnalyzerPtr InstantiateAnalyzer(const std::string& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a string vector that represents the analyzer history of the
|
||||||
|
* current packet based on the analyzers' tags.
|
||||||
|
*
|
||||||
|
* @return A vector of strings representing the packet analyzer history.
|
||||||
|
*/
|
||||||
|
VectorValPtr BuildAnalyzerHistory() const;
|
||||||
|
|
||||||
bool PermitUnknownProtocol(const std::string& analyzer, uint32_t protocol);
|
bool PermitUnknownProtocol(const std::string& analyzer, uint32_t protocol);
|
||||||
|
|
||||||
std::map<std::string, AnalyzerPtr> analyzers;
|
std::map<std::string, AnalyzerPtr> analyzers;
|
||||||
|
@ -216,6 +231,8 @@ private:
|
||||||
|
|
||||||
uint64_t total_not_processed = 0;
|
uint64_t total_not_processed = 0;
|
||||||
iosource::PktDumper* unprocessed_dumper = nullptr;
|
iosource::PktDumper* unprocessed_dumper = nullptr;
|
||||||
|
|
||||||
|
std::vector<AnalyzerPtr> analyzer_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace packet_analysis
|
} // namespace packet_analysis
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue