mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Move dispatching into packet analyzers.
WIP that updates only the Ethernet analyzer.
This commit is contained in:
parent
96d0e11bb8
commit
9feda100b9
13 changed files with 105 additions and 88 deletions
|
@ -1,11 +1,11 @@
|
|||
@load base/packet-protocols/default
|
||||
#@load base/packet-protocols/default
|
||||
@load base/packet-protocols/ethernet
|
||||
@load base/packet-protocols/fddi
|
||||
@load base/packet-protocols/ieee802_11
|
||||
@load base/packet-protocols/ieee802_11_radio
|
||||
@load base/packet-protocols/linux_sll
|
||||
@load base/packet-protocols/nflog
|
||||
@load base/packet-protocols/null
|
||||
@load base/packet-protocols/ppp_serial
|
||||
@load base/packet-protocols/pppoe
|
||||
@load base/packet-protocols/vlan
|
||||
#@load base/packet-protocols/fddi
|
||||
#@load base/packet-protocols/ieee802_11
|
||||
#@load base/packet-protocols/ieee802_11_radio
|
||||
#@load base/packet-protocols/linux_sll
|
||||
#@load base/packet-protocols/nflog
|
||||
#@load base/packet-protocols/null
|
||||
#@load base/packet-protocols/ppp_serial
|
||||
#@load base/packet-protocols/pppoe
|
||||
#@load base/packet-protocols/vlan
|
||||
|
|
|
@ -4,13 +4,13 @@ const DLT_EN10MB : count = 1;
|
|||
|
||||
redef PacketAnalyzer::config_map += {
|
||||
PacketAnalyzer::ConfigEntry($identifier=DLT_EN10MB, $analyzer=PacketAnalyzer::ANALYZER_ETHERNET),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8847, $analyzer=PacketAnalyzer::ANALYZER_MPLS),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8847, $analyzer=PacketAnalyzer::ANALYZER_MPLS),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x0800, $analyzer=PacketAnalyzer::ANALYZER_IPV4),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x86DD, $analyzer=PacketAnalyzer::ANALYZER_IPV6),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x0806, $analyzer=PacketAnalyzer::ANALYZER_ARP),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8035, $analyzer=PacketAnalyzer::ANALYZER_ARP),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8100, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x88A8, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x9100, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8864, $analyzer=PacketAnalyzer::ANALYZER_PPPOE)
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x0806, $analyzer=PacketAnalyzer::ANALYZER_ARP),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8035, $analyzer=PacketAnalyzer::ANALYZER_ARP),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8100, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x88A8, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x9100, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8864, $analyzer=PacketAnalyzer::ANALYZER_PPPOE)
|
||||
};
|
||||
|
|
|
@ -44,4 +44,23 @@ bool Analyzer::IsAnalyzer(const char* name)
|
|||
return packet_mgr->GetComponentName(tag).compare(name) == 0;
|
||||
}
|
||||
|
||||
AnalyzerResult Analyzer::AnalyzeInnerPacket(Packet* packet,
|
||||
const uint8_t*& data, uint32_t identifier) const
|
||||
{
|
||||
auto inner_analyzer = packet_mgr->Dispatch(identifier);
|
||||
|
||||
if ( inner_analyzer == nullptr )
|
||||
{
|
||||
//TODO: Handle default analysis here
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s failed, could not find analyzer for identifier %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
packet->Weird("no_suitable_analyzer_found");
|
||||
return AnalyzerResult::Failed;
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
return inner_analyzer->Analyze(packet, data);
|
||||
}
|
||||
|
||||
}
|
|
@ -68,18 +68,29 @@ public:
|
|||
* protocol, the data reference should be updated to point to that payload.
|
||||
*
|
||||
* @param packet The packet to analyze.
|
||||
*
|
||||
* @param data Reference to the payload pointer into the raw packet.
|
||||
*
|
||||
* @return A tuple of analysis result and identifier. The result indicates
|
||||
* how to proceed. If analysis can continue, the identifier determines the
|
||||
* encapsulated protocol.
|
||||
*/
|
||||
virtual AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) = 0;
|
||||
virtual AnalyzerResult Analyze(Packet* packet, const uint8_t*& data) = 0;
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
/**
|
||||
* Triggers analysis of the encapsulated packet. The encapsulated protocol
|
||||
* is determined using the given identifier.
|
||||
*
|
||||
* @param packet The packet to analyze.
|
||||
* @param data Reference to the payload pointer into the raw packet.
|
||||
* @param identifier The identifier of the encapsulated protocol.
|
||||
*
|
||||
* @return The outcome of the analysis.
|
||||
*/
|
||||
AnalyzerResult AnalyzeInnerPacket(Packet* packet, const uint8_t*& data,
|
||||
uint32_t identifier) const;
|
||||
private:
|
||||
Tag tag;
|
||||
|
||||
|
|
|
@ -147,44 +147,22 @@ void Manager::ProcessPacket(Packet* packet)
|
|||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time);
|
||||
#endif
|
||||
|
||||
// Dispatch and analyze layers
|
||||
AnalyzerResult result = AnalyzerResult::Continue;
|
||||
uint32_t next_layer_id = packet->link_type;
|
||||
// Start packet analysis
|
||||
const uint8_t* data = packet->data;
|
||||
do
|
||||
|
||||
auto root_analyzer = Dispatch(packet->link_type);
|
||||
if ( root_analyzer == nullptr )
|
||||
{
|
||||
auto current_analyzer = Dispatch(next_layer_id);
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "No analyzer for link type: %#x.", packet->link_type);
|
||||
packet->Weird("no_suitable_analyzer_found");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto result = root_analyzer->Analyze(packet, data);
|
||||
|
||||
// Analyzer not found
|
||||
if ( current_analyzer == nullptr )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Could not find analyzer for identifier %#x", next_layer_id);
|
||||
packet->Weird("no_suitable_analyzer_found");
|
||||
break;
|
||||
}
|
||||
|
||||
// Analyze this layer and get identifier of next layer protocol
|
||||
std::tie(result, next_layer_id) = current_analyzer->Analyze(packet, data);
|
||||
|
||||
#ifdef DEBUG
|
||||
switch ( result )
|
||||
{
|
||||
case AnalyzerResult::Continue:
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||
current_analyzer->GetAnalyzerName(), next_layer_id);
|
||||
break;
|
||||
case AnalyzerResult::Terminate:
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Done, last found layer identifier was %#x.", next_layer_id);
|
||||
break;
|
||||
case AnalyzerResult::Failed:
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis failed in %s", current_analyzer->GetAnalyzerName());
|
||||
}
|
||||
#endif
|
||||
|
||||
} while ( result == AnalyzerResult::Continue );
|
||||
|
||||
if ( result == AnalyzerResult::Terminate )
|
||||
CustomEncapsulationSkip(packet, data);
|
||||
if (result == AnalyzerResult::Terminate)
|
||||
CustomEncapsulationSkip(packet, data);
|
||||
}
|
||||
|
||||
// Processing finished, reset analyzer set state for next packet
|
||||
current_state = root_dispatcher;
|
||||
|
|
|
@ -87,6 +87,16 @@ public:
|
|||
*/
|
||||
void ProcessPacket(Packet* packet);
|
||||
|
||||
/**
|
||||
* Looks up a packet analyzer by identifier considering the context
|
||||
* as given by current_state.
|
||||
*
|
||||
* @param identifier The identifier to look up.
|
||||
*
|
||||
* @return The analyzer corresponding to the identifier.
|
||||
*/
|
||||
AnalyzerPtr Dispatch(uint32_t identifier);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -99,8 +109,6 @@ private:
|
|||
*/
|
||||
void CustomEncapsulationSkip(Packet* packet, const uint8_t* data);
|
||||
|
||||
AnalyzerPtr Dispatch(uint32_t identifier);
|
||||
|
||||
DispatcherPtr GetDispatcher(Config& configuration, const std::string& dispatcher_name);
|
||||
|
||||
std::map<std::string, AnalyzerPtr> analyzers;
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
add_subdirectory(default)
|
||||
|
||||
add_subdirectory(wrapper)
|
||||
add_subdirectory(null)
|
||||
#add_subdirectory(default)
|
||||
#
|
||||
#add_subdirectory(wrapper)
|
||||
#add_subdirectory(null)
|
||||
add_subdirectory(ethernet)
|
||||
add_subdirectory(vlan)
|
||||
add_subdirectory(pppoe)
|
||||
add_subdirectory(ppp_serial)
|
||||
add_subdirectory(ieee802_11)
|
||||
add_subdirectory(ieee802_11_radio)
|
||||
add_subdirectory(fddi)
|
||||
add_subdirectory(nflog)
|
||||
add_subdirectory(mpls)
|
||||
add_subdirectory(linux_sll)
|
||||
|
||||
add_subdirectory(arp)
|
||||
#add_subdirectory(vlan)
|
||||
#add_subdirectory(pppoe)
|
||||
#add_subdirectory(ppp_serial)
|
||||
#add_subdirectory(ieee802_11)
|
||||
#add_subdirectory(ieee802_11_radio)
|
||||
#add_subdirectory(fddi)
|
||||
#add_subdirectory(nflog)
|
||||
#add_subdirectory(mpls)
|
||||
#add_subdirectory(linux_sll)
|
||||
#
|
||||
#add_subdirectory(arp)
|
||||
add_subdirectory(ipv4)
|
||||
add_subdirectory(ipv6)
|
||||
|
|
|
@ -10,7 +10,7 @@ EthernetAnalyzer::EthernetAnalyzer()
|
|||
{
|
||||
}
|
||||
|
||||
zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||
zeek::packet_analysis::AnalyzerResult EthernetAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||
{
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
|
@ -19,7 +19,7 @@ zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* pac
|
|||
if ( data + 16 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_ethernet_frame");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
return AnalyzerResult::Failed;
|
||||
}
|
||||
|
||||
// Skip past Cisco FabricPath to encapsulated ethernet frame.
|
||||
|
@ -30,7 +30,7 @@ zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* pac
|
|||
if ( data + cfplen + 14 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header_cfp");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
return AnalyzerResult::Failed;
|
||||
}
|
||||
|
||||
data += cfplen;
|
||||
|
@ -47,7 +47,7 @@ zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* pac
|
|||
if ( protocol >= 1536 )
|
||||
{
|
||||
data += 14;
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
return AnalyzeInnerPacket(packet, data, protocol);
|
||||
}
|
||||
|
||||
// Other ethernet frame types
|
||||
|
@ -56,27 +56,28 @@ zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* pac
|
|||
if ( data + 16 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_ethernet_frame");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
return AnalyzerResult::Failed;
|
||||
}
|
||||
|
||||
// In the following we use undefined EtherTypes to signal uncommon
|
||||
// frame types. This allows specialized analyzers to take over.
|
||||
// Note that pdata remains at the start of the ethernet frame.
|
||||
//TODO: Lookup the analyzers on startup
|
||||
|
||||
// IEEE 802.2 SNAP
|
||||
if ( data[14] == 0xAA && data[15] == 0xAA)
|
||||
return { AnalyzerResult::Continue, 1502 };
|
||||
return AnalyzeInnerPacket(packet, data, 1502);
|
||||
|
||||
// Novell raw IEEE 802.3
|
||||
if ( data[14] == 0xFF && data[15] == 0xFF)
|
||||
return { AnalyzerResult::Continue, 1503 };
|
||||
return AnalyzeInnerPacket(packet, data, 1503);
|
||||
|
||||
|
||||
// IEEE 802.2 LLC
|
||||
return { AnalyzerResult::Continue, 1501 };
|
||||
return AnalyzeInnerPacket(packet, data, 1501);
|
||||
}
|
||||
|
||||
// Undefined (1500 < EtherType < 1536)
|
||||
packet->Weird("undefined_ether_type");
|
||||
return { AnalyzerResult::Failed, protocol };
|
||||
return AnalyzerResult::Failed;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
EthernetAnalyzer();
|
||||
~EthernetAnalyzer() override = default;
|
||||
|
||||
AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
|
||||
AnalyzerResult Analyze(Packet* packet, const uint8_t*& data) override;
|
||||
|
||||
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
||||
{
|
||||
|
|
|
@ -9,10 +9,10 @@ IPv4Analyzer::IPv4Analyzer()
|
|||
{
|
||||
}
|
||||
|
||||
zeek::packet_analysis::AnalysisResultTuple IPv4Analyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||
zeek::packet_analysis::AnalyzerResult IPv4Analyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||
{
|
||||
packet->l3_proto = L3_IPV4;
|
||||
|
||||
// Leave packet analyzer land
|
||||
return { AnalyzerResult::Terminate, 0 };
|
||||
return AnalyzerResult::Terminate;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
IPv4Analyzer();
|
||||
~IPv4Analyzer() override = default;
|
||||
|
||||
AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
|
||||
AnalyzerResult Analyze(Packet* packet, const uint8_t*& data) override;
|
||||
|
||||
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
||||
{
|
||||
|
|
|
@ -9,10 +9,10 @@ IPv6Analyzer::IPv6Analyzer()
|
|||
{
|
||||
}
|
||||
|
||||
zeek::packet_analysis::AnalysisResultTuple IPv6Analyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||
zeek::packet_analysis::AnalyzerResult IPv6Analyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||
{
|
||||
packet->l3_proto = L3_IPV6;
|
||||
|
||||
// Leave packet analyzer land
|
||||
return { AnalyzerResult::Terminate, 0 };
|
||||
return AnalyzerResult::Terminate;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
IPv6Analyzer();
|
||||
~IPv6Analyzer() override = default;
|
||||
|
||||
AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
|
||||
AnalyzerResult Analyze(Packet* packet, const uint8_t*& data) override;
|
||||
|
||||
static AnalyzerPtr Instantiate()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue