mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Merge remote-tracking branch 'origin/topic/timw/1114-analyzers'
* origin/topic/timw/1114-analyzers: Add type field to session::Key to help avoid collisions in map Move bad UDP checksum handling into adapter object Rename IPBasedTransportAnalyzer to SessionAdapter Move building session analyzer tree out of analyzer::Manager Rework the packet flow through the IP-based analyzers Add new UDP packet analyzer, remove old one Add new ICMP packet analyzer, remove old one Add base class for IP-based packet analyzers Move SessionManager::ParseIPPacket to IP analyzer's namespace Added skeletons for TCP/UDP/ICMP packet analysis plugins.
This commit is contained in:
commit
aa09e02117
78 changed files with 1939 additions and 1403 deletions
28
CHANGES
28
CHANGES
|
@ -1,4 +1,32 @@
|
||||||
|
|
||||||
|
4.1.0-dev.660 | 2021-05-24 12:38:44 -0700
|
||||||
|
|
||||||
|
* Add type field to session::Key to help avoid collisions in map (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move bad UDP checksum handling into adapter object (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Rename IPBasedTransportAnalyzer to SessionAdapter (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
This also also combines the old TransportLayerAnalyzer class into
|
||||||
|
SessionAdapter, and removes the old class. This requires naming changes
|
||||||
|
in a few places but no functionality changes.
|
||||||
|
|
||||||
|
* Move building session analyzer tree out of analyzer::Manager (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Rework the packet flow through the IP-based analyzers (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add new UDP packet analyzer, remove old one (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add new ICMP packet analyzer, remove old one (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add base class for IP-based packet analyzers (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move SessionManager::ParseIPPacket to IP analyzer's namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Added skeletons for TCP/UDP/ICMP packet analysis plugins. (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
This includes integration into the IP plugin and calling of the sessions code from each plugin.
|
||||||
|
|
||||||
4.1.0-dev.646 | 2021-05-18 11:47:25 -0700
|
4.1.0-dev.646 | 2021-05-18 11:47:25 -0700
|
||||||
|
|
||||||
* Omit unneeded decimal points in modp_dtoa2() scientific notation output (Jon Siwek, Corelight)
|
* Omit unneeded decimal points in modp_dtoa2() scientific notation output (Jon Siwek, Corelight)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
4.1.0-dev.646
|
4.1.0-dev.660
|
||||||
|
|
|
@ -15,3 +15,6 @@
|
||||||
@load base/packet-protocols/gre
|
@load base/packet-protocols/gre
|
||||||
@load base/packet-protocols/iptunnel
|
@load base/packet-protocols/iptunnel
|
||||||
@load base/packet-protocols/vntag
|
@load base/packet-protocols/vntag
|
||||||
|
@load base/packet-protocols/udp
|
||||||
|
@load base/packet-protocols/tcp
|
||||||
|
@load base/packet-protocols/icmp
|
||||||
|
|
1
scripts/base/packet-protocols/icmp/__load__.zeek
Normal file
1
scripts/base/packet-protocols/icmp/__load__.zeek
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@load ./main
|
5
scripts/base/packet-protocols/icmp/main.zeek
Normal file
5
scripts/base/packet-protocols/icmp/main.zeek
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module PacketAnalyzer::ICMP;
|
||||||
|
|
||||||
|
#event zeek_init() &priority=20
|
||||||
|
# {
|
||||||
|
# }
|
|
@ -1,8 +1,22 @@
|
||||||
module PacketAnalyzer::IP;
|
module PacketAnalyzer::IP;
|
||||||
|
|
||||||
|
const IPPROTO_TCP : count = 6;
|
||||||
|
const IPPROTO_UDP : count = 17;
|
||||||
|
const IPPROTO_ICMP : count = 1;
|
||||||
|
const IPPROTO_ICMP6 : count = 58;
|
||||||
|
|
||||||
|
const IPPROTO_IPIP : count = 4;
|
||||||
|
const IPPROTO_IPV6 : count = 41;
|
||||||
|
const IPPROTO_GRE : count = 47;
|
||||||
|
|
||||||
event zeek_init() &priority=20
|
event zeek_init() &priority=20
|
||||||
{
|
{
|
||||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL);
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_IPIP, PacketAnalyzer::ANALYZER_IPTUNNEL);
|
||||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL);
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_IPV6, PacketAnalyzer::ANALYZER_IPTUNNEL);
|
||||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE);
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_GRE, PacketAnalyzer::ANALYZER_GRE);
|
||||||
|
|
||||||
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_TCP, PacketAnalyzer::ANALYZER_TCP);
|
||||||
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_UDP, PacketAnalyzer::ANALYZER_UDP);
|
||||||
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_ICMP, PacketAnalyzer::ANALYZER_ICMP);
|
||||||
|
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_ICMP6, PacketAnalyzer::ANALYZER_ICMP);
|
||||||
}
|
}
|
||||||
|
|
1
scripts/base/packet-protocols/tcp/__load__.zeek
Normal file
1
scripts/base/packet-protocols/tcp/__load__.zeek
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@load ./main
|
5
scripts/base/packet-protocols/tcp/main.zeek
Normal file
5
scripts/base/packet-protocols/tcp/main.zeek
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module PacketAnalyzer::TCP;
|
||||||
|
|
||||||
|
#event zeek_init() &priority=20
|
||||||
|
# {
|
||||||
|
# }
|
1
scripts/base/packet-protocols/udp/__load__.zeek
Normal file
1
scripts/base/packet-protocols/udp/__load__.zeek
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@load ./main
|
5
scripts/base/packet-protocols/udp/main.zeek
Normal file
5
scripts/base/packet-protocols/udp/main.zeek
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module PacketAnalyzer::UDP;
|
||||||
|
|
||||||
|
#event zeek_init() &priority=20
|
||||||
|
# {
|
||||||
|
# }
|
37
src/Conn.cc
37
src/Conn.cc
|
@ -19,6 +19,7 @@
|
||||||
#include "zeek/analyzer/Analyzer.h"
|
#include "zeek/analyzer/Analyzer.h"
|
||||||
#include "zeek/analyzer/Manager.h"
|
#include "zeek/analyzer/Manager.h"
|
||||||
#include "zeek/iosource/IOSource.h"
|
#include "zeek/iosource/IOSource.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
|
||||||
|
|
||||||
namespace zeek {
|
namespace zeek {
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ Connection::Connection(const detail::ConnKey& k, double t,
|
||||||
hist_seen = 0;
|
hist_seen = 0;
|
||||||
history = "";
|
history = "";
|
||||||
|
|
||||||
root_analyzer = nullptr;
|
adapter = nullptr;
|
||||||
primary_PIA = nullptr;
|
primary_PIA = nullptr;
|
||||||
|
|
||||||
++current_connections;
|
++current_connections;
|
||||||
|
@ -83,7 +84,7 @@ Connection::~Connection()
|
||||||
if ( conn_val )
|
if ( conn_val )
|
||||||
conn_val->SetOrigin(nullptr);
|
conn_val->SetOrigin(nullptr);
|
||||||
|
|
||||||
delete root_analyzer;
|
delete adapter;
|
||||||
|
|
||||||
--current_connections;
|
--current_connections;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ void Connection::Done()
|
||||||
// somewhere, but it's session-related, so maybe not?
|
// somewhere, but it's session-related, so maybe not?
|
||||||
if ( ConnTransport() == TRANSPORT_TCP )
|
if ( ConnTransport() == TRANSPORT_TCP )
|
||||||
{
|
{
|
||||||
auto ta = static_cast<analyzer::tcp::TCP_Analyzer*>(GetRootAnalyzer());
|
auto ta = static_cast<analyzer::tcp::TCP_Analyzer*>(adapter);
|
||||||
assert(ta->IsAnalyzer("TCP"));
|
assert(ta->IsAnalyzer("TCP"));
|
||||||
analyzer::tcp::TCP_Endpoint* to = ta->Orig();
|
analyzer::tcp::TCP_Endpoint* to = ta->Orig();
|
||||||
analyzer::tcp::TCP_Endpoint* tr = ta->Resp();
|
analyzer::tcp::TCP_Endpoint* tr = ta->Resp();
|
||||||
|
@ -139,8 +140,8 @@ void Connection::Done()
|
||||||
|
|
||||||
finished = 1;
|
finished = 1;
|
||||||
|
|
||||||
if ( root_analyzer && ! root_analyzer->IsFinished() )
|
if ( adapter && ! adapter->IsFinished() )
|
||||||
root_analyzer->Done();
|
adapter->Done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::NextPacket(double t, bool is_orig,
|
void Connection::NextPacket(double t, bool is_orig,
|
||||||
|
@ -156,11 +157,11 @@ void Connection::NextPacket(double t, bool is_orig,
|
||||||
if ( Skipping() )
|
if ( Skipping() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( root_analyzer )
|
if ( adapter )
|
||||||
{
|
{
|
||||||
record_current_packet = record_packet;
|
record_current_packet = record_packet;
|
||||||
record_current_content = record_content;
|
record_current_content = record_content;
|
||||||
root_analyzer->NextPacket(len, data, is_orig, -1, ip, caplen);
|
adapter->NextPacket(len, data, is_orig, -1, ip, caplen);
|
||||||
record_packet = record_current_packet;
|
record_packet = record_current_packet;
|
||||||
record_content = record_current_content;
|
record_content = record_current_content;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +174,7 @@ void Connection::NextPacket(double t, bool is_orig,
|
||||||
|
|
||||||
bool Connection::IsReuse(double t, const u_char* pkt)
|
bool Connection::IsReuse(double t, const u_char* pkt)
|
||||||
{
|
{
|
||||||
return root_analyzer && root_analyzer->IsReuse(t, pkt);
|
return adapter && adapter->IsReuse(t, pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Connection::ScaledHistoryEntry(char code, uint32_t& counter,
|
bool Connection::ScaledHistoryEntry(char code, uint32_t& counter,
|
||||||
|
@ -275,8 +276,8 @@ const RecordValPtr& Connection::GetVal()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( root_analyzer )
|
if ( adapter )
|
||||||
root_analyzer->UpdateConnVal(conn_val.get());
|
adapter->UpdateConnVal(conn_val.get());
|
||||||
|
|
||||||
conn_val->AssignTime(3, start_time); // ###
|
conn_val->AssignTime(3, start_time); // ###
|
||||||
conn_val->AssignInterval(4, last_time - start_time);
|
conn_val->AssignInterval(4, last_time - start_time);
|
||||||
|
@ -289,17 +290,17 @@ const RecordValPtr& Connection::GetVal()
|
||||||
|
|
||||||
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id)
|
analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id)
|
||||||
{
|
{
|
||||||
return root_analyzer ? root_analyzer->FindChild(id) : nullptr;
|
return adapter ? adapter->FindChild(id) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
analyzer::Analyzer* Connection::FindAnalyzer(const analyzer::Tag& tag)
|
analyzer::Analyzer* Connection::FindAnalyzer(const analyzer::Tag& tag)
|
||||||
{
|
{
|
||||||
return root_analyzer ? root_analyzer->FindChild(tag) : nullptr;
|
return adapter ? adapter->FindChild(tag) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
analyzer::Analyzer* Connection::FindAnalyzer(const char* name)
|
analyzer::Analyzer* Connection::FindAnalyzer(const char* name)
|
||||||
{
|
{
|
||||||
return root_analyzer->FindChild(name);
|
return adapter->FindChild(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::AppendAddl(const char* str)
|
void Connection::AppendAddl(const char* str)
|
||||||
|
@ -370,8 +371,8 @@ void Connection::FlipRoles()
|
||||||
|
|
||||||
conn_val = nullptr;
|
conn_val = nullptr;
|
||||||
|
|
||||||
if ( root_analyzer )
|
if ( adapter )
|
||||||
root_analyzer->FlipRoles();
|
adapter->FlipRoles();
|
||||||
|
|
||||||
analyzer_mgr->ApplyScheduledAnalyzers(this);
|
analyzer_mgr->ApplyScheduledAnalyzers(this);
|
||||||
|
|
||||||
|
@ -383,7 +384,7 @@ unsigned int Connection::MemoryAllocation() const
|
||||||
return session::Session::MemoryAllocation() + padded_sizeof(*this)
|
return session::Session::MemoryAllocation() + padded_sizeof(*this)
|
||||||
+ (timers.MemoryAllocation() - padded_sizeof(timers))
|
+ (timers.MemoryAllocation() - padded_sizeof(timers))
|
||||||
+ (conn_val ? conn_val->MemoryAllocation() : 0)
|
+ (conn_val ? conn_val->MemoryAllocation() : 0)
|
||||||
+ (root_analyzer ? root_analyzer->MemoryAllocation(): 0)
|
+ (adapter ? adapter->MemoryAllocation(): 0)
|
||||||
// primary_PIA is already contained in the analyzer tree.
|
// primary_PIA is already contained in the analyzer tree.
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -448,10 +449,10 @@ void Connection::IDString(ODesc* d) const
|
||||||
d->Add(ntohs(resp_port));
|
d->Add(ntohs(resp_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer,
|
void Connection::SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa,
|
||||||
analyzer::pia::PIA* pia)
|
analyzer::pia::PIA* pia)
|
||||||
{
|
{
|
||||||
root_analyzer = analyzer;
|
adapter = aa;
|
||||||
primary_PIA = pia;
|
primary_PIA = pia;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
src/Conn.h
19
src/Conn.h
|
@ -41,12 +41,8 @@ class RuleHdrTest;
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
namespace analyzer {
|
namespace analyzer { class Analyzer; }
|
||||||
|
namespace packet_analysis::IP { class SessionAdapter; }
|
||||||
class TransportLayerAnalyzer;
|
|
||||||
class Analyzer;
|
|
||||||
|
|
||||||
} // namespace analyzer
|
|
||||||
|
|
||||||
enum ConnEventToFlag {
|
enum ConnEventToFlag {
|
||||||
NUL_IN_LINE,
|
NUL_IN_LINE,
|
||||||
|
@ -117,7 +113,10 @@ public:
|
||||||
// should be marked invalid.
|
// should be marked invalid.
|
||||||
const detail::ConnKey& Key() const { return key; }
|
const detail::ConnKey& Key() const { return key; }
|
||||||
session::detail::Key SessionKey(bool copy) const override
|
session::detail::Key SessionKey(bool copy) const override
|
||||||
{ return session::detail::Key{&key, sizeof(key), copy}; }
|
{
|
||||||
|
return session::detail::Key{
|
||||||
|
&key, sizeof(key), session::detail::Key::CONNECTION_KEY_TYPE, copy};
|
||||||
|
}
|
||||||
|
|
||||||
const IPAddr& OrigAddr() const { return orig_addr; }
|
const IPAddr& OrigAddr() const { return orig_addr; }
|
||||||
const IPAddr& RespAddr() const { return resp_addr; }
|
const IPAddr& RespAddr() const { return resp_addr; }
|
||||||
|
@ -231,8 +230,8 @@ public:
|
||||||
void AddHistory(char code) { history += code; }
|
void AddHistory(char code) { history += code; }
|
||||||
|
|
||||||
// Sets the root of the analyzer tree as well as the primary PIA.
|
// Sets the root of the analyzer tree as well as the primary PIA.
|
||||||
void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia);
|
void SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, analyzer::pia::PIA* pia);
|
||||||
analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
|
packet_analysis::IP::SessionAdapter* GetSessionAdapter() { return adapter; }
|
||||||
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
|
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
|
||||||
|
|
||||||
// Sets the transport protocol in use.
|
// Sets the transport protocol in use.
|
||||||
|
@ -279,7 +278,7 @@ private:
|
||||||
uint32_t hist_seen;
|
uint32_t hist_seen;
|
||||||
std::string history;
|
std::string history;
|
||||||
|
|
||||||
analyzer::TransportLayerAnalyzer* root_analyzer;
|
packet_analysis::IP::SessionAdapter* adapter;
|
||||||
analyzer::pia::PIA* primary_PIA;
|
analyzer::pia::PIA* primary_PIA;
|
||||||
|
|
||||||
UID uid; // Globally unique connection ID.
|
UID uid; // Globally unique connection ID.
|
||||||
|
|
|
@ -177,6 +177,7 @@ public:
|
||||||
bool operator!=( const DictIterator& that ) const { return !(*this == that); }
|
bool operator!=( const DictIterator& that ) const { return !(*this == that); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class Dictionary;
|
friend class Dictionary;
|
||||||
|
|
||||||
DictIterator(const Dictionary* d, detail::DictEntry* begin, detail::DictEntry* end);
|
DictIterator(const Dictionary* d, detail::DictEntry* begin, detail::DictEntry* end);
|
||||||
|
|
|
@ -25,12 +25,12 @@ namespace zeek::detail {
|
||||||
bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
{
|
{
|
||||||
analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
auto* adapter = state->GetAnalyzer()->Conn()->GetSessionAdapter();
|
||||||
|
|
||||||
if ( ! root || ! root->IsAnalyzer("TCP") )
|
if ( ! adapter || ! adapter->IsAnalyzer("TCP") )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(root);
|
auto* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(adapter);
|
||||||
|
|
||||||
if ( tcpstates & RULE_STATE_STATELESS )
|
if ( tcpstates & RULE_STATE_STATELESS )
|
||||||
return true;
|
return true;
|
||||||
|
@ -57,9 +57,9 @@ void RuleConditionTCPState::PrintDebug()
|
||||||
bool RuleConditionUDPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
bool RuleConditionUDPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||||
const u_char* data, int len)
|
const u_char* data, int len)
|
||||||
{
|
{
|
||||||
analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
auto* adapter = state->GetAnalyzer()->Conn()->GetSessionAdapter();
|
||||||
|
|
||||||
if ( ! root || ! root->IsAnalyzer("UDP") )
|
if ( ! adapter || ! adapter->IsAnalyzer("UDP") )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( states & RULE_STATE_STATELESS )
|
if ( states & RULE_STATE_STATELESS )
|
||||||
|
|
|
@ -880,31 +880,4 @@ void SupportAnalyzer::ForwardUndelivered(uint64_t seq, int len, bool is_orig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TransportLayerAnalyzer::Done()
|
|
||||||
{
|
|
||||||
Analyzer::Done();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransportLayerAnalyzer::SetContentsFile(unsigned int /* direction */,
|
|
||||||
FilePtr /* f */)
|
|
||||||
{
|
|
||||||
reporter->Error("analyzer type does not support writing to a contents file");
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePtr TransportLayerAnalyzer::GetContentsFile(unsigned int /* direction */) const
|
|
||||||
{
|
|
||||||
reporter->Error("analyzer type does not support writing to a contents file");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransportLayerAnalyzer::PacketContents(const u_char* data, int len)
|
|
||||||
{
|
|
||||||
if ( packet_contents && len > 0 )
|
|
||||||
{
|
|
||||||
String* cbs = new String(data, len, true);
|
|
||||||
auto contents = make_intrusive<StringVal>(cbs);
|
|
||||||
EnqueueConnEvent(packet_contents, ConnVal(), std::move(contents));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace zeek::analyzer
|
} // namespace zeek::analyzer
|
||||||
|
|
|
@ -25,6 +25,7 @@ using FilePtr = zeek::IntrusivePtr<File>;
|
||||||
using RecordValPtr = zeek::IntrusivePtr<RecordVal>;
|
using RecordValPtr = zeek::IntrusivePtr<RecordVal>;
|
||||||
|
|
||||||
namespace detail { class Rule; }
|
namespace detail { class Rule; }
|
||||||
|
namespace packet_analysis::IP { class IPBasedAnalyzer; }
|
||||||
|
|
||||||
} // namespace zeek
|
} // namespace zeek
|
||||||
|
|
||||||
|
@ -601,6 +602,7 @@ protected:
|
||||||
friend class Manager;
|
friend class Manager;
|
||||||
friend class zeek::Connection;
|
friend class zeek::Connection;
|
||||||
friend class zeek::analyzer::tcp::TCP_ApplicationAnalyzer;
|
friend class zeek::analyzer::tcp::TCP_ApplicationAnalyzer;
|
||||||
|
friend class zeek::packet_analysis::IP::IPBasedAnalyzer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a string represantation of an analyzer, containing its name
|
* Return a string represantation of an analyzer, containing its name
|
||||||
|
@ -844,83 +846,4 @@ private:
|
||||||
#define CONTENTS_RESP 2
|
#define CONTENTS_RESP 2
|
||||||
#define CONTENTS_BOTH 3
|
#define CONTENTS_BOTH 3
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for analyzers parsing transport-layer protocols.
|
|
||||||
*/
|
|
||||||
class TransportLayerAnalyzer : public Analyzer {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param name A name for the protocol the analyzer is parsing. The
|
|
||||||
* name must match the one the corresponding Component registers.
|
|
||||||
*
|
|
||||||
* @param conn The connection the analyzer is associated with.
|
|
||||||
*/
|
|
||||||
TransportLayerAnalyzer(const char* name, Connection* conn)
|
|
||||||
: Analyzer(name, conn) { pia = nullptr; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overridden from parent class.
|
|
||||||
*/
|
|
||||||
void Done() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the analyzer determines that in fact a new
|
|
||||||
* connection has started without the connection statement having
|
|
||||||
* terminated the previous one, i.e., the new data is arriving at
|
|
||||||
* what's the analyzer for the previous instance. This is used only
|
|
||||||
* for TCP.
|
|
||||||
*/
|
|
||||||
virtual bool IsReuse(double t, const u_char* pkt) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates a file with the analyzer in which to record all
|
|
||||||
* analyzed input. This must only be called with derived classes that
|
|
||||||
* overide the method; the default implementation will abort.
|
|
||||||
*
|
|
||||||
* @param direction One of the CONTENTS_* constants indicating which
|
|
||||||
* direction of the input stream is to be recorded.
|
|
||||||
*
|
|
||||||
* @param f The file to record to.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
virtual void SetContentsFile(unsigned int direction, FilePtr f);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an associated contents file, if any. This must only be
|
|
||||||
* called with derived classes that overide the method; the default
|
|
||||||
* implementation will abort.
|
|
||||||
*
|
|
||||||
* @param direction One of the CONTENTS_* constants indicating which
|
|
||||||
* direction the query is for.
|
|
||||||
*/
|
|
||||||
virtual FilePtr GetContentsFile(unsigned int direction) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates a PIA with this analyzer. A PIA takes the
|
|
||||||
* transport-layer input and determine which protocol analyzer(s) to
|
|
||||||
* use for parsing it.
|
|
||||||
*/
|
|
||||||
void SetPIA(analyzer::pia::PIA* arg_PIA) { pia = arg_PIA; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the associated PIA, or null of none. Does not take
|
|
||||||
* ownership.
|
|
||||||
*/
|
|
||||||
analyzer::pia::PIA* GetPIA() const { return pia; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to raise a \c packet_contents event.
|
|
||||||
*
|
|
||||||
* @param data The dass to pass to the event.
|
|
||||||
*
|
|
||||||
* @param len The length of \a data.
|
|
||||||
*/
|
|
||||||
void PacketContents(const u_char* data, int len);
|
|
||||||
|
|
||||||
private:
|
|
||||||
analyzer::pia::PIA* pia;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace zeek::analyzer
|
} // namespace zeek::analyzer
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
#include "zeek/RunState.h"
|
#include "zeek/RunState.h"
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
|
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
|
||||||
#include "zeek/analyzer/protocol/icmp/ICMP.h"
|
|
||||||
#include "zeek/analyzer/protocol/pia/PIA.h"
|
#include "zeek/analyzer/protocol/pia/PIA.h"
|
||||||
#include "zeek/analyzer/protocol/stepping-stone/SteppingStone.h"
|
#include "zeek/analyzer/protocol/stepping-stone/SteppingStone.h"
|
||||||
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
|
||||||
|
|
||||||
#include "zeek/plugin/Manager.h"
|
#include "zeek/plugin/Manager.h"
|
||||||
|
|
||||||
|
@ -354,15 +354,10 @@ Manager::tag_set* Manager::LookupPort(TransportProto proto, uint32_t port, bool
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::tag_set* Manager::LookupPort(PortVal* val, bool add_if_not_found)
|
|
||||||
{
|
|
||||||
return LookupPort(val->PortType(), val->Port(), add_if_not_found);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::BuildInitialAnalyzerTree(Connection* conn)
|
bool Manager::BuildInitialAnalyzerTree(Connection* conn)
|
||||||
{
|
{
|
||||||
analyzer::tcp::TCP_Analyzer* tcp = nullptr;
|
analyzer::tcp::TCP_Analyzer* tcp = nullptr;
|
||||||
TransportLayerAnalyzer* root = nullptr;
|
packet_analysis::IP::SessionAdapter* root = nullptr;
|
||||||
analyzer::pia::PIA* pia = nullptr;
|
analyzer::pia::PIA* pia = nullptr;
|
||||||
bool check_port = false;
|
bool check_port = false;
|
||||||
|
|
||||||
|
@ -375,19 +370,6 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
|
||||||
DBG_ANALYZER(conn, "activated TCP analyzer");
|
DBG_ANALYZER(conn, "activated TCP analyzer");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRANSPORT_UDP:
|
|
||||||
root = new analyzer::udp::UDP_Analyzer(conn);
|
|
||||||
pia = new analyzer::pia::PIA_UDP(conn);
|
|
||||||
check_port = true;
|
|
||||||
DBG_ANALYZER(conn, "activated UDP analyzer");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TRANSPORT_ICMP: {
|
|
||||||
root = new analyzer::icmp::ICMP_Analyzer(conn);
|
|
||||||
DBG_ANALYZER(conn, "activated ICMP analyzer");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
reporter->InternalWarning("unknown protocol can't build analyzer tree");
|
reporter->InternalWarning("unknown protocol can't build analyzer tree");
|
||||||
return false;
|
return false;
|
||||||
|
@ -489,7 +471,7 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
|
||||||
if ( pia )
|
if ( pia )
|
||||||
root->AddChildAnalyzer(pia->AsAnalyzer());
|
root->AddChildAnalyzer(pia->AsAnalyzer());
|
||||||
|
|
||||||
conn->SetRootAnalyzer(root, pia);
|
conn->SetSessionAdapter(root, pia);
|
||||||
root->Init();
|
root->Init();
|
||||||
root->InitChildren();
|
root->InitChildren();
|
||||||
|
|
||||||
|
@ -607,10 +589,11 @@ Manager::tag_set Manager::GetScheduled(const Connection* conn)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::ApplyScheduledAnalyzers(Connection* conn, bool init, TransportLayerAnalyzer* parent)
|
bool Manager::ApplyScheduledAnalyzers(Connection* conn, bool init,
|
||||||
|
packet_analysis::IP::SessionAdapter* parent)
|
||||||
{
|
{
|
||||||
if ( ! parent )
|
if ( ! parent )
|
||||||
parent = conn->GetRootAnalyzer();
|
parent = conn->GetSessionAdapter();
|
||||||
|
|
||||||
if ( ! parent )
|
if ( ! parent )
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,6 +35,14 @@
|
||||||
#include "zeek/analyzer/analyzer.bif.h"
|
#include "zeek/analyzer/analyzer.bif.h"
|
||||||
|
|
||||||
namespace zeek {
|
namespace zeek {
|
||||||
|
|
||||||
|
namespace packet_analysis::IP {
|
||||||
|
|
||||||
|
class IPBasedAnalyzer;
|
||||||
|
class SessionAdapter;
|
||||||
|
|
||||||
|
} // namespace packet_analysis::IP
|
||||||
|
|
||||||
namespace analyzer {
|
namespace analyzer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -244,8 +252,8 @@ public:
|
||||||
*
|
*
|
||||||
* @param conn The connection to add the initial set of analyzers to.
|
* @param conn The connection to add the initial set of analyzers to.
|
||||||
*
|
*
|
||||||
* @return False if the tree cannot be build; that's usually an
|
* @return False if the tree cannot be built; that's usually an
|
||||||
* internally error.
|
* internal error.
|
||||||
*/
|
*/
|
||||||
bool BuildInitialAnalyzerTree(Connection* conn);
|
bool BuildInitialAnalyzerTree(Connection* conn);
|
||||||
|
|
||||||
|
@ -313,7 +321,7 @@ public:
|
||||||
* @return True if at least one scheduled analyzer was found.
|
* @return True if at least one scheduled analyzer was found.
|
||||||
*/
|
*/
|
||||||
bool ApplyScheduledAnalyzers(Connection* conn, bool init_and_event = true,
|
bool ApplyScheduledAnalyzers(Connection* conn, bool init_and_event = true,
|
||||||
TransportLayerAnalyzer* parent = nullptr);
|
packet_analysis::IP::SessionAdapter* parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a particular analyzer for an upcoming connection. Once
|
* Schedules a particular analyzer for an upcoming connection. Once
|
||||||
|
@ -345,10 +353,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
friend class packet_analysis::IP::IPBasedAnalyzer;
|
||||||
|
|
||||||
using tag_set = std::set<Tag>;
|
using tag_set = std::set<Tag>;
|
||||||
using analyzer_map_by_port = std::map<uint32_t, tag_set*>;
|
using analyzer_map_by_port = std::map<uint32_t, tag_set*>;
|
||||||
|
|
||||||
tag_set* LookupPort(PortVal* val, bool add_if_not_found);
|
|
||||||
tag_set* LookupPort(TransportProto proto, uint32_t port, bool add_if_not_found);
|
tag_set* LookupPort(TransportProto proto, uint32_t port, bool add_if_not_found);
|
||||||
|
|
||||||
tag_set GetScheduled(const Connection* conn);
|
tag_set GetScheduled(const Connection* conn);
|
||||||
|
|
|
@ -14,7 +14,6 @@ add_subdirectory(gnutella)
|
||||||
add_subdirectory(gssapi)
|
add_subdirectory(gssapi)
|
||||||
add_subdirectory(gtpv1)
|
add_subdirectory(gtpv1)
|
||||||
add_subdirectory(http)
|
add_subdirectory(http)
|
||||||
add_subdirectory(icmp)
|
|
||||||
add_subdirectory(ident)
|
add_subdirectory(ident)
|
||||||
add_subdirectory(imap)
|
add_subdirectory(imap)
|
||||||
add_subdirectory(irc)
|
add_subdirectory(irc)
|
||||||
|
@ -45,7 +44,6 @@ add_subdirectory(stepping-stone)
|
||||||
add_subdirectory(syslog)
|
add_subdirectory(syslog)
|
||||||
add_subdirectory(tcp)
|
add_subdirectory(tcp)
|
||||||
add_subdirectory(teredo)
|
add_subdirectory(teredo)
|
||||||
add_subdirectory(udp)
|
|
||||||
add_subdirectory(vxlan)
|
add_subdirectory(vxlan)
|
||||||
add_subdirectory(xmpp)
|
add_subdirectory(xmpp)
|
||||||
add_subdirectory(zip)
|
add_subdirectory(zip)
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/ayiya/AYIYA.h"
|
#include "zeek/analyzer/protocol/ayiya/AYIYA.h"
|
||||||
|
|
||||||
#include "zeek/session/Manager.h"
|
|
||||||
#include "zeek/Func.h"
|
#include "zeek/Func.h"
|
||||||
#include "zeek/packet_analysis/protocol/iptunnel/IPTunnel.h"
|
#include "zeek/packet_analysis/protocol/iptunnel/IPTunnel.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IP.h"
|
||||||
|
|
||||||
namespace zeek::analyzer::ayiya {
|
namespace zeek::analyzer::ayiya {
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint6
|
||||||
caplen -= inner_packet_offset;
|
caplen -= inner_packet_offset;
|
||||||
inner_packet_offset = -1;
|
inner_packet_offset = -1;
|
||||||
|
|
||||||
IP_Hdr* inner = nullptr;
|
std::unique_ptr<IP_Hdr> inner;
|
||||||
int result = session_mgr->ParseIPPacket(len, data, next_header, inner);
|
int result = packet_analysis::IP::ParsePacket(len, data, next_header, inner);
|
||||||
|
|
||||||
if ( result == 0 )
|
if ( result == 0 )
|
||||||
{
|
{
|
||||||
|
@ -66,9 +66,6 @@ void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint6
|
||||||
else
|
else
|
||||||
ProtocolViolation("AYIYA payload length",
|
ProtocolViolation("AYIYA payload length",
|
||||||
reinterpret_cast<const char*>(data), len);
|
reinterpret_cast<const char*>(data), len);
|
||||||
|
|
||||||
if ( result != 0 )
|
|
||||||
delete inner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace zeek::analyzer::ayiya
|
} // namespace zeek::analyzer::ayiya
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "analyzer/protocol/dhcp/dhcp_pac.h"
|
#include "analyzer/protocol/dhcp/dhcp_pac.h"
|
||||||
|
|
||||||
namespace zeek::analyzer::dhcp {
|
namespace zeek::analyzer::dhcp {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "analyzer/protocol/dnp3/dnp3_pac.h"
|
#include "analyzer/protocol/dnp3/dnp3_pac.h"
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ bool Gnutella_Analyzer::IsHTTP(std::string header)
|
||||||
if ( Parent()->IsAnalyzer("TCP") )
|
if ( Parent()->IsAnalyzer("TCP") )
|
||||||
{
|
{
|
||||||
// Replay buffered data.
|
// Replay buffered data.
|
||||||
analyzer::pia::PIA* pia = static_cast<analyzer::TransportLayerAnalyzer *>(Parent())->GetPIA();
|
analyzer::pia::PIA* pia = static_cast<packet_analysis::IP::SessionAdapter*>(Parent())->GetPIA();
|
||||||
if ( pia )
|
if ( pia )
|
||||||
static_cast<analyzer::pia::PIA_TCP *>(pia)->ReplayStreamBuffer(a);
|
static_cast<analyzer::pia::PIA_TCP *>(pia)->ReplayStreamBuffer(a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/gtpv1/GTPv1.h"
|
#include "zeek/analyzer/protocol/gtpv1/GTPv1.h"
|
||||||
#include "zeek/packet_analysis/protocol/iptunnel/IPTunnel.h"
|
#include "zeek/packet_analysis/protocol/iptunnel/IPTunnel.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IP.h"
|
||||||
|
|
||||||
#include "zeek/session/Manager.h"
|
|
||||||
#include "zeek/analyzer/protocol/gtpv1/events.bif.h"
|
#include "zeek/analyzer/protocol/gtpv1/events.bif.h"
|
||||||
|
|
||||||
namespace zeek::analyzer::gtpv1 {
|
namespace zeek::analyzer::gtpv1 {
|
||||||
|
@ -47,8 +47,8 @@ void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint6
|
||||||
caplen -= inner_packet_offset;
|
caplen -= inner_packet_offset;
|
||||||
inner_packet_offset = -1;
|
inner_packet_offset = -1;
|
||||||
|
|
||||||
IP_Hdr* inner = nullptr;
|
std::unique_ptr<IP_Hdr> inner = nullptr;
|
||||||
int result = session_mgr->ParseIPPacket(len, data, next_header, inner);
|
int result = packet_analysis::IP::ParsePacket(len, data, next_header, inner);
|
||||||
|
|
||||||
if ( result == 0 )
|
if ( result == 0 )
|
||||||
{
|
{
|
||||||
|
@ -77,9 +77,6 @@ void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint6
|
||||||
else
|
else
|
||||||
ProtocolViolation("GTPv1 payload length",
|
ProtocolViolation("GTPv1 payload length",
|
||||||
reinterpret_cast<const char*>(odata), olen);
|
reinterpret_cast<const char*>(odata), olen);
|
||||||
|
|
||||||
if ( result != 0 )
|
|
||||||
delete inner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace zeek::analyzer::gtpv1
|
} // namespace zeek::analyzer::gtpv1
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "zeek/RuleMatcher.h"
|
|
||||||
#include "zeek/analyzer/Analyzer.h"
|
|
||||||
#include "zeek/net_util.h"
|
|
||||||
|
|
||||||
namespace zeek {
|
|
||||||
|
|
||||||
class VectorVal;
|
|
||||||
using VectorValPtr = IntrusivePtr<VectorVal>;
|
|
||||||
|
|
||||||
namespace analyzer::icmp {
|
|
||||||
|
|
||||||
enum ICMP_EndpointState {
|
|
||||||
ICMP_INACTIVE, // no packet seen
|
|
||||||
ICMP_ACTIVE, // packets seen
|
|
||||||
};
|
|
||||||
|
|
||||||
// We do not have an PIA for ICMP (yet) and therefore derive from
|
|
||||||
// RuleMatcherState to perform our own matching.
|
|
||||||
class ICMP_Analyzer final : public analyzer::TransportLayerAnalyzer {
|
|
||||||
public:
|
|
||||||
explicit ICMP_Analyzer(Connection* conn);
|
|
||||||
|
|
||||||
void UpdateConnVal(RecordVal *conn_val) override;
|
|
||||||
|
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
|
||||||
{ return new ICMP_Analyzer(conn); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Done() override;
|
|
||||||
void DeliverPacket(int len, const u_char* data, bool orig,
|
|
||||||
uint64_t seq, const IP_Hdr* ip, int caplen) override;
|
|
||||||
bool IsReuse(double t, const u_char* pkt) override;
|
|
||||||
unsigned int MemoryAllocation() const override;
|
|
||||||
|
|
||||||
void ICMP_Sent(const struct icmp* icmpp, int len, int caplen, int icmpv6,
|
|
||||||
const u_char* data, const IP_Hdr* ip_hdr);
|
|
||||||
|
|
||||||
void Echo(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
void Redirect(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
void RouterAdvert(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
void NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
void NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
void RouterSolicit(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
|
|
||||||
void Describe(ODesc* d) const;
|
|
||||||
|
|
||||||
RecordValPtr BuildInfo(const struct icmp* icmpp, int len,
|
|
||||||
bool icmpv6, const IP_Hdr* ip_hdr);
|
|
||||||
|
|
||||||
void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
|
|
||||||
const u_char*& data, const IP_Hdr* ip_hdr );
|
|
||||||
|
|
||||||
RecordValPtr ExtractICMP4Context(int len, const u_char*& data);
|
|
||||||
|
|
||||||
void Context4(double t, const struct icmp* icmpp, int len, int caplen,
|
|
||||||
const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
|
|
||||||
TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port,
|
|
||||||
uint32_t* dst_port);
|
|
||||||
|
|
||||||
void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
|
|
||||||
const u_char*& data, const IP_Hdr* ip_hdr );
|
|
||||||
|
|
||||||
RecordValPtr ExtractICMP6Context(int len, const u_char*& data);
|
|
||||||
|
|
||||||
void Context6(double t, const struct icmp* icmpp, int len, int caplen,
|
|
||||||
const u_char*& data, const IP_Hdr* ip_hdr);
|
|
||||||
|
|
||||||
// RFC 4861 Neighbor Discover message options
|
|
||||||
VectorValPtr BuildNDOptionsVal(int caplen, const u_char* data);
|
|
||||||
|
|
||||||
RecordValPtr icmp_conn_val;
|
|
||||||
int type;
|
|
||||||
int code;
|
|
||||||
int request_len, reply_len;
|
|
||||||
|
|
||||||
detail::RuleMatcherState matcher_state;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void UpdateEndpointVal(const ValPtr& endp, bool is_orig);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the counterpart type to the given type (e.g., the counterpart
|
|
||||||
// to ICMP_ECHOREPLY is ICMP_ECHO).
|
|
||||||
extern int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
|
||||||
extern int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
|
||||||
|
|
||||||
} // namespace analyzer::icmp
|
|
||||||
} // namespace zeek
|
|
|
@ -1,22 +0,0 @@
|
||||||
// See the file in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#include "zeek/plugin/Plugin.h"
|
|
||||||
#include "zeek/analyzer/Component.h"
|
|
||||||
#include "zeek/analyzer/protocol/icmp/ICMP.h"
|
|
||||||
|
|
||||||
namespace zeek::plugin::detail::Zeek_ICMP {
|
|
||||||
|
|
||||||
class Plugin : public zeek::plugin::Plugin {
|
|
||||||
public:
|
|
||||||
zeek::plugin::Configuration Configure() override
|
|
||||||
{
|
|
||||||
AddComponent(new zeek::analyzer::Component("ICMP", zeek::analyzer::icmp::ICMP_Analyzer::Instantiate));
|
|
||||||
|
|
||||||
zeek::plugin::Configuration config;
|
|
||||||
config.name = "Zeek::ICMP";
|
|
||||||
config.description = "ICMP analyzer";
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
} plugin;
|
|
||||||
|
|
||||||
} // namespace zeek::plugin::detail::Zeek_ICMP
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
||||||
|
|
||||||
namespace zeek::analyzer::netbios_ssn {
|
namespace zeek::analyzer::netbios_ssn {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/ntp/events.bif.h"
|
#include "zeek/analyzer/protocol/ntp/events.bif.h"
|
||||||
#include "zeek/analyzer/protocol/ntp/types.bif.h"
|
#include "zeek/analyzer/protocol/ntp/types.bif.h"
|
||||||
#include "zeek/analyzer/protocol/ntp/ntp_pac.h"
|
#include "zeek/analyzer/protocol/ntp/ntp_pac.h"
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/radius/events.bif.h"
|
#include "zeek/analyzer/protocol/radius/events.bif.h"
|
||||||
#include "zeek/analyzer/protocol/radius/radius_pac.h"
|
#include "zeek/analyzer/protocol/radius/radius_pac.h"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/rdp/events.bif.h"
|
#include "zeek/analyzer/protocol/rdp/events.bif.h"
|
||||||
#include "zeek/analyzer/protocol/rdp/rdpeudp_pac.h"
|
#include "zeek/analyzer/protocol/rdp/rdpeudp_pac.h"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/sip/events.bif.h"
|
#include "zeek/analyzer/protocol/sip/events.bif.h"
|
||||||
#include "zeek/analyzer/protocol/sip/sip_pac.h"
|
#include "zeek/analyzer/protocol/sip/sip_pac.h"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/ssl/events.bif.h"
|
#include "zeek/analyzer/protocol/ssl/events.bif.h"
|
||||||
|
|
||||||
namespace binpac { namespace DTLS { class SSL_Conn; } }
|
namespace binpac { namespace DTLS { class SSL_Conn; } }
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
||||||
|
|
||||||
#include "analyzer/protocol/syslog/syslog_pac.h"
|
#include "analyzer/protocol/syslog/syslog_pac.h"
|
||||||
|
|
|
@ -123,7 +123,7 @@ static RecordVal* build_syn_packet_val(bool is_orig, const IP_Hdr* ip,
|
||||||
|
|
||||||
|
|
||||||
TCP_Analyzer::TCP_Analyzer(Connection* conn)
|
TCP_Analyzer::TCP_Analyzer(Connection* conn)
|
||||||
: TransportLayerAnalyzer("TCP", conn)
|
: packet_analysis::IP::SessionAdapter("TCP", conn)
|
||||||
{
|
{
|
||||||
// Set a timer to eventually time out this connection.
|
// Set a timer to eventually time out this connection.
|
||||||
ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer,
|
ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer,
|
||||||
|
@ -180,7 +180,7 @@ void TCP_Analyzer::Done()
|
||||||
|
|
||||||
analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::ID arg_id)
|
analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::ID arg_id)
|
||||||
{
|
{
|
||||||
analyzer::Analyzer* child = analyzer::TransportLayerAnalyzer::FindChild(arg_id);
|
analyzer::Analyzer* child = packet_analysis::IP::SessionAdapter::FindChild(arg_id);
|
||||||
|
|
||||||
if ( child )
|
if ( child )
|
||||||
return child;
|
return child;
|
||||||
|
@ -197,7 +197,7 @@ analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::ID arg_id)
|
||||||
|
|
||||||
analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::Tag arg_tag)
|
analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::Tag arg_tag)
|
||||||
{
|
{
|
||||||
analyzer::Analyzer* child = analyzer::TransportLayerAnalyzer::FindChild(arg_tag);
|
analyzer::Analyzer* child = packet_analysis::IP::SessionAdapter::FindChild(arg_tag);
|
||||||
|
|
||||||
if ( child )
|
if ( child )
|
||||||
return child;
|
return child;
|
||||||
|
@ -214,7 +214,7 @@ analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::Tag arg_tag)
|
||||||
|
|
||||||
bool TCP_Analyzer::RemoveChildAnalyzer(analyzer::ID id)
|
bool TCP_Analyzer::RemoveChildAnalyzer(analyzer::ID id)
|
||||||
{
|
{
|
||||||
auto rval = analyzer::TransportLayerAnalyzer::RemoveChildAnalyzer(id);
|
auto rval = packet_analysis::IP::SessionAdapter::RemoveChildAnalyzer(id);
|
||||||
|
|
||||||
if ( rval )
|
if ( rval )
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -1048,7 +1048,7 @@ static int32_t update_last_seq(TCP_Endpoint* endpoint, uint32_t last_seq,
|
||||||
void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
||||||
uint64_t seq, const IP_Hdr* ip, int caplen)
|
uint64_t seq, const IP_Hdr* ip, int caplen)
|
||||||
{
|
{
|
||||||
TransportLayerAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
packet_analysis::IP::SessionAdapter::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||||
|
|
||||||
const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen);
|
const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen);
|
||||||
if ( ! tp )
|
if ( ! tp )
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "zeek/IPAddr.h"
|
#include "zeek/IPAddr.h"
|
||||||
#include "zeek/analyzer/protocol/tcp/TCP_Endpoint.h"
|
#include "zeek/analyzer/protocol/tcp/TCP_Endpoint.h"
|
||||||
#include "zeek/analyzer/protocol/tcp/TCP_Flags.h"
|
#include "zeek/analyzer/protocol/tcp/TCP_Flags.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
|
||||||
#include "zeek/Conn.h"
|
#include "zeek/Conn.h"
|
||||||
|
|
||||||
// We define two classes here:
|
// We define two classes here:
|
||||||
|
@ -22,7 +23,7 @@ class TCP_Endpoint;
|
||||||
class TCP_Reassembler;
|
class TCP_Reassembler;
|
||||||
class TCP_ApplicationAnalyzer;
|
class TCP_ApplicationAnalyzer;
|
||||||
|
|
||||||
class TCP_Analyzer final : public analyzer::TransportLayerAnalyzer {
|
class TCP_Analyzer final : public packet_analysis::IP::SessionAdapter {
|
||||||
public:
|
public:
|
||||||
explicit TCP_Analyzer(Connection* conn);
|
explicit TCP_Analyzer(Connection* conn);
|
||||||
~TCP_Analyzer() override;
|
~TCP_Analyzer() override;
|
||||||
|
@ -72,6 +73,8 @@ public:
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
static analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
{ return new TCP_Analyzer(conn); }
|
{ return new TCP_Analyzer(conn); }
|
||||||
|
|
||||||
|
void AddExtraAnalyzers(Connection* conn) override {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class TCP_ApplicationAnalyzer;
|
friend class TCP_ApplicationAnalyzer;
|
||||||
friend class TCP_Reassembler;
|
friend class TCP_Reassembler;
|
||||||
|
|
|
@ -101,7 +101,7 @@ function set_contents_file%(cid: conn_id, direction: count, f: file%): bool
|
||||||
if ( ! c )
|
if ( ! c )
|
||||||
return zeek::val_mgr->False();
|
return zeek::val_mgr->False();
|
||||||
|
|
||||||
c->GetRootAnalyzer()->SetContentsFile(direction, {zeek::NewRef{}, f});
|
c->GetSessionAdapter()->SetContentsFile(direction, {zeek::NewRef{}, f});
|
||||||
return zeek::val_mgr->True();
|
return zeek::val_mgr->True();
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ function get_contents_file%(cid: conn_id, direction: count%): file
|
||||||
|
|
||||||
if ( c )
|
if ( c )
|
||||||
{
|
{
|
||||||
auto cf = c->GetRootAnalyzer()->GetContentsFile(direction);
|
auto cf = c->GetSessionAdapter()->GetContentsFile(direction);
|
||||||
|
|
||||||
if ( cf )
|
if ( cf )
|
||||||
return zeek::make_intrusive<zeek::FileVal>(std::move(cf));
|
return zeek::make_intrusive<zeek::FileVal>(std::move(cf));
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
#include "zeek/Conn.h"
|
#include "zeek/Conn.h"
|
||||||
#include "zeek/IP.h"
|
#include "zeek/IP.h"
|
||||||
#include "zeek/Reporter.h"
|
#include "zeek/Reporter.h"
|
||||||
#include "zeek/session/Manager.h"
|
|
||||||
#include "zeek/ZeekString.h"
|
#include "zeek/ZeekString.h"
|
||||||
#include "zeek/RunState.h"
|
#include "zeek/RunState.h"
|
||||||
#include "zeek/packet_analysis/protocol/iptunnel/IPTunnel.h"
|
#include "zeek/packet_analysis/protocol/iptunnel/IPTunnel.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IP.h"
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/teredo/events.bif.h"
|
#include "zeek/analyzer/protocol/teredo/events.bif.h"
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordValPtr TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const
|
RecordValPtr TeredoEncapsulation::BuildVal(const std::unique_ptr<IP_Hdr>& inner) const
|
||||||
{
|
{
|
||||||
static auto teredo_hdr_type = id::find_type<RecordType>("teredo_hdr");
|
static auto teredo_hdr_type = id::find_type<RecordType>("teredo_hdr");
|
||||||
static auto teredo_auth_type = id::find_type<RecordType>("teredo_auth");
|
static auto teredo_auth_type = id::find_type<RecordType>("teredo_auth");
|
||||||
|
@ -164,8 +164,8 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr* inner = nullptr;
|
std::unique_ptr<IP_Hdr> inner = nullptr;
|
||||||
int rslt = session_mgr->ParseIPPacket(len, te.InnerIP(), IPPROTO_IPV6, inner);
|
int rslt = packet_analysis::IP::ParsePacket(len, te.InnerIP(), IPPROTO_IPV6, inner);
|
||||||
|
|
||||||
if ( rslt > 0 )
|
if ( rslt > 0 )
|
||||||
{
|
{
|
||||||
|
@ -175,7 +175,6 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
Weird("Teredo_bubble_with_payload", true);
|
Weird("Teredo_bubble_with_payload", true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete inner;
|
|
||||||
ProtocolViolation("Teredo payload length", (const char*) data, len);
|
ProtocolViolation("Teredo payload length", (const char*) data, len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +192,6 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete inner;
|
|
||||||
ProtocolViolation("Truncated Teredo or invalid inner IP version", (const char*) data, len);
|
ProtocolViolation("Truncated Teredo or invalid inner IP version", (const char*) data, len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
const u_char* Authentication() const
|
const u_char* Authentication() const
|
||||||
{ return auth; }
|
{ return auth; }
|
||||||
|
|
||||||
RecordValPtr BuildVal(const IP_Hdr* inner) const;
|
RecordValPtr BuildVal(const std::unique_ptr<IP_Hdr>& inner) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au);
|
bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au);
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
// See the file in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#include "zeek/plugin/Plugin.h"
|
|
||||||
#include "zeek/analyzer/Component.h"
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
namespace zeek::plugin::detail::Zeek_UDP {
|
|
||||||
|
|
||||||
class Plugin : public zeek::plugin::Plugin {
|
|
||||||
public:
|
|
||||||
zeek::plugin::Configuration Configure() override
|
|
||||||
{
|
|
||||||
AddComponent(new zeek::analyzer::Component("UDP", zeek::analyzer::udp::UDP_Analyzer::Instantiate));
|
|
||||||
|
|
||||||
zeek::plugin::Configuration config;
|
|
||||||
config.name = "Zeek::UDP";
|
|
||||||
config.description = "UDP Analyzer";
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
} plugin;
|
|
||||||
|
|
||||||
} // namespace zeek::plugin::detail::Zeek_UDP
|
|
|
@ -1,275 +0,0 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#include "zeek/zeek-config.h"
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "zeek/RunState.h"
|
|
||||||
#include "zeek/NetVar.h"
|
|
||||||
#include "zeek/analyzer/Manager.h"
|
|
||||||
#include "zeek/Reporter.h"
|
|
||||||
#include "zeek/Conn.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/udp/events.bif.h"
|
|
||||||
|
|
||||||
namespace zeek::analyzer::udp {
|
|
||||||
|
|
||||||
UDP_Analyzer::UDP_Analyzer(Connection* conn)
|
|
||||||
: analyzer::TransportLayerAnalyzer("UDP", conn)
|
|
||||||
{
|
|
||||||
conn->EnableStatusUpdateTimer();
|
|
||||||
conn->SetInactivityTimeout(zeek::detail::udp_inactivity_timeout);
|
|
||||||
request_len = reply_len = -1; // -1 means "haven't seen any activity"
|
|
||||||
|
|
||||||
req_chk_cnt = rep_chk_cnt = 0;
|
|
||||||
req_chk_thresh = rep_chk_thresh = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
UDP_Analyzer::~UDP_Analyzer()
|
|
||||||
{
|
|
||||||
// XXX: need to implement this!
|
|
||||||
// delete src_pkt_writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDP_Analyzer::Init()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDP_Analyzer::Done()
|
|
||||||
{
|
|
||||||
Analyzer::Done();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
|
||||||
uint64_t seq, const IP_Hdr* ip, int caplen)
|
|
||||||
{
|
|
||||||
assert(ip);
|
|
||||||
|
|
||||||
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
|
|
||||||
|
|
||||||
const struct udphdr* up = (const struct udphdr*) data;
|
|
||||||
|
|
||||||
// Increment data before checksum check so that data will
|
|
||||||
// point to UDP payload even if checksum fails. Particularly,
|
|
||||||
// it allows event packet_contents to get to the data.
|
|
||||||
data += sizeof(struct udphdr);
|
|
||||||
|
|
||||||
// We need the min() here because Ethernet frame padding can lead to
|
|
||||||
// caplen > len.
|
|
||||||
if ( packet_contents )
|
|
||||||
PacketContents(data, std::min(len, caplen) - sizeof(struct udphdr));
|
|
||||||
|
|
||||||
int chksum = up->uh_sum;
|
|
||||||
|
|
||||||
auto validate_checksum =
|
|
||||||
! run_state::current_pkt->l3_checksummed &&
|
|
||||||
! zeek::detail::ignore_checksums &&
|
|
||||||
! zeek::id::find_val<TableVal>("ignore_checksums_nets")->Contains(ip->IPHeaderSrcAddr()) &&
|
|
||||||
caplen >=len;
|
|
||||||
|
|
||||||
constexpr auto vxlan_len = 8;
|
|
||||||
constexpr auto eth_len = 14;
|
|
||||||
|
|
||||||
if ( validate_checksum &&
|
|
||||||
len > ((int)sizeof(struct udphdr) + vxlan_len + eth_len) &&
|
|
||||||
(data[0] & 0x08) == 0x08 )
|
|
||||||
{
|
|
||||||
auto& vxlan_ports = analyzer_mgr->GetVxlanPorts();
|
|
||||||
|
|
||||||
if ( std::find(vxlan_ports.begin(), vxlan_ports.end(),
|
|
||||||
ntohs(up->uh_dport)) != vxlan_ports.end() )
|
|
||||||
{
|
|
||||||
// Looks like VXLAN on a well-known port, so the checksum should be
|
|
||||||
// transmitted as zero, and we should accept that. If not
|
|
||||||
// transmitted as zero, then validating the checksum is optional.
|
|
||||||
if ( chksum == 0 )
|
|
||||||
validate_checksum = false;
|
|
||||||
else
|
|
||||||
validate_checksum = BifConst::Tunnel::validate_vxlan_checksums;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( validate_checksum )
|
|
||||||
{
|
|
||||||
bool bad = false;
|
|
||||||
|
|
||||||
if ( ip->IP4_Hdr() )
|
|
||||||
{
|
|
||||||
if ( chksum && ! ValidateChecksum(ip, up, len) )
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* checksum is not optional for IPv6 */
|
|
||||||
else if ( ! ValidateChecksum(ip, up, len) )
|
|
||||||
bad = true;
|
|
||||||
|
|
||||||
if ( bad )
|
|
||||||
{
|
|
||||||
Weird("bad_UDP_checksum");
|
|
||||||
|
|
||||||
if ( is_orig )
|
|
||||||
{
|
|
||||||
uint32_t t = req_chk_thresh;
|
|
||||||
if ( Conn()->ScaledHistoryEntry('C', req_chk_cnt,
|
|
||||||
req_chk_thresh) )
|
|
||||||
ChecksumEvent(is_orig, t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t t = rep_chk_thresh;
|
|
||||||
if ( Conn()->ScaledHistoryEntry('c', rep_chk_cnt,
|
|
||||||
rep_chk_thresh) )
|
|
||||||
ChecksumEvent(is_orig, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ulen = ntohs(up->uh_ulen);
|
|
||||||
if ( ulen != len )
|
|
||||||
Weird("UDP_datagram_length_mismatch", util::fmt("%d != %d", ulen, len));
|
|
||||||
|
|
||||||
len -= sizeof(struct udphdr);
|
|
||||||
ulen -= sizeof(struct udphdr);
|
|
||||||
caplen -= sizeof(struct udphdr);
|
|
||||||
|
|
||||||
Conn()->SetLastTime(run_state::current_timestamp);
|
|
||||||
|
|
||||||
if ( udp_contents )
|
|
||||||
{
|
|
||||||
static auto udp_content_ports = id::find_val<TableVal>("udp_content_ports");
|
|
||||||
static auto udp_content_delivery_ports_orig = id::find_val<TableVal>("udp_content_delivery_ports_orig");
|
|
||||||
static auto udp_content_delivery_ports_resp = id::find_val<TableVal>("udp_content_delivery_ports_resp");
|
|
||||||
bool do_udp_contents = false;
|
|
||||||
const auto& sport_val = val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP);
|
|
||||||
const auto& dport_val = val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP);
|
|
||||||
|
|
||||||
if ( udp_content_ports->FindOrDefault(dport_val) ||
|
|
||||||
udp_content_ports->FindOrDefault(sport_val) )
|
|
||||||
do_udp_contents = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint16_t p = zeek::detail::udp_content_delivery_ports_use_resp ? Conn()->RespPort()
|
|
||||||
: up->uh_dport;
|
|
||||||
const auto& port_val = zeek::val_mgr->Port(ntohs(p), TRANSPORT_UDP);
|
|
||||||
|
|
||||||
if ( is_orig )
|
|
||||||
{
|
|
||||||
auto result = udp_content_delivery_ports_orig->FindOrDefault(port_val);
|
|
||||||
|
|
||||||
if ( zeek::detail::udp_content_deliver_all_orig || (result && result->AsBool()) )
|
|
||||||
do_udp_contents = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto result = udp_content_delivery_ports_resp->FindOrDefault(port_val);
|
|
||||||
|
|
||||||
if ( zeek::detail::udp_content_deliver_all_resp || (result && result->AsBool()) )
|
|
||||||
do_udp_contents = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( do_udp_contents )
|
|
||||||
EnqueueConnEvent(udp_contents,
|
|
||||||
ConnVal(),
|
|
||||||
val_mgr->Bool(is_orig),
|
|
||||||
make_intrusive<StringVal>(len, (const char*) data));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( is_orig )
|
|
||||||
{
|
|
||||||
Conn()->CheckHistory(HIST_ORIG_DATA_PKT, 'D');
|
|
||||||
|
|
||||||
if ( request_len < 0 )
|
|
||||||
request_len = ulen;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request_len += ulen;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if ( request_len < 0 )
|
|
||||||
reporter->Warning("wrapping around for UDP request length");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Event(udp_request);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Conn()->CheckHistory(HIST_RESP_DATA_PKT, 'd');
|
|
||||||
|
|
||||||
if ( reply_len < 0 )
|
|
||||||
reply_len = ulen;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reply_len += ulen;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if ( reply_len < 0 )
|
|
||||||
reporter->Warning("wrapping around for UDP reply length");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Event(udp_reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( caplen >= len )
|
|
||||||
ForwardPacket(len, data, is_orig, seq, ip, caplen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDP_Analyzer::UpdateConnVal(RecordVal* conn_val)
|
|
||||||
{
|
|
||||||
auto orig_endp = conn_val->GetFieldAs<RecordVal>("orig");
|
|
||||||
auto resp_endp = conn_val->GetFieldAs<RecordVal>("resp");
|
|
||||||
|
|
||||||
UpdateEndpointVal(orig_endp, true);
|
|
||||||
UpdateEndpointVal(resp_endp, false);
|
|
||||||
|
|
||||||
// Call children's UpdateConnVal
|
|
||||||
Analyzer::UpdateConnVal(conn_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDP_Analyzer::UpdateEndpointVal(RecordVal* endp, bool is_orig)
|
|
||||||
{
|
|
||||||
bro_int_t size = is_orig ? request_len : reply_len;
|
|
||||||
if ( size < 0 )
|
|
||||||
{
|
|
||||||
endp->Assign(0, 0);
|
|
||||||
endp->Assign(1, UDP_INACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
endp->Assign(0, static_cast<uint64_t>(size));
|
|
||||||
endp->Assign(1, UDP_ACTIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UDP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int UDP_Analyzer::MemoryAllocation() const
|
|
||||||
{
|
|
||||||
// A rather low lower bound....
|
|
||||||
return Analyzer::MemoryAllocation() + padded_sizeof(*this) - 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDP_Analyzer::ChecksumEvent(bool is_orig, uint32_t threshold)
|
|
||||||
{
|
|
||||||
Conn()->HistoryThresholdEvent(udp_multiple_checksum_errors,
|
|
||||||
is_orig, threshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UDP_Analyzer::ValidateChecksum(const IP_Hdr* ip, const udphdr* up, int len)
|
|
||||||
{
|
|
||||||
auto sum = detail::ip_in_cksum(ip->IP4_Hdr(), ip->SrcAddr(), ip->DstAddr(),
|
|
||||||
IPPROTO_UDP,
|
|
||||||
reinterpret_cast<const uint8_t*>(up), len);
|
|
||||||
|
|
||||||
return sum == 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace zeek::analyzer::udp
|
|
|
@ -1,57 +0,0 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// This will include netinet/udp.h for us, plus set up some defines that make it work on all
|
|
||||||
// of the CI platforms.
|
|
||||||
#include "zeek/net_util.h"
|
|
||||||
|
|
||||||
#include "zeek/analyzer/Analyzer.h"
|
|
||||||
|
|
||||||
namespace zeek::analyzer::udp {
|
|
||||||
|
|
||||||
enum UDP_EndpointState {
|
|
||||||
UDP_INACTIVE, // no packet seen
|
|
||||||
UDP_ACTIVE, // packets seen
|
|
||||||
};
|
|
||||||
|
|
||||||
class UDP_Analyzer final : public analyzer::TransportLayerAnalyzer {
|
|
||||||
public:
|
|
||||||
explicit UDP_Analyzer(Connection* conn);
|
|
||||||
~UDP_Analyzer() override;
|
|
||||||
|
|
||||||
void Init() override;
|
|
||||||
void UpdateConnVal(RecordVal *conn_val) override;
|
|
||||||
|
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
|
||||||
{ return new UDP_Analyzer(conn); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Done() override;
|
|
||||||
void DeliverPacket(int len, const u_char* data, bool orig,
|
|
||||||
uint64_t seq, const IP_Hdr* ip, int caplen) override;
|
|
||||||
bool IsReuse(double t, const u_char* pkt) override;
|
|
||||||
unsigned int MemoryAllocation() const override;
|
|
||||||
|
|
||||||
void ChecksumEvent(bool is_orig, uint32_t threshold);
|
|
||||||
|
|
||||||
// Returns true if the checksum is valid, false if not
|
|
||||||
static bool ValidateChecksum(const IP_Hdr* ip, const struct udphdr* up,
|
|
||||||
int len);
|
|
||||||
|
|
||||||
bro_int_t request_len, reply_len;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void UpdateEndpointVal(RecordVal* endp, bool is_orig);
|
|
||||||
|
|
||||||
#define HIST_ORIG_DATA_PKT 0x1
|
|
||||||
#define HIST_RESP_DATA_PKT 0x2
|
|
||||||
#define HIST_ORIG_CORRUPT_PKT 0x4
|
|
||||||
#define HIST_RESP_CORRUPT_PKT 0x8
|
|
||||||
|
|
||||||
// For tracking checksum history.
|
|
||||||
uint32_t req_chk_cnt, req_chk_thresh;
|
|
||||||
uint32_t rep_chk_cnt, rep_chk_thresh;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace zeek::analyzer::udp
|
|
|
@ -41,7 +41,7 @@ static zeek::analyzer::Analyzer* add_analyzer(zeek::Connection* conn)
|
||||||
auto a = zeek::analyzer_mgr->InstantiateAnalyzer(ZEEK_FUZZ_ANALYZER, conn);
|
auto a = zeek::analyzer_mgr->InstantiateAnalyzer(ZEEK_FUZZ_ANALYZER, conn);
|
||||||
tcp->AddChildAnalyzer(a);
|
tcp->AddChildAnalyzer(a);
|
||||||
tcp->AddChildAnalyzer(pia->AsAnalyzer());
|
tcp->AddChildAnalyzer(pia->AsAnalyzer());
|
||||||
conn->SetRootAnalyzer(tcp, pia);
|
conn->SetSessionAdapter(tcp, pia);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,13 @@ public:
|
||||||
*/
|
*/
|
||||||
mutable bool dump_packet;
|
mutable bool dump_packet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the amount of data to be dumped. If only a header is needed,
|
||||||
|
* set this to the size of the header. Setting it to zero will dump the
|
||||||
|
* entire packet.
|
||||||
|
*/
|
||||||
|
mutable int dump_size = 0;
|
||||||
|
|
||||||
// These are fields passed between various packet analyzers. They're best
|
// These are fields passed between various packet analyzers. They're best
|
||||||
// stored with the packet so they stay available as the packet is passed
|
// stored with the packet so they stay available as the packet is passed
|
||||||
// around.
|
// around.
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
namespace zeek::packet_analysis {
|
namespace zeek::packet_analysis {
|
||||||
|
|
||||||
Analyzer::Analyzer(std::string name)
|
Analyzer::Analyzer(std::string name, bool report_unknown_protocols) :
|
||||||
|
report_unknown_protocols(report_unknown_protocols)
|
||||||
{
|
{
|
||||||
Tag t = packet_mgr->GetComponentTag(name);
|
Tag t = packet_mgr->GetComponentTag(name);
|
||||||
|
|
||||||
|
@ -79,12 +80,17 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet,
|
||||||
inner_analyzer = default_analyzer;
|
inner_analyzer = default_analyzer;
|
||||||
|
|
||||||
if ( inner_analyzer == nullptr )
|
if ( inner_analyzer == nullptr )
|
||||||
|
{
|
||||||
|
if ( report_unknown_protocols )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s failed, could not find analyzer for identifier %#x.",
|
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s failed, could not find analyzer for identifier %#x.",
|
||||||
GetAnalyzerName(), identifier);
|
GetAnalyzerName(), identifier);
|
||||||
packet_mgr->ReportUnknownProtocol(GetAnalyzerName(), identifier, data, len);
|
packet_mgr->ReportUnknownProtocol(GetAnalyzerName(), identifier, data, len);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||||
GetAnalyzerName(), identifier);
|
GetAnalyzerName(), identifier);
|
||||||
|
@ -99,7 +105,9 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet) co
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s stopped, no default analyzer available.",
|
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s stopped, no default analyzer available.",
|
||||||
GetAnalyzerName());
|
GetAnalyzerName());
|
||||||
|
|
||||||
|
if ( report_unknown_protocols )
|
||||||
Weird("no_suitable_analyzer_found", packet);
|
Weird("no_suitable_analyzer_found", packet);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,11 @@ public:
|
||||||
*
|
*
|
||||||
* @param name The name for the type of analyzer. The name must match
|
* @param name The name for the type of analyzer. The name must match
|
||||||
* the one the corresponding Component registers.
|
* the one the corresponding Component registers.
|
||||||
|
* @param report_unknown_protocols Flag for whether to report unknown
|
||||||
|
* protocols during packet forwarding. This should generally always be
|
||||||
|
* set to true.
|
||||||
*/
|
*/
|
||||||
explicit Analyzer(std::string name);
|
explicit Analyzer(std::string name, bool report_unknown_protocols=true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -165,6 +168,11 @@ private:
|
||||||
Dispatcher dispatcher;
|
Dispatcher dispatcher;
|
||||||
AnalyzerPtr default_analyzer = nullptr;
|
AnalyzerPtr default_analyzer = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag for whether to report unknown protocols in ForwardPacket.
|
||||||
|
*/
|
||||||
|
bool report_unknown_protocols = true;
|
||||||
|
|
||||||
void Init(const Tag& tag);
|
void Init(const Tag& tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ void Manager::ProcessPacket(Packet* packet)
|
||||||
bool dumped_packet = false;
|
bool dumped_packet = false;
|
||||||
if ( packet->dump_packet || zeek::detail::record_all_packets )
|
if ( packet->dump_packet || zeek::detail::record_all_packets )
|
||||||
{
|
{
|
||||||
DumpPacket(packet);
|
DumpPacket(packet, packet->dump_size);
|
||||||
dumped_packet = true;
|
dumped_packet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ void Manager::ProcessPacket(Packet* packet)
|
||||||
|
|
||||||
// Check whether packet should be recorded based on session analysis
|
// Check whether packet should be recorded based on session analysis
|
||||||
if ( packet->dump_packet && ! dumped_packet )
|
if ( packet->dump_packet && ! dumped_packet )
|
||||||
DumpPacket(packet);
|
DumpPacket(packet, packet->dump_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::ProcessInnerPacket(Packet* packet)
|
bool Manager::ProcessInnerPacket(Packet* packet)
|
||||||
|
|
|
@ -15,6 +15,9 @@ add_subdirectory(linux_sll)
|
||||||
|
|
||||||
add_subdirectory(arp)
|
add_subdirectory(arp)
|
||||||
add_subdirectory(ip)
|
add_subdirectory(ip)
|
||||||
|
add_subdirectory(udp)
|
||||||
|
add_subdirectory(tcp)
|
||||||
|
add_subdirectory(icmp)
|
||||||
add_subdirectory(gre)
|
add_subdirectory(gre)
|
||||||
add_subdirectory(iptunnel)
|
add_subdirectory(iptunnel)
|
||||||
add_subdirectory(vntag)
|
add_subdirectory(vntag)
|
||||||
|
|
|
@ -1,55 +1,89 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include "zeek/zeek-config.h"
|
#include "zeek/packet_analysis/protocol/icmp/ICMP.h"
|
||||||
#include "zeek/analyzer/protocol/icmp/ICMP.h"
|
|
||||||
|
|
||||||
#include <netinet/icmp6.h>
|
#include <netinet/icmp6.h>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "zeek/IP.h"
|
|
||||||
#include "zeek/RunState.h"
|
#include "zeek/RunState.h"
|
||||||
#include "zeek/NetVar.h"
|
|
||||||
#include "zeek/Event.h"
|
|
||||||
#include "zeek/Conn.h"
|
#include "zeek/Conn.h"
|
||||||
#include "zeek/Desc.h"
|
|
||||||
#include "zeek/Reporter.h"
|
#include "zeek/Reporter.h"
|
||||||
|
#include "zeek/Desc.h"
|
||||||
|
#include "zeek/Val.h"
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
#include "zeek/session/Manager.h"
|
||||||
|
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/icmp/events.bif.h"
|
#include "zeek/ZeekString.h"
|
||||||
|
|
||||||
namespace zeek::analyzer::icmp {
|
#include "zeek/packet_analysis/protocol/icmp/events.bif.h"
|
||||||
|
|
||||||
ICMP_Analyzer::ICMP_Analyzer(Connection* c)
|
enum ICMP_EndpointState {
|
||||||
: TransportLayerAnalyzer("ICMP", c),
|
ICMP_INACTIVE, // no packet seen
|
||||||
icmp_conn_val(), type(), code(), request_len(-1), reply_len(-1)
|
ICMP_ACTIVE, // packets seen
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace zeek::packet_analysis::ICMP;
|
||||||
|
using namespace zeek::packet_analysis::IP;
|
||||||
|
|
||||||
|
ICMPAnalyzer::ICMPAnalyzer() : IPBasedAnalyzer("ICMP", TRANSPORT_ICMP, ICMP_PORT_MASK, false)
|
||||||
{
|
{
|
||||||
c->SetInactivityTimeout(zeek::detail::icmp_inactivity_timeout);
|
// TODO: remove once the other plugins are done
|
||||||
|
new_plugin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::Done()
|
ICMPAnalyzer::~ICMPAnalyzer()
|
||||||
{
|
{
|
||||||
TransportLayerAnalyzer::Done();
|
|
||||||
icmp_conn_val = nullptr;
|
|
||||||
matcher_state.FinishEndpointMatcher();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
|
SessionAdapter* ICMPAnalyzer::MakeSessionAdapter(Connection* conn)
|
||||||
bool is_orig, uint64_t seq, const IP_Hdr* ip, int caplen)
|
|
||||||
{
|
{
|
||||||
assert(ip);
|
auto* root = new ICMPSessionAdapter(conn);
|
||||||
|
root->SetParent(this);
|
||||||
|
conn->SetInactivityTimeout(zeek::detail::icmp_inactivity_timeout);
|
||||||
|
|
||||||
TransportLayerAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
// We need the min() here because Ethernet frame padding can lead to
|
bool ICMPAnalyzer::BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
// caplen > len.
|
ConnTuple& tuple)
|
||||||
if ( packet_contents )
|
{
|
||||||
// Subtract off the common part of ICMP header.
|
if ( ! CheckHeaderTrunc(ICMP_MINLEN, len, packet) )
|
||||||
PacketContents(data + 8, std::min(len, caplen) - 8);
|
return false;
|
||||||
|
|
||||||
|
tuple.src_addr = packet->ip_hdr->SrcAddr();
|
||||||
|
tuple.dst_addr = packet->ip_hdr->DstAddr();
|
||||||
|
tuple.proto = TRANSPORT_ICMP;
|
||||||
|
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
const struct icmp* icmpp = (const struct icmp *) data;
|
||||||
|
tuple.src_port = htons(icmpp->icmp_type);
|
||||||
|
|
||||||
|
if ( packet->proto == IPPROTO_ICMP )
|
||||||
|
tuple.dst_port = htons(ICMP4_counterpart(icmpp->icmp_type, icmpp->icmp_code, tuple.is_one_way));
|
||||||
|
else if ( packet->proto == IPPROTO_ICMPV6 )
|
||||||
|
tuple.dst_port = htons(ICMP6_counterpart(icmpp->icmp_type, icmpp->icmp_code, tuple.is_one_way));
|
||||||
|
else
|
||||||
|
reporter->InternalError("Reached ICMP packet analyzer with unknown packet protocol %x",
|
||||||
|
packet->proto);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remaining, Packet* pkt)
|
||||||
|
{
|
||||||
|
auto* adapter = static_cast<ICMPSessionAdapter*>(c->GetSessionAdapter());
|
||||||
|
|
||||||
|
const u_char* data = pkt->ip_hdr->Payload();
|
||||||
|
int len = pkt->ip_hdr->PayloadLen();
|
||||||
|
|
||||||
|
if ( packet_contents && len > 0 )
|
||||||
|
adapter->PacketContents(data + 8, std::min(len, remaining) - 8);
|
||||||
|
|
||||||
|
const struct icmp* icmpp = (const struct icmp*) data;
|
||||||
|
const std::unique_ptr<IP_Hdr>& ip = pkt->ip_hdr;
|
||||||
|
|
||||||
if ( ! zeek::detail::ignore_checksums &&
|
if ( ! zeek::detail::ignore_checksums &&
|
||||||
! zeek::id::find_val<TableVal>("ignore_checksums_nets")->Contains(ip->IPHeaderSrcAddr()) &&
|
! zeek::id::find_val<TableVal>("ignore_checksums_nets")->Contains(ip->IPHeaderSrcAddr()) &&
|
||||||
caplen >= len )
|
remaining >= len )
|
||||||
{
|
{
|
||||||
int chksum = 0;
|
int chksum = 0;
|
||||||
|
|
||||||
|
@ -60,94 +94,81 @@ void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_ICMPV6:
|
case IPPROTO_ICMPV6:
|
||||||
chksum = icmp6_checksum(icmpp, ip, len);
|
chksum = icmp6_checksum(icmpp, ip.get(), len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
reporter->AnalyzerError(
|
reporter->Error("unexpected IP proto in ICMP analyzer: %d", ip->NextProto());
|
||||||
this, "unexpected IP proto in ICMP analyzer: %d", ip->NextProto());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( chksum != 0xffff )
|
if ( chksum != 0xffff )
|
||||||
{
|
{
|
||||||
Weird("bad_ICMP_checksum");
|
adapter->Weird("bad_ICMP_checksum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Conn()->SetLastTime(run_state::current_timestamp);
|
c->SetLastTime(run_state::current_timestamp);
|
||||||
|
adapter->InitEndpointMatcher(ip.get(), len, is_orig);
|
||||||
if ( zeek::detail::rule_matcher )
|
|
||||||
{
|
|
||||||
if ( ! matcher_state.MatcherInitialized(is_orig) )
|
|
||||||
matcher_state.InitEndpointMatcher(this, ip, len, is_orig, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
type = icmpp->icmp_type;
|
|
||||||
code = icmpp->icmp_code;
|
|
||||||
|
|
||||||
// Move past common portion of ICMP header.
|
// Move past common portion of ICMP header.
|
||||||
data += 8;
|
data += 8;
|
||||||
caplen -= 8;
|
remaining -= 8;
|
||||||
len -= 8;
|
len -= 8;
|
||||||
|
|
||||||
int& len_stat = is_orig ? request_len : reply_len;
|
adapter->UpdateLength(is_orig, len);
|
||||||
if ( len_stat < 0 )
|
|
||||||
len_stat = len;
|
|
||||||
else
|
|
||||||
len_stat += len;
|
|
||||||
|
|
||||||
if ( ip->NextProto() == IPPROTO_ICMP )
|
if ( ip->NextProto() == IPPROTO_ICMP )
|
||||||
NextICMP4(run_state::current_timestamp, icmpp, len, caplen, data, ip);
|
NextICMP4(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), adapter);
|
||||||
else if ( ip->NextProto() == IPPROTO_ICMPV6 )
|
else if ( ip->NextProto() == IPPROTO_ICMPV6 )
|
||||||
NextICMP6(run_state::current_timestamp, icmpp, len, caplen, data, ip);
|
NextICMP6(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), adapter);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reporter->AnalyzerError(
|
reporter->Error("expected ICMP as IP packet's protocol, got %d", ip->NextProto());
|
||||||
this, "expected ICMP as IP packet's protocol, got %d", ip->NextProto());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ForwardPacket(len, data, pkt);
|
||||||
|
|
||||||
if ( caplen >= len )
|
if ( remaining >= len )
|
||||||
ForwardPacket(len, data, is_orig, seq, ip, caplen);
|
adapter->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining);
|
||||||
|
|
||||||
if ( zeek::detail::rule_matcher )
|
adapter->MatchEndpoint(data, len, is_orig);
|
||||||
matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig,
|
|
||||||
false, false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
|
void ICMPAnalyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
const u_char*& data, const IP_Hdr* ip_hdr )
|
const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
switch ( icmpp->icmp_type )
|
switch ( icmpp->icmp_type )
|
||||||
{
|
{
|
||||||
case ICMP_ECHO:
|
case ICMP_ECHO:
|
||||||
case ICMP_ECHOREPLY:
|
case ICMP_ECHOREPLY:
|
||||||
Echo(t, icmpp, len, caplen, data, ip_hdr);
|
Echo(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICMP_UNREACH:
|
case ICMP_UNREACH:
|
||||||
case ICMP_TIMXCEED:
|
case ICMP_TIMXCEED:
|
||||||
Context4(t, icmpp, len, caplen, data, ip_hdr);
|
Context4(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ICMP_Sent(icmpp, len, caplen, 0, data, ip_hdr);
|
ICMP_Sent(icmpp, len, caplen, 0, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
|
void ICMPAnalyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
const u_char*& data, const IP_Hdr* ip_hdr )
|
const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
switch ( icmpp->icmp_type )
|
switch ( icmpp->icmp_type )
|
||||||
{
|
{
|
||||||
// Echo types.
|
// Echo types.
|
||||||
case ICMP6_ECHO_REQUEST:
|
case ICMP6_ECHO_REQUEST:
|
||||||
case ICMP6_ECHO_REPLY:
|
case ICMP6_ECHO_REPLY:
|
||||||
Echo(t, icmpp, len, caplen, data, ip_hdr);
|
Echo(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Error messages all have the same structure for their context,
|
// Error messages all have the same structure for their context,
|
||||||
|
@ -156,27 +177,27 @@ void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int c
|
||||||
case ICMP6_TIME_EXCEEDED:
|
case ICMP6_TIME_EXCEEDED:
|
||||||
case ICMP6_PACKET_TOO_BIG:
|
case ICMP6_PACKET_TOO_BIG:
|
||||||
case ICMP6_DST_UNREACH:
|
case ICMP6_DST_UNREACH:
|
||||||
Context6(t, icmpp, len, caplen, data, ip_hdr);
|
Context6(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Router related messages.
|
// Router related messages.
|
||||||
case ND_REDIRECT:
|
case ND_REDIRECT:
|
||||||
Redirect(t, icmpp, len, caplen, data, ip_hdr);
|
Redirect(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
case ND_ROUTER_ADVERT:
|
case ND_ROUTER_ADVERT:
|
||||||
RouterAdvert(t, icmpp, len, caplen, data, ip_hdr);
|
RouterAdvert(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
case ND_NEIGHBOR_ADVERT:
|
case ND_NEIGHBOR_ADVERT:
|
||||||
NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr);
|
NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
case ND_NEIGHBOR_SOLICIT:
|
case ND_NEIGHBOR_SOLICIT:
|
||||||
NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr);
|
NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
case ND_ROUTER_SOLICIT:
|
case ND_ROUTER_SOLICIT:
|
||||||
RouterSolicit(t, icmpp, len, caplen, data, ip_hdr);
|
RouterSolicit(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
case ICMP6_ROUTER_RENUMBERING:
|
case ICMP6_ROUTER_RENUMBERING:
|
||||||
ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr);
|
ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -190,49 +211,45 @@ void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int c
|
||||||
// the same structure for their context, and are
|
// the same structure for their context, and are
|
||||||
// handled by the same function.
|
// handled by the same function.
|
||||||
if ( icmpp->icmp_type < 128 )
|
if ( icmpp->icmp_type < 128 )
|
||||||
Context6(t, icmpp, len, caplen, data, ip_hdr);
|
Context6(t, icmpp, len, caplen, data, ip_hdr, adapter);
|
||||||
else
|
else
|
||||||
ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr);
|
ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, adapter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::ICMP_Sent(const struct icmp* icmpp, int len, int caplen,
|
void ICMPAnalyzer::ICMP_Sent(const struct icmp* icmpp, int len, int caplen,
|
||||||
int icmpv6, const u_char* data,
|
int icmpv6, const u_char* data, const IP_Hdr* ip_hdr,
|
||||||
const IP_Hdr* ip_hdr)
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
if ( icmp_sent )
|
if ( icmp_sent )
|
||||||
EnqueueConnEvent(icmp_sent,
|
adapter->EnqueueConnEvent(icmp_sent, adapter->ConnVal(),
|
||||||
ConnVal(),
|
BuildInfo(icmpp, len, icmpv6, ip_hdr));
|
||||||
BuildInfo(icmpp, len, icmpv6, ip_hdr)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( icmp_sent_payload )
|
if ( icmp_sent_payload )
|
||||||
{
|
{
|
||||||
String* payload = new String(data, std::min(len, caplen), false);
|
String* payload = new String(data, std::min(len, caplen), false);
|
||||||
|
|
||||||
EnqueueConnEvent(icmp_sent_payload,
|
adapter->EnqueueConnEvent(icmp_sent_payload, adapter->ConnVal(),
|
||||||
ConnVal(),
|
|
||||||
BuildInfo(icmpp, len, icmpv6, ip_hdr),
|
BuildInfo(icmpp, len, icmpv6, ip_hdr),
|
||||||
make_intrusive<StringVal>(payload)
|
make_intrusive<StringVal>(payload));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordValPtr ICMP_Analyzer::BuildInfo(const struct icmp* icmpp, int len,
|
zeek::RecordValPtr ICMPAnalyzer::BuildInfo(const struct icmp* icmpp, int len,
|
||||||
bool icmpv6, const IP_Hdr* ip_hdr)
|
bool icmpv6, const IP_Hdr* ip_hdr)
|
||||||
{
|
{
|
||||||
static auto icmp_info = id::find_type<RecordType>("icmp_info");
|
static auto icmp_info = id::find_type<RecordType>("icmp_info");
|
||||||
auto rval = make_intrusive<RecordVal>(icmp_info);
|
auto rval = make_intrusive<zeek::RecordVal>(icmp_info);
|
||||||
rval->Assign(0, static_cast<bool>(icmpv6));
|
rval->Assign(0, val_mgr->Bool(icmpv6));
|
||||||
rval->Assign(1, icmpp->icmp_type);
|
rval->Assign(1, val_mgr->Count(icmpp->icmp_type));
|
||||||
rval->Assign(2, icmpp->icmp_code);
|
rval->Assign(2, val_mgr->Count(icmpp->icmp_code));
|
||||||
rval->Assign(3, len);
|
rval->Assign(3, val_mgr->Count(len));
|
||||||
rval->Assign(4, ip_hdr->TTL());
|
rval->Assign(4, val_mgr->Count(ip_hdr->TTL()));
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransportProto ICMP_Analyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, uint32_t* dst_port)
|
TransportProto ICMPAnalyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, uint32_t* dst_port)
|
||||||
{
|
{
|
||||||
const u_char* transport_hdr;
|
const u_char* transport_hdr;
|
||||||
uint32_t ip_hdr_len = ip_hdr->HdrLen();
|
uint32_t ip_hdr_len = ip_hdr->HdrLen();
|
||||||
|
@ -297,7 +314,7 @@ TransportProto ICMP_Analyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t*
|
||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordValPtr ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data)
|
zeek::RecordValPtr ICMPAnalyzer::ExtractICMP4Context(int len, const u_char*& data)
|
||||||
{
|
{
|
||||||
const IP_Hdr ip_hdr_data((const struct ip*) data, false);
|
const IP_Hdr ip_hdr_data((const struct ip*) data, false);
|
||||||
const IP_Hdr* ip_hdr = &ip_hdr_data;
|
const IP_Hdr* ip_hdr = &ip_hdr_data;
|
||||||
|
@ -346,8 +363,8 @@ RecordValPtr ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto icmp_context = id::find_type<RecordType>("icmp_context");
|
static auto icmp_context = id::find_type<RecordType>("icmp_context");
|
||||||
auto iprec = make_intrusive<RecordVal>(icmp_context);
|
auto iprec = make_intrusive<zeek::RecordVal>(icmp_context);
|
||||||
auto id_val = make_intrusive<RecordVal>(id::conn_id);
|
auto id_val = make_intrusive<zeek::RecordVal>(id::conn_id);
|
||||||
|
|
||||||
id_val->Assign(0, make_intrusive<AddrVal>(src_addr));
|
id_val->Assign(0, make_intrusive<AddrVal>(src_addr));
|
||||||
id_val->Assign(1, val_mgr->Port(src_port, proto));
|
id_val->Assign(1, val_mgr->Port(src_port, proto));
|
||||||
|
@ -355,18 +372,18 @@ RecordValPtr ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data)
|
||||||
id_val->Assign(3, val_mgr->Port(dst_port, proto));
|
id_val->Assign(3, val_mgr->Port(dst_port, proto));
|
||||||
|
|
||||||
iprec->Assign(0, std::move(id_val));
|
iprec->Assign(0, std::move(id_val));
|
||||||
iprec->Assign(1, ip_len);
|
iprec->Assign(1, val_mgr->Count(ip_len));
|
||||||
iprec->Assign(2, proto);
|
iprec->Assign(2, val_mgr->Count(proto));
|
||||||
iprec->Assign(3, frag_offset);
|
iprec->Assign(3, val_mgr->Count(frag_offset));
|
||||||
iprec->Assign(4, static_cast<bool>(bad_hdr_len));
|
iprec->Assign(4, val_mgr->Bool(bad_hdr_len));
|
||||||
iprec->Assign(5, static_cast<bool>(bad_checksum));
|
iprec->Assign(5, val_mgr->Bool(bad_checksum));
|
||||||
iprec->Assign(6, static_cast<bool>(MF));
|
iprec->Assign(6, val_mgr->Bool(MF));
|
||||||
iprec->Assign(7, static_cast<bool>(DF));
|
iprec->Assign(7, val_mgr->Bool(DF));
|
||||||
|
|
||||||
return iprec;
|
return iprec;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordValPtr ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
|
zeek::RecordValPtr ICMPAnalyzer::ExtractICMP6Context(int len, const u_char*& data)
|
||||||
{
|
{
|
||||||
int DF = 0, MF = 0, bad_hdr_len = 0;
|
int DF = 0, MF = 0, bad_hdr_len = 0;
|
||||||
TransportProto proto = TRANSPORT_UNKNOWN;
|
TransportProto proto = TRANSPORT_UNKNOWN;
|
||||||
|
@ -406,8 +423,8 @@ RecordValPtr ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto icmp_context = id::find_type<RecordType>("icmp_context");
|
static auto icmp_context = id::find_type<RecordType>("icmp_context");
|
||||||
auto iprec = make_intrusive<RecordVal>(icmp_context);
|
auto iprec = make_intrusive<zeek::RecordVal>(icmp_context);
|
||||||
auto id_val = make_intrusive<RecordVal>(id::conn_id);
|
auto id_val = make_intrusive<zeek::RecordVal>(id::conn_id);
|
||||||
|
|
||||||
id_val->Assign(0, make_intrusive<AddrVal>(src_addr));
|
id_val->Assign(0, make_intrusive<AddrVal>(src_addr));
|
||||||
id_val->Assign(1, val_mgr->Port(src_port, proto));
|
id_val->Assign(1, val_mgr->Port(src_port, proto));
|
||||||
|
@ -415,84 +432,21 @@ RecordValPtr ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
|
||||||
id_val->Assign(3, val_mgr->Port(dst_port, proto));
|
id_val->Assign(3, val_mgr->Port(dst_port, proto));
|
||||||
|
|
||||||
iprec->Assign(0, std::move(id_val));
|
iprec->Assign(0, std::move(id_val));
|
||||||
iprec->Assign(1, ip_len);
|
iprec->Assign(1, val_mgr->Count(ip_len));
|
||||||
iprec->Assign(2, proto);
|
iprec->Assign(2, val_mgr->Count(proto));
|
||||||
iprec->Assign(3, frag_offset);
|
iprec->Assign(3, val_mgr->Count(frag_offset));
|
||||||
iprec->Assign(4, static_cast<bool>(bad_hdr_len));
|
iprec->Assign(4, val_mgr->Bool(bad_hdr_len));
|
||||||
// bad_checksum is always false since IPv6 layer doesn't have a checksum.
|
// bad_checksum is always false since IPv6 layer doesn't have a checksum.
|
||||||
iprec->Assign(5, false);
|
iprec->Assign(5, val_mgr->False());
|
||||||
iprec->Assign(6, static_cast<bool>(MF));
|
iprec->Assign(6, val_mgr->Bool(MF));
|
||||||
iprec->Assign(7, static_cast<bool>(DF));
|
iprec->Assign(7, val_mgr->Bool(DF));
|
||||||
|
|
||||||
return iprec;
|
return iprec;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ICMP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
|
void ICMPAnalyzer::Echo(double t, const struct icmp* icmpp, int len,
|
||||||
{
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
return false;
|
ICMPSessionAdapter* adapter)
|
||||||
}
|
|
||||||
|
|
||||||
void ICMP_Analyzer::Describe(ODesc* d) const
|
|
||||||
{
|
|
||||||
d->Add(Conn()->StartTime());
|
|
||||||
d->Add("(");
|
|
||||||
d->Add(Conn()->LastTime());
|
|
||||||
d->AddSP(")");
|
|
||||||
|
|
||||||
d->Add(Conn()->OrigAddr());
|
|
||||||
d->Add(".");
|
|
||||||
d->Add(type);
|
|
||||||
d->Add(".");
|
|
||||||
d->Add(code);
|
|
||||||
|
|
||||||
d->SP();
|
|
||||||
d->AddSP("->");
|
|
||||||
|
|
||||||
d->Add(Conn()->RespAddr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val)
|
|
||||||
{
|
|
||||||
const auto& orig_endp = conn_val->GetField("orig");
|
|
||||||
const auto& resp_endp = conn_val->GetField("resp");
|
|
||||||
|
|
||||||
UpdateEndpointVal(orig_endp, true);
|
|
||||||
UpdateEndpointVal(resp_endp, false);
|
|
||||||
|
|
||||||
// Call children's UpdateConnVal
|
|
||||||
Analyzer::UpdateConnVal(conn_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICMP_Analyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig)
|
|
||||||
{
|
|
||||||
Conn()->EnableStatusUpdateTimer();
|
|
||||||
|
|
||||||
int size = is_orig ? request_len : reply_len;
|
|
||||||
auto endp = endp_arg->AsRecordVal();
|
|
||||||
|
|
||||||
if ( size < 0 )
|
|
||||||
{
|
|
||||||
endp->Assign(0, 0);
|
|
||||||
endp->Assign(1, ICMP_INACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
endp->Assign(0, size);
|
|
||||||
endp->Assign(1, ICMP_ACTIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ICMP_Analyzer::MemoryAllocation() const
|
|
||||||
{
|
|
||||||
return Analyzer::MemoryAllocation()
|
|
||||||
+ padded_sizeof(*this) - padded_sizeof(Connection)
|
|
||||||
+ (icmp_conn_val ? icmp_conn_val->MemoryAllocation() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::Echo(double t, const struct icmp* icmpp, int len,
|
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
|
||||||
{
|
{
|
||||||
// For handling all Echo related ICMP messages
|
// For handling all Echo related ICMP messages
|
||||||
EventHandlerPtr f = nullptr;
|
EventHandlerPtr f = nullptr;
|
||||||
|
@ -512,8 +466,8 @@ void ICMP_Analyzer::Echo(double t, const struct icmp* icmpp, int len,
|
||||||
|
|
||||||
String* payload = new String(data, caplen, false);
|
String* payload = new String(data, caplen, false);
|
||||||
|
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP, ip_hdr),
|
BuildInfo(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP, ip_hdr),
|
||||||
val_mgr->Count(iid),
|
val_mgr->Count(iid),
|
||||||
val_mgr->Count(iseq),
|
val_mgr->Count(iseq),
|
||||||
|
@ -522,8 +476,9 @@ void ICMP_Analyzer::Echo(double t, const struct icmp* icmpp, int len,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::RouterAdvert(double t, const struct icmp* icmpp, int len,
|
void ICMPAnalyzer::RouterAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = icmp_router_advertisement;
|
EventHandlerPtr f = icmp_router_advertisement;
|
||||||
|
|
||||||
|
@ -540,8 +495,8 @@ void ICMP_Analyzer::RouterAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
|
|
||||||
int opt_offset = sizeof(reachable) + sizeof(retrans);
|
int opt_offset = sizeof(reachable) + sizeof(retrans);
|
||||||
|
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 1, ip_hdr),
|
BuildInfo(icmpp, len, 1, ip_hdr),
|
||||||
val_mgr->Count(icmpp->icmp_num_addrs), // Cur Hop Limit
|
val_mgr->Count(icmpp->icmp_num_addrs), // Cur Hop Limit
|
||||||
val_mgr->Bool(icmpp->icmp_wpa & 0x80), // Managed
|
val_mgr->Bool(icmpp->icmp_wpa & 0x80), // Managed
|
||||||
|
@ -553,13 +508,14 @@ void ICMP_Analyzer::RouterAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
make_intrusive<IntervalVal>((double)ntohs(icmpp->icmp_lifetime), Seconds),
|
make_intrusive<IntervalVal>((double)ntohs(icmpp->icmp_lifetime), Seconds),
|
||||||
make_intrusive<IntervalVal>((double)ntohl(reachable), Milliseconds),
|
make_intrusive<IntervalVal>((double)ntohl(reachable), Milliseconds),
|
||||||
make_intrusive<IntervalVal>((double)ntohl(retrans), Milliseconds),
|
make_intrusive<IntervalVal>((double)ntohl(retrans), Milliseconds),
|
||||||
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset)
|
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
void ICMPAnalyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = icmp_neighbor_advertisement;
|
EventHandlerPtr f = icmp_neighbor_advertisement;
|
||||||
|
|
||||||
|
@ -573,20 +529,21 @@ void ICMP_Analyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
|
|
||||||
int opt_offset = sizeof(in6_addr);
|
int opt_offset = sizeof(in6_addr);
|
||||||
|
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 1, ip_hdr),
|
BuildInfo(icmpp, len, 1, ip_hdr),
|
||||||
val_mgr->Bool(icmpp->icmp_num_addrs & 0x80), // Router
|
val_mgr->Bool(icmpp->icmp_num_addrs & 0x80), // Router
|
||||||
val_mgr->Bool(icmpp->icmp_num_addrs & 0x40), // Solicited
|
val_mgr->Bool(icmpp->icmp_num_addrs & 0x40), // Solicited
|
||||||
val_mgr->Bool(icmpp->icmp_num_addrs & 0x20), // Override
|
val_mgr->Bool(icmpp->icmp_num_addrs & 0x20), // Override
|
||||||
make_intrusive<AddrVal>(tgtaddr),
|
make_intrusive<AddrVal>(tgtaddr),
|
||||||
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset)
|
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
void ICMPAnalyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = icmp_neighbor_solicitation;
|
EventHandlerPtr f = icmp_neighbor_solicitation;
|
||||||
|
|
||||||
|
@ -600,17 +557,18 @@ void ICMP_Analyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
|
|
||||||
int opt_offset = sizeof(in6_addr);
|
int opt_offset = sizeof(in6_addr);
|
||||||
|
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 1, ip_hdr),
|
BuildInfo(icmpp, len, 1, ip_hdr),
|
||||||
make_intrusive<AddrVal>(tgtaddr),
|
make_intrusive<AddrVal>(tgtaddr),
|
||||||
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset)
|
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::Redirect(double t, const struct icmp* icmpp, int len,
|
void ICMPAnalyzer::Redirect(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = icmp_redirect;
|
EventHandlerPtr f = icmp_redirect;
|
||||||
|
|
||||||
|
@ -627,34 +585,36 @@ void ICMP_Analyzer::Redirect(double t, const struct icmp* icmpp, int len,
|
||||||
|
|
||||||
int opt_offset = 2 * sizeof(in6_addr);
|
int opt_offset = 2 * sizeof(in6_addr);
|
||||||
|
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 1, ip_hdr),
|
BuildInfo(icmpp, len, 1, ip_hdr),
|
||||||
make_intrusive<AddrVal>(tgtaddr),
|
make_intrusive<AddrVal>(tgtaddr),
|
||||||
make_intrusive<AddrVal>(dstaddr),
|
make_intrusive<AddrVal>(dstaddr),
|
||||||
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset)
|
BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::RouterSolicit(double t, const struct icmp* icmpp, int len,
|
void ICMPAnalyzer::RouterSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = icmp_router_solicitation;
|
EventHandlerPtr f = icmp_router_solicitation;
|
||||||
|
|
||||||
if ( ! f )
|
if ( ! f )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 1, ip_hdr),
|
BuildInfo(icmpp, len, 1, ip_hdr),
|
||||||
BuildNDOptionsVal(caplen, data)
|
BuildNDOptionsVal(caplen, data, adapter)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::Context4(double t, const struct icmp* icmpp,
|
void ICMPAnalyzer::Context4(double t, const struct icmp* icmpp, int len,
|
||||||
int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = nullptr;
|
EventHandlerPtr f = nullptr;
|
||||||
|
|
||||||
|
@ -670,8 +630,8 @@ void ICMP_Analyzer::Context4(double t, const struct icmp* icmpp,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( f )
|
if ( f )
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 0, ip_hdr),
|
BuildInfo(icmpp, len, 0, ip_hdr),
|
||||||
val_mgr->Count(icmpp->icmp_code),
|
val_mgr->Count(icmpp->icmp_code),
|
||||||
ExtractICMP4Context(caplen, data)
|
ExtractICMP4Context(caplen, data)
|
||||||
|
@ -679,8 +639,9 @@ void ICMP_Analyzer::Context4(double t, const struct icmp* icmpp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Analyzer::Context6(double t, const struct icmp* icmpp,
|
void ICMPAnalyzer::Context6(double t, const struct icmp* icmpp, int len,
|
||||||
int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = nullptr;
|
EventHandlerPtr f = nullptr;
|
||||||
|
|
||||||
|
@ -708,20 +669,21 @@ void ICMP_Analyzer::Context6(double t, const struct icmp* icmpp,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( f )
|
if ( f )
|
||||||
EnqueueConnEvent(f,
|
adapter->EnqueueConnEvent(f,
|
||||||
ConnVal(),
|
adapter->ConnVal(),
|
||||||
BuildInfo(icmpp, len, 1, ip_hdr),
|
BuildInfo(icmpp, len, 1, ip_hdr),
|
||||||
val_mgr->Count(icmpp->icmp_code),
|
val_mgr->Count(icmpp->icmp_code),
|
||||||
ExtractICMP6Context(caplen, data)
|
ExtractICMP6Context(caplen, data)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* data,
|
||||||
|
ICMPSessionAdapter* adapter)
|
||||||
{
|
{
|
||||||
static auto icmp6_nd_option_type = id::find_type<RecordType>("icmp6_nd_option");
|
static auto icmp6_nd_option_type = id::find_type<RecordType>("icmp6_nd_option");
|
||||||
static auto icmp6_nd_prefix_info_type = id::find_type<RecordType>("icmp6_nd_prefix_info");
|
static auto icmp6_nd_prefix_info_type = id::find_type<RecordType>("icmp6_nd_prefix_info");
|
||||||
|
|
||||||
auto vv = make_intrusive<VectorVal>(
|
auto vv = make_intrusive<zeek::VectorVal>(
|
||||||
id::find_type<VectorType>("icmp6_nd_options"));
|
id::find_type<VectorType>("icmp6_nd_options"));
|
||||||
|
|
||||||
while ( caplen > 0 )
|
while ( caplen > 0 )
|
||||||
|
@ -729,7 +691,7 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
// Must have at least type & length to continue parsing options.
|
// Must have at least type & length to continue parsing options.
|
||||||
if ( caplen < 2 )
|
if ( caplen < 2 )
|
||||||
{
|
{
|
||||||
Weird("truncated_ICMPv6_ND_options");
|
adapter->Weird("truncated_ICMPv6_ND_options");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,13 +700,13 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
|
|
||||||
if ( length == 0 )
|
if ( length == 0 )
|
||||||
{
|
{
|
||||||
Weird("zero_length_ICMPv6_ND_option");
|
adapter->Weird("zero_length_ICMPv6_ND_option");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rv = make_intrusive<RecordVal>(icmp6_nd_option_type);
|
auto rv = make_intrusive<zeek::RecordVal>(icmp6_nd_option_type);
|
||||||
rv->Assign(0, type);
|
rv->Assign(0, val_mgr->Count(type));
|
||||||
rv->Assign(1, length);
|
rv->Assign(1, val_mgr->Count(length));
|
||||||
|
|
||||||
// Adjust length to be in units of bytes, exclude type/length fields.
|
// Adjust length to be in units of bytes, exclude type/length fields.
|
||||||
length = length * 8 - 2;
|
length = length * 8 - 2;
|
||||||
|
@ -763,7 +725,7 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
if ( caplen >= length )
|
if ( caplen >= length )
|
||||||
{
|
{
|
||||||
String* link_addr = new String(data, length, false);
|
String* link_addr = new String(data, length, false);
|
||||||
rv->Assign(2, link_addr);
|
rv->Assign(2, make_intrusive<StringVal>(link_addr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
set_payload_field = true;
|
set_payload_field = true;
|
||||||
|
@ -776,18 +738,18 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
{
|
{
|
||||||
if ( caplen >= 30 )
|
if ( caplen >= 30 )
|
||||||
{
|
{
|
||||||
auto info = make_intrusive<RecordVal>(icmp6_nd_prefix_info_type);
|
auto info = make_intrusive<zeek::RecordVal>(icmp6_nd_prefix_info_type);
|
||||||
uint8_t prefix_len = *((const uint8_t*)(data));
|
uint8_t prefix_len = *((const uint8_t*)(data));
|
||||||
bool L_flag = (*((const uint8_t*)(data + 1)) & 0x80) != 0;
|
bool L_flag = (*((const uint8_t*)(data + 1)) & 0x80) != 0;
|
||||||
bool A_flag = (*((const uint8_t*)(data + 1)) & 0x40) != 0;
|
bool A_flag = (*((const uint8_t*)(data + 1)) & 0x40) != 0;
|
||||||
uint32_t valid_life = *((const uint32_t*)(data + 2));
|
uint32_t valid_life = *((const uint32_t*)(data + 2));
|
||||||
uint32_t prefer_life = *((const uint32_t*)(data + 6));
|
uint32_t prefer_life = *((const uint32_t*)(data + 6));
|
||||||
in6_addr prefix = *((const in6_addr*)(data + 14));
|
in6_addr prefix = *((const in6_addr*)(data + 14));
|
||||||
info->Assign(0, prefix_len);
|
info->Assign(0, val_mgr->Count(prefix_len));
|
||||||
info->Assign(1, L_flag);
|
info->Assign(1, val_mgr->Bool(L_flag));
|
||||||
info->Assign(2, A_flag);
|
info->Assign(2, val_mgr->Bool(A_flag));
|
||||||
info->AssignInterval(3, double(ntohl(valid_life)));
|
info->Assign(3, make_intrusive<IntervalVal>((double)ntohl(valid_life), Seconds));
|
||||||
info->AssignInterval(4, double(ntohl(prefer_life)));
|
info->Assign(4, make_intrusive<IntervalVal>((double)ntohl(prefer_life), Seconds));
|
||||||
info->Assign(5, make_intrusive<AddrVal>(IPAddr(prefix)));
|
info->Assign(5, make_intrusive<AddrVal>(IPAddr(prefix)));
|
||||||
rv->Assign(3, std::move(info));
|
rv->Assign(3, std::move(info));
|
||||||
}
|
}
|
||||||
|
@ -816,7 +778,7 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
// MTU option
|
// MTU option
|
||||||
{
|
{
|
||||||
if ( caplen >= 6 )
|
if ( caplen >= 6 )
|
||||||
rv->Assign(5, ntohl(*((const uint32_t*)(data + 2))));
|
rv->Assign(5, val_mgr->Count(ntohl(*((const uint32_t*)(data + 2)))));
|
||||||
else
|
else
|
||||||
set_payload_field = true;
|
set_payload_field = true;
|
||||||
|
|
||||||
|
@ -833,7 +795,7 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
if ( set_payload_field )
|
if ( set_payload_field )
|
||||||
{
|
{
|
||||||
String* payload = new String(data, std::min((int)length, caplen), false);
|
String* payload = new String(data, std::min((int)length, caplen), false);
|
||||||
rv->Assign(6, payload);
|
rv->Assign(6, make_intrusive<StringVal>(payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
data += length;
|
data += length;
|
||||||
|
@ -845,7 +807,7 @@ VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data)
|
||||||
return vv;
|
return vv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
int ICMPAnalyzer::ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||||
{
|
{
|
||||||
is_one_way = false;
|
is_one_way = false;
|
||||||
|
|
||||||
|
@ -873,7 +835,7 @@ int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
int ICMPAnalyzer::ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||||
{
|
{
|
||||||
is_one_way = false;
|
is_one_way = false;
|
||||||
|
|
||||||
|
@ -905,4 +867,72 @@ int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace zeek::analyzer::icmp
|
void ICMPSessionAdapter::AddExtraAnalyzers(Connection* conn)
|
||||||
|
{
|
||||||
|
static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE");
|
||||||
|
|
||||||
|
if ( analyzer_mgr->IsEnabled(analyzer_connsize) )
|
||||||
|
// Add ConnSize analyzer. Needs to see packets, not stream.
|
||||||
|
AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPSessionAdapter::UpdateConnVal(zeek::RecordVal* conn_val)
|
||||||
|
{
|
||||||
|
const auto& orig_endp = conn_val->GetField("orig");
|
||||||
|
const auto& resp_endp = conn_val->GetField("resp");
|
||||||
|
|
||||||
|
UpdateEndpointVal(orig_endp, true);
|
||||||
|
UpdateEndpointVal(resp_endp, false);
|
||||||
|
|
||||||
|
analyzer::Analyzer::UpdateConnVal(conn_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig)
|
||||||
|
{
|
||||||
|
Conn()->EnableStatusUpdateTimer();
|
||||||
|
|
||||||
|
int size = is_orig ? request_len : reply_len;
|
||||||
|
auto endp = endp_arg->AsRecordVal();
|
||||||
|
|
||||||
|
if ( size < 0 )
|
||||||
|
{
|
||||||
|
endp->Assign(0, val_mgr->Count(0));
|
||||||
|
endp->Assign(1, val_mgr->Count(int(ICMP_INACTIVE)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endp->Assign(0, val_mgr->Count(size));
|
||||||
|
endp->Assign(1, val_mgr->Count(int(ICMP_ACTIVE)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPSessionAdapter::UpdateLength(bool is_orig, int len)
|
||||||
|
{
|
||||||
|
int& len_stat = is_orig ? request_len : reply_len;
|
||||||
|
if ( len_stat < 0 )
|
||||||
|
len_stat = len;
|
||||||
|
else
|
||||||
|
len_stat += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPSessionAdapter::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig)
|
||||||
|
{
|
||||||
|
if ( zeek::detail::rule_matcher )
|
||||||
|
{
|
||||||
|
if ( ! matcher_state.MatcherInitialized(is_orig) )
|
||||||
|
matcher_state.InitEndpointMatcher(this, ip_hdr, len, is_orig, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPSessionAdapter::MatchEndpoint(const u_char* data, int len, bool is_orig)
|
||||||
|
{
|
||||||
|
if ( zeek::detail::rule_matcher )
|
||||||
|
matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig,
|
||||||
|
false, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMPSessionAdapter::Done()
|
||||||
|
{
|
||||||
|
SessionAdapter::Done();
|
||||||
|
matcher_state.FinishEndpointMatcher();
|
||||||
|
}
|
138
src/packet_analysis/protocol/icmp/ICMP.h
Normal file
138
src/packet_analysis/protocol/icmp/ICMP.h
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/Analyzer.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||||
|
#include "zeek/analyzer/Analyzer.h"
|
||||||
|
#include "zeek/RuleMatcher.h"
|
||||||
|
|
||||||
|
namespace zeek {
|
||||||
|
|
||||||
|
class VectorVal;
|
||||||
|
using VectorValPtr = IntrusivePtr<VectorVal>;
|
||||||
|
class RecordVal;
|
||||||
|
using RecordValPtr = IntrusivePtr<RecordVal>;
|
||||||
|
|
||||||
|
namespace packet_analysis::ICMP {
|
||||||
|
|
||||||
|
class ICMPSessionAdapter;
|
||||||
|
|
||||||
|
class ICMPAnalyzer final : public IP::IPBasedAnalyzer {
|
||||||
|
public:
|
||||||
|
ICMPAnalyzer();
|
||||||
|
~ICMPAnalyzer() override;
|
||||||
|
|
||||||
|
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
||||||
|
{
|
||||||
|
return std::make_shared<ICMPAnalyzer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_analysis::IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the header from the packet into a ConnTuple object.
|
||||||
|
*/
|
||||||
|
bool BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
|
ConnTuple& tuple) override;
|
||||||
|
|
||||||
|
void DeliverPacket(Connection* c, double t, bool is_orig, int remaining,
|
||||||
|
Packet* pkt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
void ICMP_Sent(const struct icmp* icmpp, int len, int caplen, int icmpv6,
|
||||||
|
const u_char* data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
void Echo(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
void Redirect(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
void RouterAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
void NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
void NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
void RouterSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
RecordValPtr BuildInfo(const struct icmp* icmpp, int len,
|
||||||
|
bool icmpv6, const IP_Hdr* ip_hdr);
|
||||||
|
|
||||||
|
RecordValPtr ExtractICMP4Context(int len, const u_char*& data);
|
||||||
|
|
||||||
|
void Context4(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port,
|
||||||
|
uint32_t* dst_port);
|
||||||
|
|
||||||
|
RecordValPtr ExtractICMP6Context(int len, const u_char*& data);
|
||||||
|
|
||||||
|
void Context6(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
// RFC 4861 Neighbor Discover message options
|
||||||
|
VectorValPtr BuildNDOptionsVal(int caplen, const u_char* data,
|
||||||
|
ICMPSessionAdapter* adapter);
|
||||||
|
|
||||||
|
void UpdateEndpointVal(const ValPtr& endp, bool is_orig);
|
||||||
|
|
||||||
|
// Returns the counterpart type to the given type (e.g., the counterpart
|
||||||
|
// to ICMP_ECHOREPLY is ICMP_ECHO).
|
||||||
|
int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
||||||
|
int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ICMPSessionAdapter final : public IP::SessionAdapter {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ICMPSessionAdapter(Connection* conn) :
|
||||||
|
IP::SessionAdapter("ICMP", conn) { }
|
||||||
|
|
||||||
|
static zeek::analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
|
{
|
||||||
|
return new ICMPSessionAdapter(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddExtraAnalyzers(Connection* conn) override;
|
||||||
|
void UpdateConnVal(RecordVal* conn_val) override;
|
||||||
|
void UpdateEndpointVal(const ValPtr& endp, bool is_orig);
|
||||||
|
|
||||||
|
void UpdateLength(bool is_orig, int len);
|
||||||
|
void Done() override;
|
||||||
|
|
||||||
|
void InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig);
|
||||||
|
void MatchEndpoint(const u_char* data, int len, bool is_orig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
detail::RuleMatcherState matcher_state;
|
||||||
|
int request_len = -1;
|
||||||
|
int reply_len = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace packet_analysis::ICMP
|
||||||
|
} // namespace zeek
|
26
src/packet_analysis/protocol/icmp/Plugin.cc
Normal file
26
src/packet_analysis/protocol/icmp/Plugin.cc
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/plugin/Plugin.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/icmp/ICMP.h"
|
||||||
|
|
||||||
|
namespace zeek::plugin::Zeek_ICMP {
|
||||||
|
|
||||||
|
class Plugin : public zeek::plugin::Plugin {
|
||||||
|
public:
|
||||||
|
zeek::plugin::Configuration Configure()
|
||||||
|
{
|
||||||
|
AddComponent(new zeek::packet_analysis::Component("ICMP",
|
||||||
|
zeek::packet_analysis::ICMP::ICMPAnalyzer::Instantiate));
|
||||||
|
AddComponent(new zeek::analyzer::Component("ICMP",
|
||||||
|
zeek::packet_analysis::ICMP::ICMPSessionAdapter::Instantiate));
|
||||||
|
|
||||||
|
zeek::plugin::Configuration config;
|
||||||
|
config.name = "Zeek::ICMP";
|
||||||
|
config.description = "Packet analyzer for ICMP";
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
} plugin;
|
||||||
|
|
||||||
|
}
|
|
@ -4,5 +4,5 @@ include(ZeekPlugin)
|
||||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
zeek_plugin_begin(PacketAnalyzer IP)
|
zeek_plugin_begin(PacketAnalyzer IP)
|
||||||
zeek_plugin_cc(IP.cc Plugin.cc)
|
zeek_plugin_cc(IP.cc IPBasedAnalyzer.cc SessionAdapter.cc Plugin.cc)
|
||||||
zeek_plugin_end()
|
zeek_plugin_end()
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "zeek/Frag.h"
|
#include "zeek/Frag.h"
|
||||||
#include "zeek/Event.h"
|
#include "zeek/Event.h"
|
||||||
#include "zeek/TunnelEncapsulation.h"
|
#include "zeek/TunnelEncapsulation.h"
|
||||||
|
#include "zeek/IPAddr.h"
|
||||||
|
|
||||||
using namespace zeek::packet_analysis::IP;
|
using namespace zeek::packet_analysis::IP;
|
||||||
|
|
||||||
|
@ -235,14 +236,6 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
packet->proto = proto;
|
packet->proto = proto;
|
||||||
|
|
||||||
switch ( proto ) {
|
switch ( proto ) {
|
||||||
case IPPROTO_TCP:
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
case IPPROTO_ICMP:
|
|
||||||
case IPPROTO_ICMPV6:
|
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
|
||||||
GetAnalyzerName(), proto);
|
|
||||||
session_mgr->ProcessTransportLayer(run_state::processing_start_time, packet, len);
|
|
||||||
break;
|
|
||||||
case IPPROTO_NONE:
|
case IPPROTO_NONE:
|
||||||
// If the packet is encapsulated in Teredo, then it was a bubble and
|
// If the packet is encapsulated in Teredo, then it was a bubble and
|
||||||
// the Teredo analyzer may have raised an event for that, else we're
|
// the Teredo analyzer may have raised an event for that, else we're
|
||||||
|
@ -268,3 +261,40 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zeek::packet_analysis::IP::ParsePacket(int caplen, const u_char* const pkt, int proto,
|
||||||
|
std::unique_ptr<zeek::IP_Hdr>& inner)
|
||||||
|
{
|
||||||
|
if ( proto == IPPROTO_IPV6 )
|
||||||
|
{
|
||||||
|
if ( caplen < (int)sizeof(struct ip6_hdr) )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const struct ip6_hdr* ip6 = (const struct ip6_hdr*) pkt;
|
||||||
|
inner = std::make_unique<zeek::IP_Hdr>(ip6, false, caplen);
|
||||||
|
if ( ( ip6->ip6_ctlun.ip6_un2_vfc & 0xF0 ) != 0x60 )
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( proto == IPPROTO_IPV4 )
|
||||||
|
{
|
||||||
|
if ( caplen < (int)sizeof(struct ip) )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const struct ip* ip4 = (const struct ip*) pkt;
|
||||||
|
inner = std::make_unique<zeek::IP_Hdr>(ip4, false);
|
||||||
|
if ( ip4->ip_v != 4 )
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zeek::reporter->InternalWarning("Bad IP protocol version in IP::ParsePacket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (uint32_t)caplen != inner->TotalLen() )
|
||||||
|
return (uint32_t)caplen < inner->TotalLen() ? -1 : 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -32,4 +32,28 @@ private:
|
||||||
zeek::detail::Discarder* discarder = nullptr;
|
zeek::detail::Discarder* discarder = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
|
||||||
|
* or IPv6 header based on whether it's long enough to contain such a header,
|
||||||
|
* if version given in the header matches the proto argument, and also checks
|
||||||
|
* that the payload length field of that header matches the actual
|
||||||
|
* length of \a pkt given by \a caplen.
|
||||||
|
*
|
||||||
|
* @param caplen The length of \a pkt in bytes.
|
||||||
|
* @param pkt The inner IP packet data.
|
||||||
|
* @param proto Either IPPROTO_IPV6 or IPPROTO_IPV4 to indicate which IP
|
||||||
|
* protocol \a pkt corresponds to.
|
||||||
|
* @param inner The inner IP packet wrapper pointer to be allocated/assigned
|
||||||
|
* if \a pkt looks like a valid IP packet or at least long enough
|
||||||
|
* to hold an IP header.
|
||||||
|
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
|
||||||
|
* is greater than the supposed IP packet's payload length field, -2
|
||||||
|
* if the version of the inner header does not match proto or
|
||||||
|
* 1 if \a caplen is less than the supposed packet's payload length.
|
||||||
|
* In the -1 case, \a inner may still be non-null if \a caplen was
|
||||||
|
* long enough to be an IP header, and \a inner is always non-null
|
||||||
|
* for other return values.
|
||||||
|
*/
|
||||||
|
int ParsePacket(int caplen, const u_char* const pkt, int proto,
|
||||||
|
std::unique_ptr<IP_Hdr>& inner);
|
||||||
}
|
}
|
||||||
|
|
273
src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc
Normal file
273
src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||||
|
|
||||||
|
#include "zeek/RunState.h"
|
||||||
|
#include "zeek/Conn.h"
|
||||||
|
#include "zeek/Val.h"
|
||||||
|
#include "zeek/session/Manager.h"
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
#include "zeek/analyzer/protocol/pia/PIA.h"
|
||||||
|
#include "zeek/plugin/Manager.h"
|
||||||
|
|
||||||
|
using namespace zeek;
|
||||||
|
using namespace zeek::packet_analysis::IP;
|
||||||
|
|
||||||
|
IPBasedAnalyzer::IPBasedAnalyzer(const char* name, TransportProto proto, uint32_t mask,
|
||||||
|
bool report_unknown_protocols)
|
||||||
|
: zeek::packet_analysis::Analyzer(name, report_unknown_protocols),
|
||||||
|
transport(proto), server_port_mask(mask)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IPBasedAnalyzer::~IPBasedAnalyzer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPBasedAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pkt)
|
||||||
|
{
|
||||||
|
ConnTuple tuple;
|
||||||
|
if ( ! BuildConnTuple(len, data, pkt, tuple) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const std::unique_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
|
||||||
|
detail::ConnKey key(tuple);
|
||||||
|
|
||||||
|
Connection* conn = session_mgr->FindConnection(key);
|
||||||
|
|
||||||
|
if ( ! conn )
|
||||||
|
{
|
||||||
|
conn = NewConn(&tuple, key, pkt);
|
||||||
|
if ( conn )
|
||||||
|
session_mgr->Insert(conn, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( conn->IsReuse(run_state::processing_start_time, ip_hdr->Payload()) )
|
||||||
|
{
|
||||||
|
conn->Event(connection_reused, nullptr);
|
||||||
|
|
||||||
|
session_mgr->Remove(conn);
|
||||||
|
conn = NewConn(&tuple, key, pkt);
|
||||||
|
if ( conn )
|
||||||
|
session_mgr->Insert(conn, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conn->CheckEncapsulation(pkt->encap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! conn )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool is_orig = (tuple.src_addr == conn->OrigAddr()) &&
|
||||||
|
(tuple.src_port == conn->OrigPort());
|
||||||
|
|
||||||
|
conn->CheckFlowLabel(is_orig, ip_hdr->FlowLabel());
|
||||||
|
|
||||||
|
zeek::ValPtr pkt_hdr_val;
|
||||||
|
|
||||||
|
if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 )
|
||||||
|
{
|
||||||
|
pkt_hdr_val = ip_hdr->ToPktHdrVal();
|
||||||
|
conn->EnqueueEvent(ipv6_ext_headers, nullptr, conn->GetVal(),
|
||||||
|
pkt_hdr_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( new_packet )
|
||||||
|
conn->EnqueueEvent(new_packet, nullptr, conn->GetVal(),
|
||||||
|
pkt_hdr_val ? std::move(pkt_hdr_val) : ip_hdr->ToPktHdrVal());
|
||||||
|
|
||||||
|
if ( new_plugin )
|
||||||
|
{
|
||||||
|
conn->SetRecordPackets(true);
|
||||||
|
conn->SetRecordContents(true);
|
||||||
|
|
||||||
|
const u_char* data = pkt->ip_hdr->Payload();
|
||||||
|
|
||||||
|
run_state::current_timestamp = run_state::processing_start_time;
|
||||||
|
run_state::current_pkt = pkt;
|
||||||
|
|
||||||
|
// TODO: Does this actually mean anything?
|
||||||
|
if ( conn->Skipping() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
DeliverPacket(conn, run_state::processing_start_time, is_orig, len, pkt);
|
||||||
|
|
||||||
|
run_state::current_timestamp = 0;
|
||||||
|
run_state::current_pkt = nullptr;
|
||||||
|
|
||||||
|
// If the packet is reassembled, disable packet dumping because the
|
||||||
|
// pointer math to dump the data wouldn't work.
|
||||||
|
if ( pkt->ip_hdr->reassembled )
|
||||||
|
pkt->dump_packet = false;
|
||||||
|
else if ( conn->RecordPackets() )
|
||||||
|
{
|
||||||
|
pkt->dump_packet = true;
|
||||||
|
|
||||||
|
// If we don't want the content, set the dump size to include just
|
||||||
|
// the header.
|
||||||
|
if ( ! conn->RecordContents() )
|
||||||
|
pkt->dump_size = data - pkt->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int record_packet = 1; // whether to record the packet at all
|
||||||
|
int record_content = 1; // whether to record its data
|
||||||
|
|
||||||
|
const u_char* data = pkt->ip_hdr->Payload();
|
||||||
|
|
||||||
|
conn->NextPacket(run_state::processing_start_time, is_orig, ip_hdr.get(), ip_hdr->PayloadLen(),
|
||||||
|
len, data, record_packet, record_content, pkt);
|
||||||
|
|
||||||
|
// If the packet is reassembled, disable packet dumping because the
|
||||||
|
// pointer math to dump the data wouldn't work.
|
||||||
|
if ( ip_hdr->reassembled )
|
||||||
|
pkt->dump_packet = false;
|
||||||
|
else if ( record_packet )
|
||||||
|
{
|
||||||
|
pkt->dump_packet = true;
|
||||||
|
|
||||||
|
// If we don't want the content, set the dump size to include just
|
||||||
|
// the header.
|
||||||
|
if ( ! record_content )
|
||||||
|
pkt->dump_size = data - pkt->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPBasedAnalyzer::CheckHeaderTrunc(size_t min_hdr_len, size_t remaining, Packet* packet)
|
||||||
|
{
|
||||||
|
if ( packet->ip_hdr->PayloadLen() < min_hdr_len )
|
||||||
|
{
|
||||||
|
Weird("truncated_header", packet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ( remaining < min_hdr_len )
|
||||||
|
{
|
||||||
|
Weird("internally_truncated_header", packet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPBasedAnalyzer::IsLikelyServerPort(uint32_t port) const
|
||||||
|
{
|
||||||
|
// We keep a cached in-core version of the table to speed up the lookup.
|
||||||
|
static std::set<bro_uint_t> port_cache;
|
||||||
|
static bool have_cache = false;
|
||||||
|
|
||||||
|
if ( ! have_cache )
|
||||||
|
{
|
||||||
|
auto likely_server_ports = id::find_val<TableVal>("likely_server_ports");
|
||||||
|
auto lv = likely_server_ports->ToPureListVal();
|
||||||
|
for ( int i = 0; i < lv->Length(); i++ )
|
||||||
|
port_cache.insert(lv->Idx(i)->InternalUnsigned());
|
||||||
|
have_cache = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We exploit our knowledge of PortVal's internal storage mechanism here.
|
||||||
|
port |= server_port_mask;
|
||||||
|
|
||||||
|
return port_cache.find(port) != port_cache.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::Connection* IPBasedAnalyzer::NewConn(const ConnTuple* id, const detail::ConnKey& key,
|
||||||
|
const Packet* pkt)
|
||||||
|
{
|
||||||
|
int src_h = ntohs(id->src_port);
|
||||||
|
int dst_h = ntohs(id->dst_port);
|
||||||
|
bool flip = false;
|
||||||
|
|
||||||
|
if ( ! WantConnection(src_h, dst_h, pkt->ip_hdr->Payload(), flip) )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Connection* conn = new Connection(key, run_state::processing_start_time,
|
||||||
|
id, pkt->ip_hdr->FlowLabel(), pkt);
|
||||||
|
conn->SetTransport(transport);
|
||||||
|
|
||||||
|
if ( flip )
|
||||||
|
conn->FlipRoles();
|
||||||
|
|
||||||
|
if ( ! new_plugin )
|
||||||
|
{
|
||||||
|
if ( ! analyzer_mgr->BuildInitialAnalyzerTree(conn) )
|
||||||
|
{
|
||||||
|
conn->Done();
|
||||||
|
Unref(conn);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( ! BuildSessionAnalyzerTree(conn) )
|
||||||
|
{
|
||||||
|
conn->Done();
|
||||||
|
Unref(conn);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( new_connection )
|
||||||
|
conn->Event(new_connection, nullptr);
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn)
|
||||||
|
{
|
||||||
|
SessionAdapter* root = MakeSessionAdapter(conn);
|
||||||
|
analyzer::pia::PIA* pia = MakePIA(conn);
|
||||||
|
|
||||||
|
// TODO: temporary, can be replaced when the port lookup stuff is moved from analyzer_mgr
|
||||||
|
bool check_port = conn->ConnTransport() != TRANSPORT_ICMP;
|
||||||
|
|
||||||
|
bool scheduled = analyzer_mgr->ApplyScheduledAnalyzers(conn, false, root);
|
||||||
|
|
||||||
|
// Hmm... Do we want *just* the expected analyzer, or all
|
||||||
|
// other potential analyzers as well? For now we only take
|
||||||
|
// the scheduled ones.
|
||||||
|
if ( ! scheduled )
|
||||||
|
{ // Let's see if it's a port we know.
|
||||||
|
if ( check_port && ! zeek::detail::dpd_ignore_ports )
|
||||||
|
{
|
||||||
|
// TODO: ideally this lookup would be local to the packet analyzer instead of
|
||||||
|
// calling out to the analyzer manager. This code can move once the TCP work
|
||||||
|
// is in progress so that it doesn't have to be done piecemeal.
|
||||||
|
//
|
||||||
|
int resp_port = ntohs(conn->RespPort());
|
||||||
|
std::set<analyzer::Tag>* ports = analyzer_mgr->LookupPort(conn->ConnTransport(), resp_port, false);
|
||||||
|
|
||||||
|
if ( ports )
|
||||||
|
{
|
||||||
|
for ( const auto& port : *ports )
|
||||||
|
{
|
||||||
|
analyzer::Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(port, conn);
|
||||||
|
|
||||||
|
if ( ! analyzer )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
root->AddChildAnalyzer(analyzer, false);
|
||||||
|
DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d",
|
||||||
|
analyzer_mgr->GetComponentName(port).c_str(), resp_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root->AddExtraAnalyzers(conn);
|
||||||
|
|
||||||
|
if ( pia )
|
||||||
|
root->AddChildAnalyzer(pia->AsAnalyzer());
|
||||||
|
|
||||||
|
conn->SetSessionAdapter(root, pia);
|
||||||
|
root->Init();
|
||||||
|
root->InitChildren();
|
||||||
|
|
||||||
|
PLUGIN_HOOK_VOID(HOOK_SETUP_ANALYZER_TREE, HookSetupAnalyzerTree(conn));
|
||||||
|
|
||||||
|
// TODO: temporary
|
||||||
|
return true;
|
||||||
|
}
|
149
src/packet_analysis/protocol/ip/IPBasedAnalyzer.h
Normal file
149
src/packet_analysis/protocol/ip/IPBasedAnalyzer.h
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/Analyzer.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
|
||||||
|
#include "zeek/analyzer/Analyzer.h"
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
|
||||||
|
namespace zeek::analyzer::pia { class PIA; }
|
||||||
|
|
||||||
|
namespace zeek::packet_analysis::IP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base class for reuse by packet analyzers based on IP. This is used by default
|
||||||
|
* by the TCP, UDP, and ICMP analyzers to reduce a large amount of duplicated code
|
||||||
|
* that those plugins have in common.
|
||||||
|
*/
|
||||||
|
class IPBasedAnalyzer : public Analyzer {
|
||||||
|
public:
|
||||||
|
~IPBasedAnalyzer() override;
|
||||||
|
|
||||||
|
bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the analyzer determines that in fact a new
|
||||||
|
* connection has started without the connection statement having
|
||||||
|
* terminated the previous one, i.e., the new data is arriving at
|
||||||
|
* what's the analyzer for the previous instance. This is used only
|
||||||
|
* for TCP.
|
||||||
|
*/
|
||||||
|
virtual bool IsReuse(double t, const u_char* pkt) { return false; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new IP-based analyzer.
|
||||||
|
*
|
||||||
|
* @param name The name for the type of analyzer. The name must match
|
||||||
|
* the one the corresponding Component registers.
|
||||||
|
* @param proto The transport protocol implemented by this analyzer.
|
||||||
|
* @param mask The mask used to determine if a port is a server port
|
||||||
|
* for this protocol. This is used by IsLikelyServerPort().
|
||||||
|
* @param report_unknown_protocols Flag for whether to report unknown
|
||||||
|
* protocols during packet forwarding. This is typically false for IP
|
||||||
|
* protocols since packets may go into the session analysis framework
|
||||||
|
* as well.
|
||||||
|
*/
|
||||||
|
IPBasedAnalyzer(const char* name, TransportProto proto, uint32_t mask,
|
||||||
|
bool report_unknown_protocols);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the header from the packet into a ConnTuple object.
|
||||||
|
*/
|
||||||
|
virtual bool BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
|
ConnTuple& tuple) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Continues process of packet after the connection has been inserted into the
|
||||||
|
* session manager. This should be implemented by all child classes.
|
||||||
|
*
|
||||||
|
* @param conn The connection currently being processed.
|
||||||
|
* @param t The timestamp for the current packet.
|
||||||
|
* @param is_orig Flag denoting whether this packet is from the originator of
|
||||||
|
* the connection.
|
||||||
|
* @param remaining The remaining about of data in the packet.
|
||||||
|
* @param pkt The packet being processed.
|
||||||
|
*/
|
||||||
|
virtual void DeliverPacket(Connection* conn, double t, bool is_orig, int remaining,
|
||||||
|
Packet* pkt) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upon seeing the first packet of a connection, checks whether we want
|
||||||
|
* to analyze it (e.g. we may not want to look at partial connections)
|
||||||
|
* and, if yes, whether we should flip the roles of originator and
|
||||||
|
* responder based on known ports and such.
|
||||||
|
*
|
||||||
|
* @param src_port The source port of the connection.
|
||||||
|
* @param dst_port The destination port of the connection.
|
||||||
|
* @param data The payload data for the packet being processed.
|
||||||
|
* @param flip_roles Return value if the roles should be flipped.
|
||||||
|
* @return True if the connection is wanted. False otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool WantConnection(uint16_t src_port, uint16_t dst_port,
|
||||||
|
const u_char* data, bool& flip_roles) const
|
||||||
|
{
|
||||||
|
flip_roles = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an analyzer adapter appropriate for this IP-based analyzer. This adapter
|
||||||
|
* is used to hook into the session analyzer framework. This function can also be used
|
||||||
|
* to do any extra initialization of connection timers, etc.
|
||||||
|
*/
|
||||||
|
virtual SessionAdapter* MakeSessionAdapter(Connection* conn) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a PIA appropriate for this IP-based analyzer. This method is optional to
|
||||||
|
* override in child classes, as not all analyzers need a PIA.
|
||||||
|
*/
|
||||||
|
virtual analyzer::pia::PIA* MakePIA(Connection* conn) { return nullptr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that there is enough data in the packet to process the header
|
||||||
|
* length requested.
|
||||||
|
*
|
||||||
|
* @param min_hdr_len The minimum data in bytes that needs to exist.
|
||||||
|
* @param remaining The remaining number of bytes in the packet reported by
|
||||||
|
* previous analyzer.
|
||||||
|
* @param packet The packet being processed. This will be used to pull out the
|
||||||
|
* number of bytes the IP header says we have remaining.
|
||||||
|
*/
|
||||||
|
bool CheckHeaderTrunc(size_t min_hdr_len, size_t remaining, Packet* packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the port corresponds to an application for which there
|
||||||
|
* is a Zeek analyzer (even if it might not be used by the present policy
|
||||||
|
* script) or if it's generally a likely server port.
|
||||||
|
*
|
||||||
|
* @param port The port number to check, in host order.
|
||||||
|
*/
|
||||||
|
bool IsLikelyServerPort(uint32_t port) const;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: temporary, until all of the plugins are implemented
|
||||||
|
bool new_plugin = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Connection object from data gleaned from the current packet.
|
||||||
|
*
|
||||||
|
* @param id A connection ID generated from the packet data. This should have been
|
||||||
|
* passed in from a child analyzer.
|
||||||
|
* @param key A connection ID key generated from the ID.
|
||||||
|
* @param pkt The packet associated with the new connection.
|
||||||
|
*/
|
||||||
|
zeek::Connection* NewConn(const ConnTuple* id, const detail::ConnKey& key,
|
||||||
|
const Packet* pkt);
|
||||||
|
|
||||||
|
bool BuildSessionAnalyzerTree(Connection* conn);
|
||||||
|
|
||||||
|
TransportProto transport;
|
||||||
|
uint32_t server_port_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
39
src/packet_analysis/protocol/ip/SessionAdapter.cc
Normal file
39
src/packet_analysis/protocol/ip/SessionAdapter.cc
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
|
||||||
|
|
||||||
|
#include "zeek/File.h"
|
||||||
|
#include "zeek/ZeekString.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||||
|
|
||||||
|
using namespace zeek::packet_analysis::IP;
|
||||||
|
|
||||||
|
void SessionAdapter::Done()
|
||||||
|
{
|
||||||
|
Analyzer::Done();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SessionAdapter::IsReuse(double t, const u_char* pkt)
|
||||||
|
{
|
||||||
|
return parent->IsReuse(t, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionAdapter::SetContentsFile(unsigned int /* direction */,
|
||||||
|
FilePtr /* f */)
|
||||||
|
{
|
||||||
|
reporter->Error("analyzer type does not support writing to a contents file");
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::FilePtr SessionAdapter::GetContentsFile(unsigned int /* direction */) const
|
||||||
|
{
|
||||||
|
reporter->Error("analyzer type does not support writing to a contents file");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionAdapter::PacketContents(const u_char* data, int len)
|
||||||
|
{
|
||||||
|
if ( packet_contents && len > 0 )
|
||||||
|
{
|
||||||
|
zeek::String* cbs = new zeek::String(data, len, true);
|
||||||
|
auto contents = make_intrusive<StringVal>(cbs);
|
||||||
|
EnqueueConnEvent(packet_contents, ConnVal(), std::move(contents));
|
||||||
|
}
|
||||||
|
}
|
102
src/packet_analysis/protocol/ip/SessionAdapter.h
Normal file
102
src/packet_analysis/protocol/ip/SessionAdapter.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "zeek/analyzer/Analyzer.h"
|
||||||
|
|
||||||
|
namespace zeek::analyzer::pia { class PIA; }
|
||||||
|
|
||||||
|
namespace zeek::packet_analysis::IP {
|
||||||
|
|
||||||
|
class IPBasedAnalyzer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the interface between the packet analysis framework and
|
||||||
|
* the session analysis framework. One of these should be implemented for each
|
||||||
|
* packet analyzer that intends to forward into the session analysis.
|
||||||
|
*/
|
||||||
|
class SessionAdapter : public analyzer::Analyzer {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SessionAdapter(const char* name, Connection* conn)
|
||||||
|
: analyzer::Analyzer(name, conn) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden from parent class.
|
||||||
|
*/
|
||||||
|
virtual void Done() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the parent packet analyzer for this session adapter. This can't be passed to
|
||||||
|
* the constructor due to the way that SessionAdapter gets instantiated.
|
||||||
|
*
|
||||||
|
* @param p The parent packet analyzer to store
|
||||||
|
*/
|
||||||
|
void SetParent(IPBasedAnalyzer* p) { parent = p; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the analyzer determines that in fact a new connection has started
|
||||||
|
* without the connection statement having terminated the previous one, i.e., the new
|
||||||
|
* data is arriving at what's the analyzer for the previous instance. This is used only
|
||||||
|
* for TCP.
|
||||||
|
*/
|
||||||
|
virtual bool IsReuse(double t, const u_char* pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pure virtual method to allow extra session analzyers to be added to this analyzer's
|
||||||
|
* tree of children. This is used by analyzer::Manager when creating the session analyzer
|
||||||
|
* tree.
|
||||||
|
*/
|
||||||
|
virtual void AddExtraAnalyzers(Connection* conn) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates a file with the analyzer in which to record all
|
||||||
|
* analyzed input. This must only be called with derived classes that
|
||||||
|
* overide the method; the default implementation will abort.
|
||||||
|
*
|
||||||
|
* @param direction One of the CONTENTS_* constants indicating which
|
||||||
|
* direction of the input stream is to be recorded.
|
||||||
|
*
|
||||||
|
* @param f The file to record to.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void SetContentsFile(unsigned int direction, FilePtr f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an associated contents file, if any. This must only be
|
||||||
|
* called with derived classes that overide the method; the default
|
||||||
|
* implementation will abort.
|
||||||
|
*
|
||||||
|
* @param direction One of the CONTENTS_* constants indicating which
|
||||||
|
* direction the query is for.
|
||||||
|
*/
|
||||||
|
virtual FilePtr GetContentsFile(unsigned int direction) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates a PIA with this analyzer. A PIA takes the
|
||||||
|
* transport-layer input and determine which protocol analyzer(s) to
|
||||||
|
* use for parsing it.
|
||||||
|
*/
|
||||||
|
void SetPIA(analyzer::pia::PIA* arg_PIA) { pia = arg_PIA; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the associated PIA, or null of none. Does not take
|
||||||
|
* ownership.
|
||||||
|
*/
|
||||||
|
analyzer::pia::PIA* GetPIA() const { return pia; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to raise a \c packet_contents event.
|
||||||
|
*
|
||||||
|
* @param data The dass to pass to the event.
|
||||||
|
*
|
||||||
|
* @param len The length of \a data.
|
||||||
|
*/
|
||||||
|
void PacketContents(const u_char* data, int len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
IPBasedAnalyzer* parent;
|
||||||
|
analyzer::pia::PIA* pia;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace zeek::packet_analysis::IP
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
#include <pcap.h> // For DLT_ constants
|
#include <pcap.h> // For DLT_ constants
|
||||||
|
|
||||||
#include "zeek/session/Manager.h"
|
|
||||||
#include "zeek/RunState.h"
|
#include "zeek/RunState.h"
|
||||||
#include "zeek/IP.h"
|
#include "zeek/IP.h"
|
||||||
#include "zeek/TunnelEncapsulation.h"
|
#include "zeek/TunnelEncapsulation.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IP.h"
|
||||||
|
|
||||||
namespace zeek::packet_analysis::IPTunnel {
|
namespace zeek::packet_analysis::IPTunnel {
|
||||||
|
|
||||||
|
@ -45,12 +45,12 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
|
||||||
BifEnum::Tunnel::Type tunnel_type = packet->tunnel_type;
|
BifEnum::Tunnel::Type tunnel_type = packet->tunnel_type;
|
||||||
int gre_link_type = packet->gre_link_type;
|
int gre_link_type = packet->gre_link_type;
|
||||||
|
|
||||||
IP_Hdr* inner = nullptr;
|
std::unique_ptr<IP_Hdr> inner = nullptr;
|
||||||
|
|
||||||
if ( gre_version != 0 )
|
if ( gre_version != 0 )
|
||||||
{
|
{
|
||||||
// Check for a valid inner packet first.
|
// Check for a valid inner packet first.
|
||||||
int result = session_mgr->ParseIPPacket(len, data, proto, inner);
|
int result = packet_analysis::IP::ParsePacket(len, data, proto, inner);
|
||||||
if ( result == -2 )
|
if ( result == -2 )
|
||||||
Weird("invalid_inner_IP_version", packet);
|
Weird("invalid_inner_IP_version", packet);
|
||||||
else if ( result < 0 )
|
else if ( result < 0 )
|
||||||
|
@ -59,11 +59,8 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
|
||||||
Weird("inner_IP_payload_length_mismatch", packet);
|
Weird("inner_IP_payload_length_mismatch", packet);
|
||||||
|
|
||||||
if ( result != 0 )
|
if ( result != 0 )
|
||||||
{
|
|
||||||
delete inner;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Look up to see if we've already seen this IP tunnel, identified
|
// Look up to see if we've already seen this IP tunnel, identified
|
||||||
// by the pair of IP addresses, so that we can always associate the
|
// by the pair of IP addresses, so that we can always associate the
|
||||||
|
@ -100,7 +97,7 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
|
||||||
* Handles a packet that contains an IP header directly after the tunnel header.
|
* Handles a packet that contains an IP header directly after the tunnel header.
|
||||||
*/
|
*/
|
||||||
bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
|
bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
|
||||||
const IP_Hdr* inner,
|
const std::unique_ptr<IP_Hdr>& inner,
|
||||||
std::shared_ptr<EncapsulationStack> prev,
|
std::shared_ptr<EncapsulationStack> prev,
|
||||||
const EncapsulatingConn& ec)
|
const EncapsulatingConn& ec)
|
||||||
{
|
{
|
||||||
|
@ -138,8 +135,6 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
|
||||||
// Forward the packet back to the IP analyzer.
|
// Forward the packet back to the IP analyzer.
|
||||||
bool return_val = ForwardPacket(len, data, &p);
|
bool return_val = ForwardPacket(len, data, &p);
|
||||||
|
|
||||||
delete inner;
|
|
||||||
|
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
* @param ec The most-recently found depth of encapsulation.
|
* @param ec The most-recently found depth of encapsulation.
|
||||||
*/
|
*/
|
||||||
bool ProcessEncapsulatedPacket(double t, const Packet *pkt,
|
bool ProcessEncapsulatedPacket(double t, const Packet *pkt,
|
||||||
const IP_Hdr* inner,
|
const std::unique_ptr<IP_Hdr>& inner,
|
||||||
std::shared_ptr<EncapsulationStack> prev,
|
std::shared_ptr<EncapsulationStack> prev,
|
||||||
const EncapsulatingConn& ec);
|
const EncapsulatingConn& ec);
|
||||||
|
|
||||||
|
|
8
src/packet_analysis/protocol/tcp/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/tcp/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
include(ZeekPlugin)
|
||||||
|
|
||||||
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
zeek_plugin_begin(PacketAnalyzer TCP_PKT)
|
||||||
|
zeek_plugin_cc(TCP.cc Plugin.cc)
|
||||||
|
zeek_plugin_end()
|
24
src/packet_analysis/protocol/tcp/Plugin.cc
Normal file
24
src/packet_analysis/protocol/tcp/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/plugin/Plugin.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/tcp/TCP.h"
|
||||||
|
|
||||||
|
namespace zeek::plugin::Zeek_TCP {
|
||||||
|
|
||||||
|
class Plugin : public zeek::plugin::Plugin {
|
||||||
|
public:
|
||||||
|
zeek::plugin::Configuration Configure()
|
||||||
|
{
|
||||||
|
AddComponent(new zeek::packet_analysis::Component("TCP",
|
||||||
|
zeek::packet_analysis::TCP::TCPAnalyzer::Instantiate));
|
||||||
|
|
||||||
|
zeek::plugin::Configuration config;
|
||||||
|
config.name = "Zeek::TCP_PKT";
|
||||||
|
config.description = "Packet analyzer for TCP";
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
} plugin;
|
||||||
|
|
||||||
|
}
|
76
src/packet_analysis/protocol/tcp/TCP.cc
Normal file
76
src/packet_analysis/protocol/tcp/TCP.cc
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/protocol/tcp/TCP.h"
|
||||||
|
#include "zeek/RunState.h"
|
||||||
|
|
||||||
|
using namespace zeek::packet_analysis::TCP;
|
||||||
|
using namespace zeek::packet_analysis::IP;
|
||||||
|
|
||||||
|
TCPAnalyzer::TCPAnalyzer() : IPBasedAnalyzer("TCP", TRANSPORT_TCP, TCP_PORT_MASK, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPAnalyzer::~TCPAnalyzer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCPAnalyzer::BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
|
ConnTuple& tuple)
|
||||||
|
{
|
||||||
|
uint32_t min_hdr_len = sizeof(struct tcphdr);
|
||||||
|
if ( ! CheckHeaderTrunc(min_hdr_len, len, packet) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tuple.src_addr = packet->ip_hdr->SrcAddr();
|
||||||
|
tuple.dst_addr = packet->ip_hdr->DstAddr();
|
||||||
|
|
||||||
|
data = packet->ip_hdr->Payload();
|
||||||
|
|
||||||
|
const struct tcphdr* tp = (const struct tcphdr *) data;
|
||||||
|
tuple.src_port = tp->th_sport;
|
||||||
|
tuple.dst_port = tp->th_dport;
|
||||||
|
tuple.is_one_way = false;
|
||||||
|
tuple.proto = TRANSPORT_TCP;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCPAnalyzer::WantConnection(uint16_t src_port, uint16_t dst_port,
|
||||||
|
const u_char* data, bool& flip_roles) const
|
||||||
|
{
|
||||||
|
flip_roles = false;
|
||||||
|
const struct tcphdr* tp = (const struct tcphdr*) data;
|
||||||
|
uint8_t tcp_flags = tp->th_flags;
|
||||||
|
|
||||||
|
if ( ! (tcp_flags & TH_SYN) || (tcp_flags & TH_ACK) )
|
||||||
|
{
|
||||||
|
// The new connection is starting either without a SYN,
|
||||||
|
// or with a SYN ack. This means it's a partial connection.
|
||||||
|
if ( ! zeek::detail::partial_connection_ok )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( tcp_flags & TH_SYN && ! zeek::detail::tcp_SYN_ack_ok )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Try to guess true responder by the port numbers.
|
||||||
|
// (We might also think that for SYN acks we could
|
||||||
|
// safely flip the roles, but that doesn't work
|
||||||
|
// for stealth scans.)
|
||||||
|
if ( IsLikelyServerPort(src_port) )
|
||||||
|
{ // connection is a candidate for flipping
|
||||||
|
if ( IsLikelyServerPort(dst_port) )
|
||||||
|
// Hmmm, both source and destination
|
||||||
|
// are plausible. Heuristic: flip only
|
||||||
|
// if (1) this isn't a SYN ACK (to avoid
|
||||||
|
// confusing stealth scans) and
|
||||||
|
// (2) dest port > src port (to favor
|
||||||
|
// more plausible servers).
|
||||||
|
flip_roles = ! (tcp_flags & TH_SYN) && src_port < dst_port;
|
||||||
|
else
|
||||||
|
// Source is plausible, destination isn't.
|
||||||
|
flip_roles = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
54
src/packet_analysis/protocol/tcp/TCP.h
Normal file
54
src/packet_analysis/protocol/tcp/TCP.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/Analyzer.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||||
|
|
||||||
|
namespace zeek::packet_analysis::TCP {
|
||||||
|
|
||||||
|
class TCPAnalyzer final : public IP::IPBasedAnalyzer {
|
||||||
|
public:
|
||||||
|
TCPAnalyzer();
|
||||||
|
~TCPAnalyzer() override;
|
||||||
|
|
||||||
|
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
||||||
|
{
|
||||||
|
return std::make_shared<TCPAnalyzer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an adapter appropriate for this IP-based analyzer. This adapter is used to
|
||||||
|
* hook into the session analyzer framework. This function can also be used to do any
|
||||||
|
* extra initialization of connection timers, etc.
|
||||||
|
*
|
||||||
|
* TODO: this is a stub until the TCP analyzer moves to the packet analysis framework.
|
||||||
|
*/
|
||||||
|
IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override { return nullptr; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the header from the packet into a ConnTuple object.
|
||||||
|
*/
|
||||||
|
bool BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
|
ConnTuple& tuple) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upon seeing the first packet of a connection, checks whether we want
|
||||||
|
* to analyze it (e.g. we may not want to look at partial connections)
|
||||||
|
* and, if yes, whether we should flip the roles of originator and
|
||||||
|
* responder based on known ports and such.
|
||||||
|
*
|
||||||
|
* @param src_port The source port of the connection.
|
||||||
|
* @param dst_port The destination port of the connection.
|
||||||
|
* @param data The payload data for the packet being processed.
|
||||||
|
* @param flip_roles Return value if the roles should be flipped.
|
||||||
|
* @return True if the connection is wanted. False otherwise.
|
||||||
|
*/
|
||||||
|
bool WantConnection(uint16_t src_port, uint16_t dst_port,
|
||||||
|
const u_char* data, bool& flip_roles) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
26
src/packet_analysis/protocol/udp/Plugin.cc
Normal file
26
src/packet_analysis/protocol/udp/Plugin.cc
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/plugin/Plugin.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/udp/UDP.h"
|
||||||
|
|
||||||
|
namespace zeek::plugin::Zeek_UDP {
|
||||||
|
|
||||||
|
class Plugin : public zeek::plugin::Plugin {
|
||||||
|
public:
|
||||||
|
zeek::plugin::Configuration Configure()
|
||||||
|
{
|
||||||
|
AddComponent(new zeek::packet_analysis::Component("UDP",
|
||||||
|
zeek::packet_analysis::UDP::UDPAnalyzer::Instantiate));
|
||||||
|
AddComponent(new zeek::analyzer::Component("UDP",
|
||||||
|
zeek::packet_analysis::UDP::UDPSessionAdapter::Instantiate));
|
||||||
|
|
||||||
|
zeek::plugin::Configuration config;
|
||||||
|
config.name = "Zeek::UDP";
|
||||||
|
config.description = "Packet analyzer for UDP";
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
} plugin;
|
||||||
|
|
||||||
|
}
|
338
src/packet_analysis/protocol/udp/UDP.cc
Normal file
338
src/packet_analysis/protocol/udp/UDP.cc
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/protocol/udp/UDP.h"
|
||||||
|
#include "zeek/RunState.h"
|
||||||
|
#include "zeek/Conn.h"
|
||||||
|
#include "zeek/session/Manager.h"
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
#include "zeek/analyzer/protocol/pia/PIA.h"
|
||||||
|
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/protocol/udp/events.bif.h"
|
||||||
|
|
||||||
|
using namespace zeek::packet_analysis::UDP;
|
||||||
|
using namespace zeek::packet_analysis::IP;
|
||||||
|
|
||||||
|
constexpr uint32_t HIST_ORIG_DATA_PKT = 0x1;
|
||||||
|
constexpr uint32_t HIST_RESP_DATA_PKT = 0x2;
|
||||||
|
constexpr uint32_t HIST_ORIG_CORRUPT_PKT = 0x4;
|
||||||
|
constexpr uint32_t HIST_RESP_CORRUPT_PKT = 0x8;
|
||||||
|
|
||||||
|
enum UDP_EndpointState {
|
||||||
|
UDP_INACTIVE, // no packet seen
|
||||||
|
UDP_ACTIVE, // packets seen
|
||||||
|
};
|
||||||
|
|
||||||
|
UDPAnalyzer::UDPAnalyzer() : IPBasedAnalyzer("UDP", TRANSPORT_UDP, UDP_PORT_MASK, false)
|
||||||
|
{
|
||||||
|
// TODO: remove once the other plugins are done
|
||||||
|
new_plugin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
UDPAnalyzer::~UDPAnalyzer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionAdapter* UDPAnalyzer::MakeSessionAdapter(Connection* conn)
|
||||||
|
{
|
||||||
|
auto* root = new UDPSessionAdapter(conn);
|
||||||
|
root->SetParent(this);
|
||||||
|
|
||||||
|
conn->EnableStatusUpdateTimer();
|
||||||
|
conn->SetInactivityTimeout(zeek::detail::udp_inactivity_timeout);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::analyzer::pia::PIA* UDPAnalyzer::MakePIA(Connection* conn)
|
||||||
|
{
|
||||||
|
return new analyzer::pia::PIA_UDP(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPAnalyzer::Initialize()
|
||||||
|
{
|
||||||
|
IPBasedAnalyzer::Initialize();
|
||||||
|
|
||||||
|
const auto& id = detail::global_scope()->Find("Tunnel::vxlan_ports");
|
||||||
|
|
||||||
|
if ( ! (id && id->GetVal()) )
|
||||||
|
reporter->FatalError("Tunnel::vxlan_ports not defined");
|
||||||
|
|
||||||
|
auto table_val = id->GetVal()->AsTableVal();
|
||||||
|
auto port_list = table_val->ToPureListVal();
|
||||||
|
|
||||||
|
for ( auto i = 0; i < port_list->Length(); ++i )
|
||||||
|
vxlan_ports.emplace_back(port_list->Idx(i)->AsPortVal()->Port());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDPAnalyzer::WantConnection(uint16_t src_port, uint16_t dst_port,
|
||||||
|
const u_char* data, bool& flip_roles) const
|
||||||
|
{
|
||||||
|
flip_roles = IsLikelyServerPort(src_port) && ! IsLikelyServerPort(dst_port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDPAnalyzer::BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
|
ConnTuple& tuple)
|
||||||
|
{
|
||||||
|
uint32_t min_hdr_len = sizeof(struct udphdr);
|
||||||
|
if ( ! CheckHeaderTrunc(min_hdr_len, len, packet) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tuple.src_addr = packet->ip_hdr->SrcAddr();
|
||||||
|
tuple.dst_addr = packet->ip_hdr->DstAddr();
|
||||||
|
|
||||||
|
const struct udphdr* up = (const struct udphdr *) packet->ip_hdr->Payload();
|
||||||
|
tuple.src_port = up->uh_sport;
|
||||||
|
tuple.dst_port = up->uh_dport;
|
||||||
|
tuple.is_one_way = false;
|
||||||
|
tuple.proto = TRANSPORT_UDP;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remaining, Packet* pkt)
|
||||||
|
{
|
||||||
|
auto* adapter = static_cast<UDPSessionAdapter*>(c->GetSessionAdapter());
|
||||||
|
|
||||||
|
const u_char* data = pkt->ip_hdr->Payload();
|
||||||
|
int len = pkt->ip_hdr->PayloadLen();
|
||||||
|
|
||||||
|
const struct udphdr* up = (const struct udphdr*) data;
|
||||||
|
const std::unique_ptr<IP_Hdr>& ip = pkt->ip_hdr;
|
||||||
|
|
||||||
|
adapter->DeliverPacket(len, data, is_orig, -1, ip.get(), remaining);
|
||||||
|
|
||||||
|
// Increment data before checksum check so that data will
|
||||||
|
// point to UDP payload even if checksum fails. Particularly,
|
||||||
|
// it allows event packet_contents to get to the data.
|
||||||
|
data += sizeof(struct udphdr);
|
||||||
|
|
||||||
|
// We need the min() here because Ethernet frame padding can lead to
|
||||||
|
// remaining > len.
|
||||||
|
if ( packet_contents )
|
||||||
|
adapter->PacketContents(data, std::min(len, remaining) - sizeof(struct udphdr));
|
||||||
|
|
||||||
|
int chksum = up->uh_sum;
|
||||||
|
|
||||||
|
auto validate_checksum =
|
||||||
|
! run_state::current_pkt->l3_checksummed &&
|
||||||
|
! zeek::detail::ignore_checksums &&
|
||||||
|
! zeek::id::find_val<TableVal>("ignore_checksums_nets")->Contains(ip->IPHeaderSrcAddr()) &&
|
||||||
|
remaining >=len;
|
||||||
|
|
||||||
|
constexpr auto vxlan_len = 8;
|
||||||
|
constexpr auto eth_len = 14;
|
||||||
|
|
||||||
|
if ( validate_checksum &&
|
||||||
|
len > ((int)sizeof(struct udphdr) + vxlan_len + eth_len) &&
|
||||||
|
(data[0] & 0x08) == 0x08 )
|
||||||
|
{
|
||||||
|
if ( std::find(vxlan_ports.begin(), vxlan_ports.end(),
|
||||||
|
ntohs(up->uh_dport)) != vxlan_ports.end() )
|
||||||
|
{
|
||||||
|
// Looks like VXLAN on a well-known port, so the checksum should be
|
||||||
|
// transmitted as zero, and we should accept that. If not
|
||||||
|
// transmitted as zero, then validating the checksum is optional.
|
||||||
|
if ( chksum == 0 )
|
||||||
|
validate_checksum = false;
|
||||||
|
else
|
||||||
|
validate_checksum = BifConst::Tunnel::validate_vxlan_checksums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( validate_checksum )
|
||||||
|
{
|
||||||
|
bool bad = false;
|
||||||
|
|
||||||
|
if ( ip->IP4_Hdr() )
|
||||||
|
{
|
||||||
|
if ( chksum && ! ValidateChecksum(ip.get(), up, len) )
|
||||||
|
bad = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* checksum is not optional for IPv6 */
|
||||||
|
else if ( ! ValidateChecksum(ip.get(), up, len) )
|
||||||
|
bad = true;
|
||||||
|
|
||||||
|
if ( bad )
|
||||||
|
{
|
||||||
|
adapter->HandleBadChecksum(is_orig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ulen = ntohs(up->uh_ulen);
|
||||||
|
if ( ulen != len )
|
||||||
|
adapter->Weird("UDP_datagram_length_mismatch", util::fmt("%d != %d", ulen, len));
|
||||||
|
|
||||||
|
len -= sizeof(struct udphdr);
|
||||||
|
ulen -= sizeof(struct udphdr);
|
||||||
|
remaining -= sizeof(struct udphdr);
|
||||||
|
|
||||||
|
c->SetLastTime(run_state::current_timestamp);
|
||||||
|
|
||||||
|
if ( udp_contents )
|
||||||
|
{
|
||||||
|
static auto udp_content_ports = id::find_val<TableVal>("udp_content_ports");
|
||||||
|
static auto udp_content_delivery_ports_orig = id::find_val<TableVal>("udp_content_delivery_ports_orig");
|
||||||
|
static auto udp_content_delivery_ports_resp = id::find_val<TableVal>("udp_content_delivery_ports_resp");
|
||||||
|
bool do_udp_contents = false;
|
||||||
|
const auto& sport_val = val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP);
|
||||||
|
const auto& dport_val = val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP);
|
||||||
|
|
||||||
|
if ( udp_content_ports->FindOrDefault(dport_val) ||
|
||||||
|
udp_content_ports->FindOrDefault(sport_val) )
|
||||||
|
do_udp_contents = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t p = zeek::detail::udp_content_delivery_ports_use_resp ? c->RespPort()
|
||||||
|
: up->uh_dport;
|
||||||
|
const auto& port_val = zeek::val_mgr->Port(ntohs(p), TRANSPORT_UDP);
|
||||||
|
|
||||||
|
if ( is_orig )
|
||||||
|
{
|
||||||
|
auto result = udp_content_delivery_ports_orig->FindOrDefault(port_val);
|
||||||
|
|
||||||
|
if ( zeek::detail::udp_content_deliver_all_orig || (result && result->AsBool()) )
|
||||||
|
do_udp_contents = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto result = udp_content_delivery_ports_resp->FindOrDefault(port_val);
|
||||||
|
|
||||||
|
if ( zeek::detail::udp_content_deliver_all_resp || (result && result->AsBool()) )
|
||||||
|
do_udp_contents = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( do_udp_contents )
|
||||||
|
adapter->EnqueueConnEvent(udp_contents,
|
||||||
|
adapter->ConnVal(),
|
||||||
|
val_mgr->Bool(is_orig),
|
||||||
|
make_intrusive<StringVal>(len, (const char*) data));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_orig )
|
||||||
|
{
|
||||||
|
c->CheckHistory(HIST_ORIG_DATA_PKT, 'D');
|
||||||
|
adapter->UpdateLength(is_orig, ulen);
|
||||||
|
adapter->Event(udp_request);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c->CheckHistory(HIST_RESP_DATA_PKT, 'd');
|
||||||
|
adapter->UpdateLength(is_orig, ulen);
|
||||||
|
adapter->Event(udp_reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the packet back into the packet analysis framework.
|
||||||
|
ForwardPacket(len, data, pkt);
|
||||||
|
|
||||||
|
// Also try sending it into session analysis.
|
||||||
|
if ( remaining >= len )
|
||||||
|
adapter->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDPAnalyzer::ValidateChecksum(const IP_Hdr* ip, const udphdr* up, int len)
|
||||||
|
{
|
||||||
|
auto sum = detail::ip_in_cksum(ip->IP4_Hdr(), ip->SrcAddr(), ip->DstAddr(),
|
||||||
|
IPPROTO_UDP,
|
||||||
|
reinterpret_cast<const uint8_t*>(up), len);
|
||||||
|
|
||||||
|
return sum == 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPSessionAdapter::AddExtraAnalyzers(Connection* conn)
|
||||||
|
{
|
||||||
|
static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE");
|
||||||
|
|
||||||
|
if ( analyzer_mgr->IsEnabled(analyzer_connsize) )
|
||||||
|
// Add ConnSize analyzer. Needs to see packets, not stream.
|
||||||
|
AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPSessionAdapter::UpdateConnVal(RecordVal* conn_val)
|
||||||
|
{
|
||||||
|
auto orig_endp = conn_val->GetField("orig");
|
||||||
|
auto resp_endp = conn_val->GetField("resp");
|
||||||
|
|
||||||
|
UpdateEndpointVal(orig_endp, true);
|
||||||
|
UpdateEndpointVal(resp_endp, false);
|
||||||
|
|
||||||
|
// Call children's UpdateConnVal
|
||||||
|
Analyzer::UpdateConnVal(conn_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig)
|
||||||
|
{
|
||||||
|
bro_int_t size = is_orig ? request_len : reply_len;
|
||||||
|
auto endp = endp_arg->AsRecordVal();
|
||||||
|
|
||||||
|
if ( size < 0 )
|
||||||
|
{
|
||||||
|
endp->Assign(0, val_mgr->Count(0));
|
||||||
|
endp->Assign(1, UDP_INACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endp->Assign(0, static_cast<uint64_t>(size));
|
||||||
|
endp->Assign(1, UDP_ACTIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPSessionAdapter::UpdateLength(bool is_orig, int len)
|
||||||
|
{
|
||||||
|
if ( is_orig )
|
||||||
|
{
|
||||||
|
if ( request_len < 0 )
|
||||||
|
request_len = len;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request_len += len;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if ( request_len < 0 )
|
||||||
|
reporter->Warning("wrapping around for UDP request length");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( reply_len < 0 )
|
||||||
|
reply_len = len;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reply_len += len;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if ( reply_len < 0 )
|
||||||
|
reporter->Warning("wrapping around for UDP reply length");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPSessionAdapter::HandleBadChecksum(bool is_orig)
|
||||||
|
{
|
||||||
|
Weird("bad_UDP_checksum");
|
||||||
|
|
||||||
|
if ( is_orig )
|
||||||
|
{
|
||||||
|
uint32_t t = req_chk_thresh;
|
||||||
|
|
||||||
|
if ( Conn()->ScaledHistoryEntry('C', req_chk_cnt, req_chk_thresh) )
|
||||||
|
ChecksumEvent(is_orig, t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t t = rep_chk_thresh;
|
||||||
|
|
||||||
|
if ( Conn()->ScaledHistoryEntry('c', rep_chk_cnt, rep_chk_thresh) )
|
||||||
|
ChecksumEvent(is_orig, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPSessionAdapter::ChecksumEvent(bool is_orig, uint32_t threshold)
|
||||||
|
{
|
||||||
|
Conn()->HistoryThresholdEvent(udp_multiple_checksum_errors, is_orig, threshold);
|
||||||
|
}
|
100
src/packet_analysis/protocol/udp/UDP.h
Normal file
100
src/packet_analysis/protocol/udp/UDP.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "zeek/packet_analysis/Analyzer.h"
|
||||||
|
#include "zeek/packet_analysis/Component.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||||
|
|
||||||
|
namespace zeek::packet_analysis::UDP {
|
||||||
|
|
||||||
|
class UDPAnalyzer final : public IP::IPBasedAnalyzer {
|
||||||
|
public:
|
||||||
|
UDPAnalyzer();
|
||||||
|
~UDPAnalyzer() override;
|
||||||
|
|
||||||
|
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
||||||
|
{
|
||||||
|
return std::make_shared<UDPAnalyzer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the analyzer. This method is called after the configuration
|
||||||
|
* was read. Derived classes can override this method to implement custom
|
||||||
|
* initialization.
|
||||||
|
*/
|
||||||
|
void Initialize() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the header from the packet into a ConnTuple object.
|
||||||
|
*/
|
||||||
|
bool BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||||
|
ConnTuple& tuple) override;
|
||||||
|
|
||||||
|
void DeliverPacket(Connection* c, double t, bool is_orig, int remaining,
|
||||||
|
Packet* pkt) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upon seeing the first packet of a connection, checks whether we want
|
||||||
|
* to analyze it (e.g. we may not want to look at partial connections)
|
||||||
|
* and, if yes, whether we should flip the roles of originator and
|
||||||
|
* responder based on known ports and such.
|
||||||
|
*
|
||||||
|
* @param src_port The source port of the connection.
|
||||||
|
* @param dst_port The destination port of the connection.
|
||||||
|
* @param data The payload data for the packet being processed.
|
||||||
|
* @param flip_roles Return value if the roles should be flipped.
|
||||||
|
* @return True if the connection is wanted. False otherwise.
|
||||||
|
*/
|
||||||
|
bool WantConnection(uint16_t src_port, uint16_t dst_port,
|
||||||
|
const u_char* data, bool& flip_roles) const override;
|
||||||
|
|
||||||
|
packet_analysis::IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override;
|
||||||
|
analyzer::pia::PIA* MakePIA(Connection* conn) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Returns true if the checksum is valid, false if not
|
||||||
|
static bool ValidateChecksum(const IP_Hdr* ip, const struct udphdr* up,
|
||||||
|
int len);
|
||||||
|
|
||||||
|
std::vector<uint16_t> vxlan_ports;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UDPSessionAdapter final : public IP::SessionAdapter {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UDPSessionAdapter(Connection* conn) :
|
||||||
|
IP::SessionAdapter("UDP", conn) { }
|
||||||
|
|
||||||
|
static zeek::analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
|
{
|
||||||
|
return new UDPSessionAdapter(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddExtraAnalyzers(Connection* conn) override;
|
||||||
|
void UpdateConnVal(RecordVal* conn_val) override;
|
||||||
|
|
||||||
|
void UpdateLength(bool is_orig, int len);
|
||||||
|
void HandleBadChecksum(bool is_orig);
|
||||||
|
|
||||||
|
// For tracking checksum history. These are connection-specific so they
|
||||||
|
// need to be stored in the session adapter created for each connection.
|
||||||
|
uint32_t req_chk_cnt = 0;
|
||||||
|
uint32_t req_chk_thresh = 1;
|
||||||
|
uint32_t rep_chk_cnt = 0;
|
||||||
|
uint32_t rep_chk_thresh = 1;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig);
|
||||||
|
void ChecksumEvent(bool is_orig, uint32_t threshold);
|
||||||
|
|
||||||
|
bro_int_t request_len = -1;
|
||||||
|
bro_int_t reply_len = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
namespace zeek::session::detail {
|
namespace zeek::session::detail {
|
||||||
|
|
||||||
Key::Key(const void* session, size_t size, bool copy) : size(size)
|
Key::Key(const void* session, size_t size, size_t type, bool copy) :
|
||||||
|
size(size), type(type)
|
||||||
{
|
{
|
||||||
data = reinterpret_cast<const uint8_t*>(session);
|
data = reinterpret_cast<const uint8_t*>(session);
|
||||||
|
|
||||||
|
@ -63,6 +64,8 @@ bool Key::operator<(const Key& rhs) const
|
||||||
{
|
{
|
||||||
if ( size != rhs.size )
|
if ( size != rhs.size )
|
||||||
return size < rhs.size;
|
return size < rhs.size;
|
||||||
|
else if ( type != rhs.type )
|
||||||
|
return type < rhs.type;
|
||||||
|
|
||||||
return memcmp(data, rhs.data, size) < 0;
|
return memcmp(data, rhs.data, size) < 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,22 @@ namespace zeek::session::detail {
|
||||||
class Key final {
|
class Key final {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
const static size_t CONNECTION_KEY_TYPE=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new session key from a data pointer.
|
* Create a new session key from a data pointer.
|
||||||
*
|
*
|
||||||
* @param session A pointer to the data for the key.
|
* @param session A pointer to the data for the key.
|
||||||
* @param size The size of the key data, in bytes.
|
* @param size The size of the key data, in bytes.
|
||||||
|
* @param type An identifier for the type of this key. The value used should be
|
||||||
|
* unique across all types of session keys. CONNECTION_KEY_TYPE (0) is used by
|
||||||
|
* Connection sessions and is reserved. This value is used to avoid collisions
|
||||||
|
* when doing comparisons of the memory stored by keys.
|
||||||
* @param copy Flag for whether the data should be copied into the Key
|
* @param copy Flag for whether the data should be copied into the Key
|
||||||
* during construction. This defaults to false because normally the only time
|
* during construction. This defaults to false because normally the only time
|
||||||
* data is copied into the key is when it's inserted into the session map.
|
* data is copied into the key is when it's inserted into the session map.
|
||||||
*/
|
*/
|
||||||
Key(const void* key_data, size_t size, bool copy=false);
|
Key(const void* key_data, size_t size, size_t type, bool copy=false);
|
||||||
|
|
||||||
~Key();
|
~Key();
|
||||||
|
|
||||||
|
@ -55,6 +61,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const uint8_t* data = nullptr;
|
const uint8_t* data = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
size_t type = CONNECTION_KEY_TYPE;
|
||||||
bool copied = false;
|
bool copied = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
#include "zeek/session/Session.h"
|
#include "zeek/session/Session.h"
|
||||||
#include "zeek/TunnelEncapsulation.h"
|
#include "zeek/TunnelEncapsulation.h"
|
||||||
#include "zeek/telemetry/Manager.h"
|
#include "zeek/telemetry/Manager.h"
|
||||||
|
|
||||||
#include "zeek/analyzer/protocol/icmp/ICMP.h"
|
|
||||||
#include "zeek/analyzer/protocol/udp/UDP.h"
|
|
||||||
#include "zeek/analyzer/Manager.h"
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
|
||||||
#include "zeek/iosource/IOSource.h"
|
#include "zeek/iosource/IOSource.h"
|
||||||
|
@ -107,234 +104,6 @@ void Manager::Done()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ProcessTransportLayer(double t, const Packet* pkt, size_t remaining)
|
|
||||||
{
|
|
||||||
const std::unique_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
|
|
||||||
|
|
||||||
uint32_t len = ip_hdr->TotalLen();
|
|
||||||
uint16_t ip_hdr_len = ip_hdr->HdrLen();
|
|
||||||
|
|
||||||
if ( len < ip_hdr_len )
|
|
||||||
{
|
|
||||||
session_mgr->Weird("bogus_IP_header_lengths", pkt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
len -= ip_hdr_len; // remove IP header
|
|
||||||
|
|
||||||
int proto = ip_hdr->NextProto();
|
|
||||||
|
|
||||||
if ( CheckHeaderTrunc(proto, len, remaining, pkt) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
const u_char* data = ip_hdr->Payload();
|
|
||||||
|
|
||||||
ConnTuple id;
|
|
||||||
id.src_addr = ip_hdr->SrcAddr();
|
|
||||||
id.dst_addr = ip_hdr->DstAddr();
|
|
||||||
BifEnum::Tunnel::Type tunnel_type = BifEnum::Tunnel::IP;
|
|
||||||
|
|
||||||
switch ( proto ) {
|
|
||||||
case IPPROTO_TCP:
|
|
||||||
{
|
|
||||||
const struct tcphdr* tp = (const struct tcphdr *) data;
|
|
||||||
id.src_port = tp->th_sport;
|
|
||||||
id.dst_port = tp->th_dport;
|
|
||||||
id.is_one_way = false;
|
|
||||||
id.proto = TRANSPORT_TCP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
{
|
|
||||||
const struct udphdr* up = (const struct udphdr *) data;
|
|
||||||
id.src_port = up->uh_sport;
|
|
||||||
id.dst_port = up->uh_dport;
|
|
||||||
id.is_one_way = false;
|
|
||||||
id.proto = TRANSPORT_UDP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IPPROTO_ICMP:
|
|
||||||
{
|
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
|
||||||
|
|
||||||
id.src_port = icmpp->icmp_type;
|
|
||||||
id.dst_port = analyzer::icmp::ICMP4_counterpart(icmpp->icmp_type,
|
|
||||||
icmpp->icmp_code,
|
|
||||||
id.is_one_way);
|
|
||||||
id.src_port = htons(id.src_port);
|
|
||||||
id.dst_port = htons(id.dst_port);
|
|
||||||
id.proto = TRANSPORT_ICMP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IPPROTO_ICMPV6:
|
|
||||||
{
|
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
|
||||||
|
|
||||||
id.src_port = icmpp->icmp_type;
|
|
||||||
id.dst_port = analyzer::icmp::ICMP6_counterpart(icmpp->icmp_type,
|
|
||||||
icmpp->icmp_code,
|
|
||||||
id.is_one_way);
|
|
||||||
id.src_port = htons(id.src_port);
|
|
||||||
id.dst_port = htons(id.dst_port);
|
|
||||||
id.proto = TRANSPORT_ICMP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
Weird("unknown_protocol", pkt, util::fmt("%d", proto));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
zeek::detail::ConnKey conn_key(id);
|
|
||||||
detail::Key key(&conn_key, sizeof(conn_key), false);
|
|
||||||
Connection* conn = nullptr;
|
|
||||||
|
|
||||||
// FIXME: The following is getting pretty complex. Need to split up
|
|
||||||
// into separate functions.
|
|
||||||
auto it = session_map.find(key);
|
|
||||||
if (it != session_map.end() )
|
|
||||||
conn = static_cast<Connection*>(it->second);
|
|
||||||
|
|
||||||
if ( ! conn )
|
|
||||||
{
|
|
||||||
conn = NewConn(conn_key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt);
|
|
||||||
if ( conn )
|
|
||||||
InsertSession(std::move(key), conn);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We already know that connection.
|
|
||||||
if ( conn->IsReuse(t, data) )
|
|
||||||
{
|
|
||||||
conn->Event(connection_reused, nullptr);
|
|
||||||
|
|
||||||
Remove(conn);
|
|
||||||
conn = NewConn(conn_key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt);
|
|
||||||
if ( conn )
|
|
||||||
InsertSession(std::move(key), conn);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
conn->CheckEncapsulation(pkt->encap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! conn )
|
|
||||||
return;
|
|
||||||
|
|
||||||
int record_packet = 1; // whether to record the packet at all
|
|
||||||
int record_content = 1; // whether to record its data
|
|
||||||
|
|
||||||
bool is_orig = (id.src_addr == conn->OrigAddr()) &&
|
|
||||||
(id.src_port == conn->OrigPort());
|
|
||||||
|
|
||||||
conn->CheckFlowLabel(is_orig, ip_hdr->FlowLabel());
|
|
||||||
|
|
||||||
ValPtr pkt_hdr_val;
|
|
||||||
|
|
||||||
if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 )
|
|
||||||
{
|
|
||||||
pkt_hdr_val = ip_hdr->ToPktHdrVal();
|
|
||||||
conn->EnqueueEvent(ipv6_ext_headers, nullptr, conn->GetVal(),
|
|
||||||
pkt_hdr_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( new_packet )
|
|
||||||
conn->EnqueueEvent(new_packet, nullptr, conn->GetVal(), pkt_hdr_val ?
|
|
||||||
std::move(pkt_hdr_val) : ip_hdr->ToPktHdrVal());
|
|
||||||
|
|
||||||
conn->NextPacket(t, is_orig, ip_hdr.get(), len, remaining, data,
|
|
||||||
record_packet, record_content, pkt);
|
|
||||||
|
|
||||||
// We skip this block for reassembled packets because the pointer
|
|
||||||
// math wouldn't work.
|
|
||||||
if ( ! ip_hdr->reassembled && record_packet )
|
|
||||||
{
|
|
||||||
if ( record_content )
|
|
||||||
pkt->dump_packet = true; // save the whole thing
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int hdr_len = data - pkt->data;
|
|
||||||
packet_mgr->DumpPacket(pkt, hdr_len); // just save the header
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Manager::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
|
||||||
IP_Hdr*& inner)
|
|
||||||
{
|
|
||||||
if ( proto == IPPROTO_IPV6 )
|
|
||||||
{
|
|
||||||
if ( caplen < (int)sizeof(struct ip6_hdr) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
const struct ip6_hdr* ip6 = (const struct ip6_hdr*) pkt;
|
|
||||||
inner = new IP_Hdr(ip6, false, caplen);
|
|
||||||
if ( ( ip6->ip6_ctlun.ip6_un2_vfc & 0xF0 ) != 0x60 )
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if ( proto == IPPROTO_IPV4 )
|
|
||||||
{
|
|
||||||
if ( caplen < (int)sizeof(struct ip) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
const struct ip* ip4 = (const struct ip*) pkt;
|
|
||||||
inner = new IP_Hdr(ip4, false);
|
|
||||||
if ( ip4->ip_v != 4 )
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reporter->InternalWarning("Bad IP protocol version in ParseIPPacket");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (uint32_t)caplen != inner->TotalLen() )
|
|
||||||
return (uint32_t)caplen < inner->TotalLen() ? -1 : 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen,
|
|
||||||
const Packet* p)
|
|
||||||
{
|
|
||||||
uint32_t min_hdr_len = 0;
|
|
||||||
switch ( proto ) {
|
|
||||||
case IPPROTO_TCP:
|
|
||||||
min_hdr_len = sizeof(struct tcphdr);
|
|
||||||
break;
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
min_hdr_len = sizeof(struct udphdr);
|
|
||||||
break;
|
|
||||||
case IPPROTO_ICMP:
|
|
||||||
case IPPROTO_ICMPV6:
|
|
||||||
default:
|
|
||||||
// Use for all other packets.
|
|
||||||
min_hdr_len = ICMP_MINLEN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( len < min_hdr_len )
|
|
||||||
{
|
|
||||||
Weird("truncated_header", p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( caplen < min_hdr_len )
|
|
||||||
{
|
|
||||||
Weird("internally_truncated_header", p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection* Manager::FindConnection(Val* v)
|
Connection* Manager::FindConnection(Val* v)
|
||||||
{
|
{
|
||||||
const auto& vt = v->GetType();
|
const auto& vt = v->GetType();
|
||||||
|
@ -380,14 +149,19 @@ Connection* Manager::FindConnection(Val* v)
|
||||||
htons((unsigned short) resp_portv->Port()),
|
htons((unsigned short) resp_portv->Port()),
|
||||||
orig_portv->PortType(), false);
|
orig_portv->PortType(), false);
|
||||||
|
|
||||||
detail::Key key(&conn_key, sizeof(conn_key), false);
|
return FindConnection(conn_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection* Manager::FindConnection(const zeek::detail::ConnKey& conn_key)
|
||||||
|
{
|
||||||
|
detail::Key key(&conn_key, sizeof(conn_key),
|
||||||
|
detail::Key::CONNECTION_KEY_TYPE, false);
|
||||||
|
|
||||||
Connection* conn = nullptr;
|
|
||||||
auto it = session_map.find(key);
|
auto it = session_map.find(key);
|
||||||
if ( it != session_map.end() )
|
if ( it != session_map.end() )
|
||||||
conn = static_cast<Connection*>(it->second);
|
return static_cast<Connection*>(it->second);
|
||||||
|
|
||||||
return conn;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Remove(Session* s)
|
void Manager::Remove(Session* s)
|
||||||
|
@ -418,16 +192,20 @@ void Manager::Remove(Session* s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Insert(Session* s)
|
void Manager::Insert(Session* s, bool remove_existing)
|
||||||
{
|
{
|
||||||
Session* old = nullptr;
|
Session* old = nullptr;
|
||||||
detail::Key key = s->SessionKey(true);
|
detail::Key key = s->SessionKey(true);
|
||||||
|
|
||||||
|
if ( remove_existing )
|
||||||
|
{
|
||||||
auto it = session_map.find(key);
|
auto it = session_map.find(key);
|
||||||
if ( it != session_map.end() )
|
if ( it != session_map.end() )
|
||||||
old = it->second;
|
old = it->second;
|
||||||
|
|
||||||
session_map.erase(key);
|
session_map.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
InsertSession(std::move(key), s);
|
InsertSession(std::move(key), s);
|
||||||
|
|
||||||
if ( old && old != s )
|
if ( old && old != s )
|
||||||
|
@ -482,140 +260,6 @@ void Manager::GetStats(Stats& s)
|
||||||
s.num_packets = packet_mgr->PacketsProcessed();
|
s.num_packets = packet_mgr->PacketsProcessed();
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection* Manager::NewConn(const zeek::detail::ConnKey& k, double t, const ConnTuple* id,
|
|
||||||
const u_char* data, int proto, uint32_t flow_label,
|
|
||||||
const Packet* pkt)
|
|
||||||
{
|
|
||||||
// FIXME: This should be cleaned up a bit, it's too protocol-specific.
|
|
||||||
// But I'm not yet sure what the right abstraction for these things is.
|
|
||||||
int src_h = ntohs(id->src_port);
|
|
||||||
int dst_h = ntohs(id->dst_port);
|
|
||||||
int flags = 0;
|
|
||||||
|
|
||||||
// Hmm... This is not great.
|
|
||||||
TransportProto tproto = TRANSPORT_UNKNOWN;
|
|
||||||
switch ( proto ) {
|
|
||||||
case IPPROTO_ICMP:
|
|
||||||
tproto = TRANSPORT_ICMP;
|
|
||||||
break;
|
|
||||||
case IPPROTO_TCP:
|
|
||||||
tproto = TRANSPORT_TCP;
|
|
||||||
break;
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
tproto = TRANSPORT_UDP;
|
|
||||||
break;
|
|
||||||
case IPPROTO_ICMPV6:
|
|
||||||
tproto = TRANSPORT_ICMP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
reporter->InternalWarning("unknown transport protocol");
|
|
||||||
return nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( tproto == TRANSPORT_TCP )
|
|
||||||
{
|
|
||||||
const struct tcphdr* tp = (const struct tcphdr*) data;
|
|
||||||
flags = tp->th_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flip = false;
|
|
||||||
|
|
||||||
if ( ! WantConnection(src_h, dst_h, tproto, flags, flip) )
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
Connection* conn = new Connection(k, t, id, flow_label, pkt);
|
|
||||||
conn->SetTransport(tproto);
|
|
||||||
|
|
||||||
if ( flip )
|
|
||||||
conn->FlipRoles();
|
|
||||||
|
|
||||||
if ( ! analyzer_mgr->BuildInitialAnalyzerTree(conn) )
|
|
||||||
{
|
|
||||||
conn->Done();
|
|
||||||
Unref(conn);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( new_connection )
|
|
||||||
conn->Event(new_connection, nullptr);
|
|
||||||
|
|
||||||
return conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::IsLikelyServerPort(uint32_t port, TransportProto proto) const
|
|
||||||
{
|
|
||||||
// We keep a cached in-core version of the table to speed up the lookup.
|
|
||||||
static std::set<bro_uint_t> port_cache;
|
|
||||||
static bool have_cache = false;
|
|
||||||
|
|
||||||
if ( ! have_cache )
|
|
||||||
{
|
|
||||||
auto likely_server_ports = id::find_val<TableVal>("likely_server_ports");
|
|
||||||
auto lv = likely_server_ports->ToPureListVal();
|
|
||||||
for ( int i = 0; i < lv->Length(); i++ )
|
|
||||||
port_cache.insert(lv->Idx(i)->InternalUnsigned());
|
|
||||||
have_cache = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We exploit our knowledge of PortVal's internal storage mechanism
|
|
||||||
// here.
|
|
||||||
if ( proto == TRANSPORT_TCP )
|
|
||||||
port |= TCP_PORT_MASK;
|
|
||||||
else if ( proto == TRANSPORT_UDP )
|
|
||||||
port |= UDP_PORT_MASK;
|
|
||||||
else if ( proto == TRANSPORT_ICMP )
|
|
||||||
port |= ICMP_PORT_MASK;
|
|
||||||
|
|
||||||
return port_cache.find(port) != port_cache.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::WantConnection(uint16_t src_port, uint16_t dst_port,
|
|
||||||
TransportProto transport_proto,
|
|
||||||
uint8_t tcp_flags, bool& flip_roles)
|
|
||||||
{
|
|
||||||
flip_roles = false;
|
|
||||||
|
|
||||||
if ( transport_proto == TRANSPORT_TCP )
|
|
||||||
{
|
|
||||||
if ( ! (tcp_flags & TH_SYN) || (tcp_flags & TH_ACK) )
|
|
||||||
{
|
|
||||||
// The new connection is starting either without a SYN,
|
|
||||||
// or with a SYN ack. This means it's a partial connection.
|
|
||||||
if ( ! zeek::detail::partial_connection_ok )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( tcp_flags & TH_SYN && ! zeek::detail::tcp_SYN_ack_ok )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Try to guess true responder by the port numbers.
|
|
||||||
// (We might also think that for SYN acks we could
|
|
||||||
// safely flip the roles, but that doesn't work
|
|
||||||
// for stealth scans.)
|
|
||||||
if ( IsLikelyServerPort(src_port, TRANSPORT_TCP) )
|
|
||||||
{ // connection is a candidate for flipping
|
|
||||||
if ( IsLikelyServerPort(dst_port, TRANSPORT_TCP) )
|
|
||||||
// Hmmm, both source and destination
|
|
||||||
// are plausible. Heuristic: flip only
|
|
||||||
// if (1) this isn't a SYN ACK (to avoid
|
|
||||||
// confusing stealth scans) and
|
|
||||||
// (2) dest port > src port (to favor
|
|
||||||
// more plausible servers).
|
|
||||||
flip_roles = ! (tcp_flags & TH_SYN) && src_port < dst_port;
|
|
||||||
else
|
|
||||||
// Source is plausible, destination isn't.
|
|
||||||
flip_roles = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if ( transport_proto == TRANSPORT_UDP )
|
|
||||||
flip_roles =
|
|
||||||
IsLikelyServerPort(src_port, TRANSPORT_UDP) &&
|
|
||||||
! IsLikelyServerPort(dst_port, TRANSPORT_UDP);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::Weird(const char* name, const Packet* pkt, const char* addl, const char* source)
|
void Manager::Weird(const char* name, const Packet* pkt, const char* addl, const char* source)
|
||||||
{
|
{
|
||||||
const char* weird_name = name;
|
const char* weird_name = name;
|
||||||
|
|
|
@ -60,14 +60,13 @@ public:
|
||||||
/**
|
/**
|
||||||
* Looks up the connection referred to by a given key.
|
* Looks up the connection referred to by a given key.
|
||||||
*
|
*
|
||||||
* @param key The key for the connection to search for.
|
* @param conn_key The key for the connection to search for.
|
||||||
* @param proto The transport protocol for the connection.
|
|
||||||
* @return The connection, or nullptr if one doesn't exist.
|
* @return The connection, or nullptr if one doesn't exist.
|
||||||
*/
|
*/
|
||||||
Connection* FindConnection(const zeek::detail::ConnKey& key, TransportProto proto);
|
Connection* FindConnection(const zeek::detail::ConnKey& conn_key);
|
||||||
|
|
||||||
void Remove(Session* s);
|
void Remove(Session* s);
|
||||||
void Insert(Session* c);
|
void Insert(Session* c, bool remove_existing=true);
|
||||||
|
|
||||||
// Generating connection_pending events for all connections
|
// Generating connection_pending events for all connections
|
||||||
// that are still active.
|
// that are still active.
|
||||||
|
@ -94,43 +93,6 @@ public:
|
||||||
[[deprecated("Remove in v5.1. Use CurrentSessions().")]]
|
[[deprecated("Remove in v5.1. Use CurrentSessions().")]]
|
||||||
unsigned int CurrentConnections() { return CurrentSessions(); }
|
unsigned int CurrentConnections() { return CurrentSessions(); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point for processing packets destined for session analyzers. This
|
|
||||||
* method is called by the packet analysis manager when after it has processed
|
|
||||||
* an IP-based packet, and shouldn't be called directly from other places.
|
|
||||||
*
|
|
||||||
* @param t The timestamp for this packet.
|
|
||||||
* @param pkt The packet being processed.
|
|
||||||
* @param len The number of bytes that haven't been processed yet by packet
|
|
||||||
* analysis.
|
|
||||||
*/
|
|
||||||
void ProcessTransportLayer(double t, const Packet *pkt, size_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
|
|
||||||
* or IPv6 header based on whether it's long enough to contain such a header,
|
|
||||||
* if version given in the header matches the proto argument, and also checks
|
|
||||||
* that the payload length field of that header matches the actual
|
|
||||||
* length of \a pkt given by \a caplen.
|
|
||||||
*
|
|
||||||
* @param caplen The length of \a pkt in bytes.
|
|
||||||
* @param pkt The inner IP packet data.
|
|
||||||
* @param proto Either IPPROTO_IPV6 or IPPROTO_IPV4 to indicate which IP
|
|
||||||
* protocol \a pkt corresponds to.
|
|
||||||
* @param inner The inner IP packet wrapper pointer to be allocated/assigned
|
|
||||||
* if \a pkt looks like a valid IP packet or at least long enough
|
|
||||||
* to hold an IP header.
|
|
||||||
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
|
|
||||||
* is greater than the supposed IP packet's payload length field, -2
|
|
||||||
* if the version of the inner header does not match proto or
|
|
||||||
* 1 if \a caplen is less than the supposed packet's payload length.
|
|
||||||
* In the -1 case, \a inner may still be non-null if \a caplen was
|
|
||||||
* long enough to be an IP header, and \a inner is always non-null
|
|
||||||
* for other return values.
|
|
||||||
*/
|
|
||||||
int ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
|
||||||
IP_Hdr*& inner);
|
|
||||||
|
|
||||||
unsigned int SessionMemoryUsage();
|
unsigned int SessionMemoryUsage();
|
||||||
unsigned int SessionMemoryUsageVals();
|
unsigned int SessionMemoryUsageVals();
|
||||||
|
|
||||||
|
@ -148,32 +110,6 @@ private:
|
||||||
|
|
||||||
using SessionMap = std::map<detail::Key, Session*>;
|
using SessionMap = std::map<detail::Key, Session*>;
|
||||||
|
|
||||||
Connection* NewConn(const zeek::detail::ConnKey& k, double t, const ConnTuple* id,
|
|
||||||
const u_char* data, int proto, uint32_t flow_label,
|
|
||||||
const Packet* pkt);
|
|
||||||
|
|
||||||
// Returns true if the port corresonds to an application
|
|
||||||
// for which there's a Bro analyzer (even if it might not
|
|
||||||
// be used by the present policy script), or it's more
|
|
||||||
// generally a likely server port, false otherwise.
|
|
||||||
//
|
|
||||||
// Note, port is in host order.
|
|
||||||
bool IsLikelyServerPort(uint32_t port, TransportProto transport_proto) const;
|
|
||||||
|
|
||||||
// Upon seeing the first packet of a connection, checks whether
|
|
||||||
// we want to analyze it (e.g., we may not want to look at partial
|
|
||||||
// connections), and, if yes, whether we should flip the roles of
|
|
||||||
// originator and responder (based on known ports or such).
|
|
||||||
// Use tcp_flags=0 for non-TCP.
|
|
||||||
bool WantConnection(uint16_t src_port, uint16_t dest_port,
|
|
||||||
TransportProto transport_proto,
|
|
||||||
uint8_t tcp_flags, bool& flip_roles);
|
|
||||||
|
|
||||||
// For a given protocol, checks whether the header's length as derived
|
|
||||||
// from lower-level headers or the length actually captured is less
|
|
||||||
// than that protocol's minimum header size.
|
|
||||||
bool CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen, const Packet *pkt);
|
|
||||||
|
|
||||||
// Inserts a new connection into the sessions map. If a connection with
|
// Inserts a new connection into the sessions map. If a connection with
|
||||||
// the same key already exists in the map, it will be overwritten by
|
// the same key already exists in the map, it will be overwritten by
|
||||||
// the new one. Connection count stats get updated either way (so most
|
// the new one. Connection count stats get updated either way (so most
|
||||||
|
|
|
@ -37,8 +37,8 @@ XXXXXXXXXX.XXXXXX - 2001:4f8:4:7:2e0:81ff:fe52:ffff 0 2001:4f8:4:7:2e0:81ff:fe52
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source
|
||||||
#types time string addr port addr port string string bool string string
|
#types time string addr port addr port string string bool string string
|
||||||
XXXXXXXXXX.XXXXXX - 10.0.0.1 0 192.0.43.10 0 internally_truncated_header - F zeek -
|
XXXXXXXXXX.XXXXXX - 10.0.0.1 0 192.0.43.10 0 internally_truncated_header - F zeek ICMP
|
||||||
XXXXXXXXXX.XXXXXX - 192.0.43.10 0 10.0.0.1 0 internally_truncated_header - F zeek -
|
XXXXXXXXXX.XXXXXX - 192.0.43.10 0 10.0.0.1 0 internally_truncated_header - F zeek ICMP
|
||||||
#close XXXX-XX-XX-XX-XX-XX
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
#separator \x09
|
#separator \x09
|
||||||
#set_separator ,
|
#set_separator ,
|
||||||
|
|
|
@ -57,6 +57,12 @@ scripts/base/init-bare.zeek
|
||||||
scripts/base/packet-protocols/iptunnel/main.zeek
|
scripts/base/packet-protocols/iptunnel/main.zeek
|
||||||
scripts/base/packet-protocols/vntag/__load__.zeek
|
scripts/base/packet-protocols/vntag/__load__.zeek
|
||||||
scripts/base/packet-protocols/vntag/main.zeek
|
scripts/base/packet-protocols/vntag/main.zeek
|
||||||
|
scripts/base/packet-protocols/udp/__load__.zeek
|
||||||
|
scripts/base/packet-protocols/udp/main.zeek
|
||||||
|
scripts/base/packet-protocols/tcp/__load__.zeek
|
||||||
|
scripts/base/packet-protocols/tcp/main.zeek
|
||||||
|
scripts/base/packet-protocols/icmp/__load__.zeek
|
||||||
|
scripts/base/packet-protocols/icmp/main.zeek
|
||||||
scripts/base/init-frameworks-and-bifs.zeek
|
scripts/base/init-frameworks-and-bifs.zeek
|
||||||
scripts/base/frameworks/logging/__load__.zeek
|
scripts/base/frameworks/logging/__load__.zeek
|
||||||
scripts/base/frameworks/logging/main.zeek
|
scripts/base/frameworks/logging/main.zeek
|
||||||
|
@ -125,7 +131,6 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_GTPv1.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_GTPv1.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_HTTP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_HTTP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_HTTP.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_HTTP.functions.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek
|
|
||||||
build/scripts/base/bif/plugins/Zeek_Ident.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_Ident.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_IMAP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_IMAP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_IRC.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_IRC.events.bif.zeek
|
||||||
|
@ -201,10 +206,11 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_Teredo.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_Teredo.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
|
||||||
build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileEntropy.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileEntropy.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileExtract.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileExtract.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
||||||
|
|
|
@ -57,6 +57,12 @@ scripts/base/init-bare.zeek
|
||||||
scripts/base/packet-protocols/iptunnel/main.zeek
|
scripts/base/packet-protocols/iptunnel/main.zeek
|
||||||
scripts/base/packet-protocols/vntag/__load__.zeek
|
scripts/base/packet-protocols/vntag/__load__.zeek
|
||||||
scripts/base/packet-protocols/vntag/main.zeek
|
scripts/base/packet-protocols/vntag/main.zeek
|
||||||
|
scripts/base/packet-protocols/udp/__load__.zeek
|
||||||
|
scripts/base/packet-protocols/udp/main.zeek
|
||||||
|
scripts/base/packet-protocols/tcp/__load__.zeek
|
||||||
|
scripts/base/packet-protocols/tcp/main.zeek
|
||||||
|
scripts/base/packet-protocols/icmp/__load__.zeek
|
||||||
|
scripts/base/packet-protocols/icmp/main.zeek
|
||||||
scripts/base/init-frameworks-and-bifs.zeek
|
scripts/base/init-frameworks-and-bifs.zeek
|
||||||
scripts/base/frameworks/logging/__load__.zeek
|
scripts/base/frameworks/logging/__load__.zeek
|
||||||
scripts/base/frameworks/logging/main.zeek
|
scripts/base/frameworks/logging/main.zeek
|
||||||
|
@ -125,7 +131,6 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_GTPv1.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_GTPv1.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_HTTP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_HTTP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_HTTP.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_HTTP.functions.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek
|
|
||||||
build/scripts/base/bif/plugins/Zeek_Ident.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_Ident.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_IMAP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_IMAP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_IRC.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_IRC.events.bif.zeek
|
||||||
|
@ -201,10 +206,11 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_Teredo.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_Teredo.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
|
||||||
build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileEntropy.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileEntropy.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileExtract.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileExtract.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
||||||
|
|
|
@ -572,9 +572,13 @@
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 32821, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 32821, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 34525, PacketAnalyzer::ANALYZER_IP)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 34525, PacketAnalyzer::ANALYZER_IP)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11_RADIO, 105, PacketAnalyzer::ANALYZER_IEEE802_11)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11_RADIO, 105, PacketAnalyzer::ANALYZER_IEEE802_11)) -> <no result>
|
||||||
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 1, PacketAnalyzer::ANALYZER_ICMP)) -> <no result>
|
||||||
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 17, PacketAnalyzer::ANALYZER_UDP)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE)) -> <no result>
|
||||||
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 58, PacketAnalyzer::ANALYZER_ICMP)) -> <no result>
|
||||||
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 6, PacketAnalyzer::ANALYZER_TCP)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2048, PacketAnalyzer::ANALYZER_IP)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2048, PacketAnalyzer::ANALYZER_IP)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2054, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2054, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
||||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
||||||
|
@ -915,6 +919,7 @@
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/hash, <...>/hash) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/hash, <...>/hash) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/hash_hrw, <...>/hash_hrw.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/hash_hrw, <...>/hash_hrw.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/http, <...>/http) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/http, <...>/http) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, base<...>/icmp, <...>/icmp) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/ieee802_11, <...>/ieee802_11) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/ieee802_11, <...>/ieee802_11) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/ieee802_11_radio, <...>/ieee802_11_radio) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/ieee802_11_radio, <...>/ieee802_11_radio) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/imap, <...>/imap) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/imap, <...>/imap) -> -1
|
||||||
|
@ -979,10 +984,12 @@
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/supervisor, <...>/supervisor) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/supervisor, <...>/supervisor) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/supervisor.bif, <...>/supervisor.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/supervisor.bif, <...>/supervisor.bif.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/syslog, <...>/syslog) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/syslog, <...>/syslog) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, base<...>/tcp, <...>/tcp) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/thresholds, <...>/thresholds.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/thresholds, <...>/thresholds.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/time, <...>/time.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/time, <...>/time.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/tunnels, <...>/tunnels) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/tunnels, <...>/tunnels) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/types.bif, <...>/types.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/types.bif, <...>/types.bif.zeek) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, base<...>/udp, <...>/udp) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/urls, <...>/urls.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/urls, <...>/urls.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/utils, <...>/utils.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/utils, <...>/utils.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, base<...>/version, <...>/version.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, base<...>/version, <...>/version.zeek) -> -1
|
||||||
|
@ -1582,9 +1589,13 @@
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 32821, PacketAnalyzer::ANALYZER_ARP))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 32821, PacketAnalyzer::ANALYZER_ARP))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 34525, PacketAnalyzer::ANALYZER_IP))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11, 34525, PacketAnalyzer::ANALYZER_IP))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11_RADIO, 105, PacketAnalyzer::ANALYZER_IEEE802_11))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IEEE802_11_RADIO, 105, PacketAnalyzer::ANALYZER_IEEE802_11))
|
||||||
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 1, PacketAnalyzer::ANALYZER_ICMP))
|
||||||
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 17, PacketAnalyzer::ANALYZER_UDP))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE))
|
||||||
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 58, PacketAnalyzer::ANALYZER_ICMP))
|
||||||
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 6, PacketAnalyzer::ANALYZER_TCP))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2048, PacketAnalyzer::ANALYZER_IP))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2048, PacketAnalyzer::ANALYZER_IP))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2054, PacketAnalyzer::ANALYZER_ARP))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 2054, PacketAnalyzer::ANALYZER_ARP))
|
||||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP))
|
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP))
|
||||||
|
@ -1925,6 +1936,7 @@
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/hash, <...>/hash)
|
0.000000 MetaHookPre LoadFile(0, base<...>/hash, <...>/hash)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/hash_hrw, <...>/hash_hrw.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/hash_hrw, <...>/hash_hrw.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/http, <...>/http)
|
0.000000 MetaHookPre LoadFile(0, base<...>/http, <...>/http)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, base<...>/icmp, <...>/icmp)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/ieee802_11, <...>/ieee802_11)
|
0.000000 MetaHookPre LoadFile(0, base<...>/ieee802_11, <...>/ieee802_11)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/ieee802_11_radio, <...>/ieee802_11_radio)
|
0.000000 MetaHookPre LoadFile(0, base<...>/ieee802_11_radio, <...>/ieee802_11_radio)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/imap, <...>/imap)
|
0.000000 MetaHookPre LoadFile(0, base<...>/imap, <...>/imap)
|
||||||
|
@ -1989,10 +2001,12 @@
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/supervisor, <...>/supervisor)
|
0.000000 MetaHookPre LoadFile(0, base<...>/supervisor, <...>/supervisor)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/supervisor.bif, <...>/supervisor.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/supervisor.bif, <...>/supervisor.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/syslog, <...>/syslog)
|
0.000000 MetaHookPre LoadFile(0, base<...>/syslog, <...>/syslog)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, base<...>/tcp, <...>/tcp)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/thresholds, <...>/thresholds.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/thresholds, <...>/thresholds.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/time, <...>/time.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/time, <...>/time.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/tunnels, <...>/tunnels)
|
0.000000 MetaHookPre LoadFile(0, base<...>/tunnels, <...>/tunnels)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/types.bif, <...>/types.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/types.bif, <...>/types.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, base<...>/udp, <...>/udp)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/urls, <...>/urls.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/urls, <...>/urls.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/utils, <...>/utils.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/utils, <...>/utils.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, base<...>/version, <...>/version.zeek)
|
0.000000 MetaHookPre LoadFile(0, base<...>/version, <...>/version.zeek)
|
||||||
|
@ -2591,9 +2605,13 @@
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IEEE802_11, 32821, PacketAnalyzer::ANALYZER_ARP)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IEEE802_11, 32821, PacketAnalyzer::ANALYZER_ARP)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IEEE802_11, 34525, PacketAnalyzer::ANALYZER_IP)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IEEE802_11, 34525, PacketAnalyzer::ANALYZER_IP)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IEEE802_11_RADIO, 105, PacketAnalyzer::ANALYZER_IEEE802_11)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IEEE802_11_RADIO, 105, PacketAnalyzer::ANALYZER_IEEE802_11)
|
||||||
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 1, PacketAnalyzer::ANALYZER_ICMP)
|
||||||
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 17, PacketAnalyzer::ANALYZER_UDP)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 4, PacketAnalyzer::ANALYZER_IPTUNNEL)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 41, PacketAnalyzer::ANALYZER_IPTUNNEL)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 47, PacketAnalyzer::ANALYZER_GRE)
|
||||||
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 58, PacketAnalyzer::ANALYZER_ICMP)
|
||||||
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 6, PacketAnalyzer::ANALYZER_TCP)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 2048, PacketAnalyzer::ANALYZER_IP)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 2048, PacketAnalyzer::ANALYZER_IP)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 2054, PacketAnalyzer::ANALYZER_ARP)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 2054, PacketAnalyzer::ANALYZER_ARP)
|
||||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP)
|
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP)
|
||||||
|
@ -2946,6 +2964,7 @@
|
||||||
0.000000 | HookLoadFile base<...>/hash <...>/hash
|
0.000000 | HookLoadFile base<...>/hash <...>/hash
|
||||||
0.000000 | HookLoadFile base<...>/hash_hrw <...>/hash_hrw.zeek
|
0.000000 | HookLoadFile base<...>/hash_hrw <...>/hash_hrw.zeek
|
||||||
0.000000 | HookLoadFile base<...>/http <...>/http
|
0.000000 | HookLoadFile base<...>/http <...>/http
|
||||||
|
0.000000 | HookLoadFile base<...>/icmp <...>/icmp
|
||||||
0.000000 | HookLoadFile base<...>/ieee802_11 <...>/ieee802_11
|
0.000000 | HookLoadFile base<...>/ieee802_11 <...>/ieee802_11
|
||||||
0.000000 | HookLoadFile base<...>/ieee802_11_radio <...>/ieee802_11_radio
|
0.000000 | HookLoadFile base<...>/ieee802_11_radio <...>/ieee802_11_radio
|
||||||
0.000000 | HookLoadFile base<...>/imap <...>/imap
|
0.000000 | HookLoadFile base<...>/imap <...>/imap
|
||||||
|
@ -3010,10 +3029,12 @@
|
||||||
0.000000 | HookLoadFile base<...>/supervisor <...>/supervisor
|
0.000000 | HookLoadFile base<...>/supervisor <...>/supervisor
|
||||||
0.000000 | HookLoadFile base<...>/supervisor.bif <...>/supervisor.bif.zeek
|
0.000000 | HookLoadFile base<...>/supervisor.bif <...>/supervisor.bif.zeek
|
||||||
0.000000 | HookLoadFile base<...>/syslog <...>/syslog
|
0.000000 | HookLoadFile base<...>/syslog <...>/syslog
|
||||||
|
0.000000 | HookLoadFile base<...>/tcp <...>/tcp
|
||||||
0.000000 | HookLoadFile base<...>/thresholds <...>/thresholds.zeek
|
0.000000 | HookLoadFile base<...>/thresholds <...>/thresholds.zeek
|
||||||
0.000000 | HookLoadFile base<...>/time <...>/time.zeek
|
0.000000 | HookLoadFile base<...>/time <...>/time.zeek
|
||||||
0.000000 | HookLoadFile base<...>/tunnels <...>/tunnels
|
0.000000 | HookLoadFile base<...>/tunnels <...>/tunnels
|
||||||
0.000000 | HookLoadFile base<...>/types.bif <...>/types.bif.zeek
|
0.000000 | HookLoadFile base<...>/types.bif <...>/types.bif.zeek
|
||||||
|
0.000000 | HookLoadFile base<...>/udp <...>/udp
|
||||||
0.000000 | HookLoadFile base<...>/urls <...>/urls.zeek
|
0.000000 | HookLoadFile base<...>/urls <...>/urls.zeek
|
||||||
0.000000 | HookLoadFile base<...>/utils <...>/utils.zeek
|
0.000000 | HookLoadFile base<...>/utils <...>/utils.zeek
|
||||||
0.000000 | HookLoadFile base<...>/version <...>/version.zeek
|
0.000000 | HookLoadFile base<...>/version <...>/version.zeek
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue