mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Add base class for IP-based packet analyzers
This commit is contained in:
parent
3e1692676d
commit
c1f0d312b5
23 changed files with 781 additions and 421 deletions
|
@ -15,8 +15,8 @@ event zeek_init() &priority=20
|
|||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_IPV6, PacketAnalyzer::ANALYZER_IPTUNNEL);
|
||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_GRE, PacketAnalyzer::ANALYZER_GRE);
|
||||
|
||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_TCP, PacketAnalyzer::ANALYZER_TCP_PKT);
|
||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_UDP, PacketAnalyzer::ANALYZER_UDP_PKT);
|
||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_ICMP, PacketAnalyzer::ANALYZER_ICMP_PKT);
|
||||
PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, IPPROTO_ICMP6, PacketAnalyzer::ANALYZER_ICMP_PKT);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "zeek/analyzer/protocol/stepping-stone/SteppingStone.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/plugin/Manager.h"
|
||||
|
||||
|
@ -498,6 +499,57 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Manager::BuildSessionAnalyzerTree(Connection* conn, packet_analysis::IP::IPBasedAnalyzer* analyzer)
|
||||
{
|
||||
packet_analysis::IP::IPBasedTransportAnalyzer* root = nullptr;
|
||||
analyzer::pia::PIA* pia = nullptr;
|
||||
bool check_port = false;
|
||||
|
||||
analyzer->CreateTransportAnalyzer(conn, root, pia, check_port);
|
||||
|
||||
bool scheduled = 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 )
|
||||
{
|
||||
int resp_port = ntohs(conn->RespPort());
|
||||
tag_set* ports = LookupPort(conn->ConnTransport(), resp_port, false);
|
||||
|
||||
if ( ports )
|
||||
{
|
||||
for ( tag_set::const_iterator j = ports->begin(); j != ports->end(); ++j )
|
||||
{
|
||||
Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(*j, conn);
|
||||
|
||||
if ( ! analyzer )
|
||||
continue;
|
||||
|
||||
root->AddChildAnalyzer(analyzer, false);
|
||||
DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d",
|
||||
analyzer_mgr->GetComponentName(*j).c_str(), resp_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root->AddExtraAnalyzers(conn);
|
||||
|
||||
if ( pia )
|
||||
root->AddChildAnalyzer(pia->AsAnalyzer());
|
||||
|
||||
conn->SetRootAnalyzer(root, pia);
|
||||
root->Init();
|
||||
root->InitChildren();
|
||||
|
||||
PLUGIN_HOOK_VOID(HOOK_SETUP_ANALYZER_TREE, HookSetupAnalyzerTree(conn));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Manager::ExpireScheduledAnalyzers()
|
||||
{
|
||||
if ( ! run_state::network_time )
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#include "zeek/analyzer/analyzer.bif.h"
|
||||
|
||||
namespace zeek {
|
||||
|
||||
namespace packet_analysis::IP { class IPBasedAnalyzer; }
|
||||
|
||||
namespace analyzer {
|
||||
|
||||
/**
|
||||
|
@ -244,11 +247,23 @@ public:
|
|||
*
|
||||
* @param conn The connection to add the initial set of analyzers to.
|
||||
*
|
||||
* @return False if the tree cannot be build; that's usually an
|
||||
* internally error.
|
||||
* @return False if the tree cannot be built; that's usually an
|
||||
* internal error.
|
||||
*/
|
||||
bool BuildInitialAnalyzerTree(Connection* conn);
|
||||
|
||||
/**
|
||||
* Builds the analyzer tree used by transport-layer analyzers in the
|
||||
* packet analysis framework.
|
||||
*
|
||||
* @param conn The connection to add the initial set of analyzers to.
|
||||
* @param analyzer The packet analyzer requesting the tree.
|
||||
* @return False if the tree cannot be built; that's usually an
|
||||
* internal error.
|
||||
*/
|
||||
bool BuildSessionAnalyzerTree(Connection* conn,
|
||||
packet_analysis::IP::IPBasedAnalyzer* analyzer);
|
||||
|
||||
/**
|
||||
* Schedules a particular analyzer for an upcoming connection. Once
|
||||
* the connection is seen, BuildInitAnalyzerTree() will add the
|
||||
|
|
|
@ -189,6 +189,13 @@ public:
|
|||
*/
|
||||
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
|
||||
// stored with the packet so they stay available as the packet is passed
|
||||
// around.
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
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);
|
||||
|
||||
|
@ -79,12 +80,17 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet,
|
|||
inner_analyzer = default_analyzer;
|
||||
|
||||
if ( inner_analyzer == nullptr )
|
||||
{
|
||||
if ( report_unknown_protocols )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s failed, could not find analyzer for identifier %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
packet_mgr->ReportUnknownProtocol(GetAnalyzerName(), identifier, data, len);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||
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.",
|
||||
GetAnalyzerName());
|
||||
|
||||
if ( report_unknown_protocols )
|
||||
Weird("no_suitable_analyzer_found", packet);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,11 @@ public:
|
|||
*
|
||||
* @param name The name for the type of analyzer. The name must match
|
||||
* 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.
|
||||
|
@ -165,6 +168,11 @@ private:
|
|||
Dispatcher dispatcher;
|
||||
AnalyzerPtr default_analyzer = nullptr;
|
||||
|
||||
/**
|
||||
* Flag for whether to report unknown protocols in ForwardPacket.
|
||||
*/
|
||||
bool report_unknown_protocols = true;
|
||||
|
||||
void Init(const Tag& tag);
|
||||
};
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ void Manager::ProcessPacket(Packet* packet)
|
|||
bool dumped_packet = false;
|
||||
if ( packet->dump_packet || zeek::detail::record_all_packets )
|
||||
{
|
||||
DumpPacket(packet);
|
||||
DumpPacket(packet, packet->dump_size);
|
||||
dumped_packet = true;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ void Manager::ProcessPacket(Packet* packet)
|
|||
|
||||
// Check whether packet should be recorded based on session analysis
|
||||
if ( packet->dump_packet && ! dumped_packet )
|
||||
DumpPacket(packet);
|
||||
DumpPacket(packet, packet->dump_size);
|
||||
}
|
||||
|
||||
bool Manager::ProcessInnerPacket(Packet* packet)
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/packet_analysis/protocol/icmp/ICMP.h"
|
||||
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/session/Manager.h"
|
||||
|
||||
using namespace zeek::packet_analysis::ICMP;
|
||||
using namespace zeek::packet_analysis::IP;
|
||||
|
||||
ICMPAnalyzer::ICMPAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("ICMP_PKT")
|
||||
ICMPAnalyzer::ICMPAnalyzer() : IPBasedAnalyzer("ICMP", TRANSPORT_ICMP, ICMP_PORT_MASK, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -17,6 +20,96 @@ ICMPAnalyzer::~ICMPAnalyzer()
|
|||
|
||||
bool ICMPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||
{
|
||||
session_mgr->ProcessTransportLayer(run_state::processing_start_time, packet, len);
|
||||
if ( ! CheckHeaderTrunc(ICMP_MINLEN, len, packet) )
|
||||
return false;
|
||||
|
||||
ConnTuple id;
|
||||
id.src_addr = packet->ip_hdr->SrcAddr();
|
||||
id.dst_addr = packet->ip_hdr->DstAddr();
|
||||
id.proto = TRANSPORT_ICMP;
|
||||
|
||||
const struct icmp* icmpp = (const struct icmp *) data;
|
||||
id.src_port = htons(icmpp->icmp_type);
|
||||
|
||||
if ( packet->proto == IPPROTO_ICMP )
|
||||
id.dst_port = htons(ICMP4_counterpart(icmpp->icmp_type, icmpp->icmp_code, id.is_one_way));
|
||||
else if ( packet->proto == IPPROTO_ICMPV6 )
|
||||
id.dst_port = htons(ICMP6_counterpart(icmpp->icmp_type, icmpp->icmp_code, id.is_one_way));
|
||||
else
|
||||
reporter->InternalError("Reached ICMP packet analyzer with unknown packet protocol %x",
|
||||
packet->proto);
|
||||
|
||||
ProcessConnection(id, packet, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ICMPAnalyzer::ContinueProcessing(Connection* c, double t, bool is_orig, int remaining, Packet* pkt)
|
||||
{
|
||||
}
|
||||
|
||||
void ICMPAnalyzer::CreateTransportAnalyzer(Connection* conn, IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_port)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int ICMPAnalyzer::ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||
{
|
||||
is_one_way = false;
|
||||
|
||||
// Return the counterpart type if one exists. This allows us
|
||||
// to track corresponding ICMP requests/replies.
|
||||
// Note that for the two-way ICMP messages, icmp_code is
|
||||
// always 0 (RFC 792).
|
||||
switch ( icmp_type ) {
|
||||
case ICMP_ECHO: return ICMP_ECHOREPLY;
|
||||
case ICMP_ECHOREPLY: return ICMP_ECHO;
|
||||
|
||||
case ICMP_TSTAMP: return ICMP_TSTAMPREPLY;
|
||||
case ICMP_TSTAMPREPLY: return ICMP_TSTAMP;
|
||||
|
||||
case ICMP_IREQ: return ICMP_IREQREPLY;
|
||||
case ICMP_IREQREPLY: return ICMP_IREQ;
|
||||
|
||||
case ICMP_ROUTERSOLICIT: return ICMP_ROUTERADVERT;
|
||||
case ICMP_ROUTERADVERT: return ICMP_ROUTERSOLICIT;
|
||||
|
||||
case ICMP_MASKREQ: return ICMP_MASKREPLY;
|
||||
case ICMP_MASKREPLY: return ICMP_MASKREQ;
|
||||
|
||||
default: is_one_way = true; return icmp_code;
|
||||
}
|
||||
}
|
||||
|
||||
int ICMPAnalyzer::ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||
{
|
||||
is_one_way = false;
|
||||
|
||||
switch ( icmp_type ) {
|
||||
case ICMP6_ECHO_REQUEST: return ICMP6_ECHO_REPLY;
|
||||
case ICMP6_ECHO_REPLY: return ICMP6_ECHO_REQUEST;
|
||||
|
||||
case ND_ROUTER_SOLICIT: return ND_ROUTER_ADVERT;
|
||||
case ND_ROUTER_ADVERT: return ND_ROUTER_SOLICIT;
|
||||
|
||||
case ND_NEIGHBOR_SOLICIT: return ND_NEIGHBOR_ADVERT;
|
||||
case ND_NEIGHBOR_ADVERT: return ND_NEIGHBOR_SOLICIT;
|
||||
|
||||
case MLD_LISTENER_QUERY: return MLD_LISTENER_REPORT;
|
||||
case MLD_LISTENER_REPORT: return MLD_LISTENER_QUERY;
|
||||
|
||||
// ICMP node information query and response respectively (not defined in
|
||||
// icmp6.h)
|
||||
case 139: return 140;
|
||||
case 140: return 139;
|
||||
|
||||
// Home Agent Address Discovery Request Message and reply
|
||||
case 144: return 145;
|
||||
case 145: return 144;
|
||||
|
||||
// TODO: Add further counterparts.
|
||||
|
||||
default: is_one_way = true; return icmp_code;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
#include "zeek/packet_analysis/Analyzer.h"
|
||||
#include "zeek/packet_analysis/Component.h"
|
||||
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
|
||||
|
||||
namespace zeek::packet_analysis::ICMP {
|
||||
|
||||
class ICMPAnalyzer : public Analyzer {
|
||||
class ICMPAnalyzer final : public IP::IPBasedAnalyzer {
|
||||
public:
|
||||
ICMPAnalyzer();
|
||||
~ICMPAnalyzer() override;
|
||||
|
@ -19,8 +20,21 @@ public:
|
|||
return std::make_shared<ICMPAnalyzer>();
|
||||
}
|
||||
|
||||
void CreateTransportAnalyzer(Connection* conn, IP::IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_port) override;
|
||||
|
||||
protected:
|
||||
|
||||
void ContinueProcessing(Connection* c, double t, bool is_orig, int remaining,
|
||||
Packet* pkt) override;
|
||||
|
||||
private:
|
||||
|
||||
// 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);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class Plugin : public zeek::plugin::Plugin {
|
|||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("ICMP_PKT",
|
||||
AddComponent(new zeek::packet_analysis::Component("ICMP",
|
||||
zeek::packet_analysis::ICMP::ICMPAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
|
|
|
@ -4,5 +4,5 @@ include(ZeekPlugin)
|
|||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(PacketAnalyzer IP)
|
||||
zeek_plugin_cc(IP.cc Plugin.cc)
|
||||
zeek_plugin_cc(IP.cc IPBasedAnalyzer.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
||||
|
|
209
src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc
Normal file
209
src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc
Normal file
|
@ -0,0 +1,209 @@
|
|||
// 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"
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
void IPBasedAnalyzer::ProcessConnection(const ConnTuple& conn_id, Packet* pkt, size_t remaining)
|
||||
{
|
||||
const std::unique_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
|
||||
detail::ConnKey key(conn_id);
|
||||
|
||||
Connection* conn = session_mgr->FindConnection(key);
|
||||
|
||||
if ( ! conn )
|
||||
{
|
||||
conn = NewConn(&conn_id, 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(&conn_id, key, pkt);
|
||||
if ( conn )
|
||||
session_mgr->Insert(conn, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
conn->CheckEncapsulation(pkt->encap);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! conn )
|
||||
return;
|
||||
|
||||
bool is_orig = (conn_id.src_addr == conn->OrigAddr()) &&
|
||||
(conn_id.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;
|
||||
|
||||
ContinueProcessing(conn, run_state::processing_start_time, is_orig, remaining, 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(),
|
||||
remaining, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 ( ! analyzer_mgr->BuildSessionAnalyzerTree(conn, this) )
|
||||
{
|
||||
conn->Done();
|
||||
Unref(conn);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( new_connection )
|
||||
conn->Event(new_connection, nullptr);
|
||||
|
||||
return conn;
|
||||
}
|
182
src/packet_analysis/protocol/ip/IPBasedAnalyzer.h
Normal file
182
src/packet_analysis/protocol/ip/IPBasedAnalyzer.h
Normal file
|
@ -0,0 +1,182 @@
|
|||
// 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/analyzer/Analyzer.h"
|
||||
#include "zeek/analyzer/Manager.h"
|
||||
|
||||
namespace zeek::analyzer::pia { class PIA; }
|
||||
|
||||
namespace zeek::packet_analysis::IP {
|
||||
|
||||
class IPBasedTransportAnalyzer;
|
||||
|
||||
/**
|
||||
* A base class for any packet analyzer 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;
|
||||
|
||||
/**
|
||||
* 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; }
|
||||
|
||||
/**
|
||||
* TODO: comment
|
||||
*/
|
||||
virtual void CreateTransportAnalyzer(Connection* conn, IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_port) = 0;
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
* Entry point for child classes to call to do the actual heavy lifting for
|
||||
* processing a packet and extracting a connection out of it.
|
||||
*
|
||||
* @param conn_id The connection ID generated by the child class.
|
||||
* @param pkt The packet being processed.
|
||||
* @param remaining The number of bytes remaining to be processed in the packet.
|
||||
*/
|
||||
void ProcessConnection(const ConnTuple& conn_id, Packet* pkt, size_t remaining);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
|
||||
/**
|
||||
* 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 ContinueProcessing(Connection* conn, double t, bool is_orig, int remaining,
|
||||
Packet* pkt) {}
|
||||
|
||||
// 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);
|
||||
|
||||
TransportProto transport;
|
||||
uint32_t server_port_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 IPBasedTransportAnalyzer : public zeek::analyzer::TransportLayerAnalyzer {
|
||||
|
||||
public:
|
||||
|
||||
IPBasedTransportAnalyzer(const char* name, Connection* conn)
|
||||
: TransportLayerAnalyzer(name, conn) { }
|
||||
|
||||
/**
|
||||
* Sets the parent packet analyzer for this transport analyzer. This can't be passed to
|
||||
* the constructor due to the way that TransportLayerAnalyzer 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.
|
||||
*/
|
||||
bool IsReuse(double t, const u_char* pkt) override { return parent->IsReuse(t, 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;
|
||||
|
||||
protected:
|
||||
|
||||
IPBasedAnalyzer* parent;
|
||||
};
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@ class Plugin : public zeek::plugin::Plugin {
|
|||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("TCP_PKT",
|
||||
AddComponent(new zeek::packet_analysis::Component("TCP",
|
||||
zeek::packet_analysis::TCP::TCPAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
#include "zeek/packet_analysis/protocol/tcp/TCP.h"
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/session/Manager.h"
|
||||
|
||||
using namespace zeek::packet_analysis::TCP;
|
||||
using namespace zeek::packet_analysis::IP;
|
||||
|
||||
TCPAnalyzer::TCPAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("TCP_PKT")
|
||||
TCPAnalyzer::TCPAnalyzer() : IPBasedAnalyzer("TCP", TRANSPORT_TCP, TCP_PORT_MASK, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -17,6 +16,68 @@ TCPAnalyzer::~TCPAnalyzer()
|
|||
|
||||
bool TCPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||
{
|
||||
session_mgr->ProcessTransportLayer(run_state::processing_start_time, packet, len);
|
||||
uint32_t min_hdr_len = sizeof(struct tcphdr);
|
||||
if ( ! CheckHeaderTrunc(min_hdr_len, len, packet) )
|
||||
return false;
|
||||
|
||||
ConnTuple id;
|
||||
id.src_addr = packet->ip_hdr->SrcAddr();
|
||||
id.dst_addr = packet->ip_hdr->DstAddr();
|
||||
|
||||
data = packet->ip_hdr->Payload();
|
||||
|
||||
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;
|
||||
|
||||
ProcessConnection(id, packet, len);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void TCPAnalyzer::CreateTransportAnalyzer(Connection* conn, IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_port)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
#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 : public Analyzer {
|
||||
class TCPAnalyzer final : public IP::IPBasedAnalyzer {
|
||||
public:
|
||||
TCPAnalyzer();
|
||||
~TCPAnalyzer() override;
|
||||
|
@ -19,8 +20,25 @@ public:
|
|||
return std::make_shared<TCPAnalyzer>();
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateTransportAnalyzer(Connection* conn, IP::IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_port) override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class Plugin : public zeek::plugin::Plugin {
|
|||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("UDP_PKT",
|
||||
AddComponent(new zeek::packet_analysis::Component("UDP",
|
||||
zeek::packet_analysis::UDP::UDPAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
#include "zeek/packet_analysis/protocol/udp/UDP.h"
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/session/Manager.h"
|
||||
|
||||
using namespace zeek::packet_analysis::UDP;
|
||||
using namespace zeek::packet_analysis::IP;
|
||||
|
||||
UDPAnalyzer::UDPAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("UDP_PKT")
|
||||
UDPAnalyzer::UDPAnalyzer() : IPBasedAnalyzer("UDP", TRANSPORT_UDP, UDP_PORT_MASK, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -17,6 +16,31 @@ UDPAnalyzer::~UDPAnalyzer()
|
|||
|
||||
bool UDPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||
{
|
||||
session_mgr->ProcessTransportLayer(run_state::processing_start_time, packet, len);
|
||||
uint32_t min_hdr_len = sizeof(struct udphdr);
|
||||
if ( ! CheckHeaderTrunc(min_hdr_len, len, packet) )
|
||||
return false;
|
||||
|
||||
ConnTuple id;
|
||||
id.src_addr = packet->ip_hdr->SrcAddr();
|
||||
id.dst_addr = packet->ip_hdr->DstAddr();
|
||||
const struct udphdr* up = (const struct udphdr *) packet->ip_hdr->Payload();
|
||||
id.src_port = up->uh_sport;
|
||||
id.dst_port = up->uh_dport;
|
||||
id.is_one_way = false;
|
||||
id.proto = TRANSPORT_UDP;
|
||||
|
||||
ProcessConnection(id, packet, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
void UDPAnalyzer::CreateTransportAnalyzer(Connection* conn, IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_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;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
#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 : public Analyzer {
|
||||
class UDPAnalyzer : public IP::IPBasedAnalyzer {
|
||||
public:
|
||||
UDPAnalyzer();
|
||||
~UDPAnalyzer() override;
|
||||
|
@ -19,8 +20,25 @@ public:
|
|||
return std::make_shared<UDPAnalyzer>();
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateTransportAnalyzer(Connection* conn, IP::IPBasedTransportAnalyzer*& root,
|
||||
analyzer::pia::PIA*& pia, bool& check_port) override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -107,197 +107,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const auto& vt = v->GetType();
|
||||
|
@ -353,6 +162,17 @@ Connection* Manager::FindConnection(Val* v)
|
|||
return conn;
|
||||
}
|
||||
|
||||
Connection* Manager::FindConnection(const zeek::detail::ConnKey& conn_key)
|
||||
{
|
||||
detail::Key key(&conn_key, sizeof(conn_key), false);
|
||||
|
||||
auto it = session_map.find(key);
|
||||
if ( it != session_map.end() )
|
||||
return dynamic_cast<Connection*>(it->second);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Manager::Remove(Session* s)
|
||||
{
|
||||
if ( s->IsInSessionTable() )
|
||||
|
@ -381,16 +201,20 @@ void Manager::Remove(Session* s)
|
|||
}
|
||||
}
|
||||
|
||||
void Manager::Insert(Session* s)
|
||||
void Manager::Insert(Session* s, bool remove_existing)
|
||||
{
|
||||
Session* old = nullptr;
|
||||
detail::Key key = s->SessionKey(true);
|
||||
|
||||
if ( remove_existing )
|
||||
{
|
||||
auto it = session_map.find(key);
|
||||
if ( it != session_map.end() )
|
||||
old = it->second;
|
||||
|
||||
session_map.erase(key);
|
||||
}
|
||||
|
||||
InsertSession(std::move(key), s);
|
||||
|
||||
if ( old && old != s )
|
||||
|
@ -445,140 +269,6 @@ void Manager::GetStats(Stats& s)
|
|||
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)
|
||||
{
|
||||
const char* weird_name = name;
|
||||
|
|
|
@ -60,14 +60,13 @@ public:
|
|||
/**
|
||||
* Looks up the connection referred to by a given key.
|
||||
*
|
||||
* @param key The key for the connection to search for.
|
||||
* @param proto The transport protocol for the connection.
|
||||
* @param conn_key The key for the connection to search for.
|
||||
* @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 Insert(Session* c);
|
||||
void Insert(Session* c, bool remove_existing=true);
|
||||
|
||||
// Generating connection_pending events for all connections
|
||||
// that are still active.
|
||||
|
@ -94,18 +93,6 @@ public:
|
|||
[[deprecated("Remove in v5.1. Use 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);
|
||||
|
||||
unsigned int SessionMemoryUsage();
|
||||
unsigned int SessionMemoryUsageVals();
|
||||
|
||||
|
@ -123,32 +110,6 @@ private:
|
|||
|
||||
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
|
||||
// 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
|
||||
|
|
|
@ -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
|
||||
#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
|
||||
XXXXXXXXXX.XXXXXX - 10.0.0.1 0 192.0.43.10 0 internally_truncated_header - F zeek -
|
||||
XXXXXXXXXX.XXXXXX - 192.0.43.10 0 10.0.0.1 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 ICMP
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
||||
#separator \x09
|
||||
#set_separator ,
|
||||
|
|
|
@ -572,13 +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, 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_IP, 1, PacketAnalyzer::ANALYZER_ICMP_PKT)) -> <no result>
|
||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 17, PacketAnalyzer::ANALYZER_UDP_PKT)) -> <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, 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, 58, PacketAnalyzer::ANALYZER_ICMP_PKT)) -> <no result>
|
||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 6, PacketAnalyzer::ANALYZER_TCP_PKT)) -> <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, 2054, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
||||
0.000000 MetaHookPost CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP)) -> <no result>
|
||||
|
@ -1589,13 +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, 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_IP, 1, PacketAnalyzer::ANALYZER_ICMP_PKT))
|
||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 17, PacketAnalyzer::ANALYZER_UDP_PKT))
|
||||
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, 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, 58, PacketAnalyzer::ANALYZER_ICMP_PKT))
|
||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_IP, 6, PacketAnalyzer::ANALYZER_TCP_PKT))
|
||||
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, 2054, PacketAnalyzer::ANALYZER_ARP))
|
||||
0.000000 MetaHookPre CallFunction(PacketAnalyzer::register_packet_analyzer, <frame>, (PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP))
|
||||
|
@ -2605,13 +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, 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_IP, 1, PacketAnalyzer::ANALYZER_ICMP_PKT)
|
||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 17, PacketAnalyzer::ANALYZER_UDP_PKT)
|
||||
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, 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, 58, PacketAnalyzer::ANALYZER_ICMP_PKT)
|
||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_IP, 6, PacketAnalyzer::ANALYZER_TCP_PKT)
|
||||
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, 2054, PacketAnalyzer::ANALYZER_ARP)
|
||||
0.000000 | HookCallFunction PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL, 32821, PacketAnalyzer::ANALYZER_ARP)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue