diff --git a/.gitignore b/.gitignore index d962c792a4..e0efa6d316 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ tmp # Configuration and build directories for CLion .idea -cmake-build-debug +cmake-build-* # skip DS Store for MacOS .DS_Store diff --git a/CHANGES b/CHANGES index eb695be422..6c11163cf8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,113 @@ +3.3.0-dev.329 | 2020-09-23 11:32:06 -0700 + + * Update NEWS (Tim Wojtulewicz, Corelight) + + * Fix build on FreeBSD, which was missing full definition of sockaddr for ARP (Tim Wojtulewicz, Corelight) + + * Update hashes for external testing repos (Tim Wojtulewicz, Corelight) + + * Fix handling of session analysis. + + This reverts commit 0e51be18ac59d7a176f18780f1f8df85561449b9. (Jan Grashoefer) + + * Fix Sessions::DoNextPacket to ignore ARP packets and not report weirds for them (Tim Wojtulewicz, Corelight) + + * Packet analysis cleanup. (Jan Grashoefer) + + * Minor cleanup (Tim Wojtulewicz, Corelight) + + * Simplify packet analyzer config. (Jan Grashoefer) + + * Make default packet analyzer definition explicit. (Jan Grashoefer) + + * Add explicit root analyzer for packet analysis. (Jan Grashoefer) + + * Extend packet analysis test. (Jan Grashoefer) + + * Simplify MPLS analysis. (Jan Grashoefer) + + * Improve packet analysis data flow. (Jan Grashoefer) + + * Improve packet analyzer API. (Jan Grashoefer) + + * Rename DefaultAnalyzer to IP. (Jan Grashoefer) + + * Move ARP analysis into packet analyzer. (Jan Grashoefer) + + * Small cleanup of packet analysis. (Jan Grashoefer) + + * Fix some build issues from the rebase (Tim Wojtulewicz, Corelight) + + * Remove encap_hdr_size (replaced by skip analyzer). (Jan Grashoefer) + + * Add skip analyzer test and update baselines. (Jan Grashoefer) + + * Allow to overwrite packet analysis mappings. (Jan Grashoefer) + + * Add SkipAnalyzer. + + This is WIP: The test case would require a new pcap or the possibility + to overwrite analyzer mappings. The CustomEncapsulationSkip method and + the corresponding options need to be removed. (Jan Grashoefer) + + * Suggested code improvements for packet analysis. (Jan Grashoefer) + + * Improve naming in packet analysis. (Jan Grashoefer) + + * Migrate all packet analyzers to new API. (Jan Grashoefer) + + * Remove magic identifiers from Ethernet analyzer. (Jan Grashoefer) + + * Bring back default packet analysis. + + Default analyzers can be configured per packet analyzer by omitting the + identifier in the ConfigEntry. (Jan Grashoefer) + + * Further simplified the packet analysis API. + + This is still WIP and includes the following changes: + * Dispatchers are now part of analyzers (moving dispatching logic from + the manager to the analyzers) + * All available analyzers are instantiated on start up + * Removal of configuration class (Jan Grashoefer) + + * Move dispatching into packet analyzers. + + WIP that updates only the Ethernet analyzer. (Jan Grashoefer) + + * Move cur_pos from packet into packet manager loop. (Jan Grashoefer) + + * Remove packet_analysis/Defines.h + + - Replace uses of identifier_t with uint32_t + - Replace repeated usage of tuple type for Analysis results with type alias (Tim Wojtulewicz, Corelight) + + * Move VectorDispatcher to be the only dispatcher (Tim Wojtulewicz, Corelight) + + * Remove Manager::Reset() method (Tim Wojtulewicz, Corelight) + + * Remove enabled state from Components, ability to enable/disable from Manager (Tim Wojtulewicz, Corelight) + + * Use shared_ptr instead of raw pointers in packet_analysis for analyzers and dispatchers (Tim Wojtulewicz, Corelight) + + * Whitespace fixes from review (Tim Wojtulewicz, Corelight) + + * Reorganize some pointer handling (Tim Wojtulewicz, Corelight) + + * Fix ordering of debug logger strings to match the enum (Tim Wojtulewicz, Corelight) + + * Fixes for various btest issues + + - Fix handling of truncated ethernet headers, fix core.truncation test output + - Update commit hashes for external private test repo (Tim Wojtulewicz, Corelight) + + * Merge ProtocolAnalyzerSet into Manager, remove AnalyzerSet base class (Tim Wojtulewicz, Corelight) + + * Minor fixes for packet analyzer renaming. (Jan Grashoefer) + + * Renamed LL-Analyzers to Packet Analyzers. (Jan Grashoefer) + + * Initial implementation of Lower-Level analyzers (Peter Oettig) 3.3.0-dev.285 | 2020-09-22 16:01:51 -0700 diff --git a/NEWS b/NEWS index d113a1783e..1a89a2ed9c 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,11 @@ New Functionality - Added support for EDNS0 Cookie and Keep-Alive options. +- Added new Packet Analysis plugin architecture for parsing packet headers + at layers below the existing Session analysis plugins. This allows + writing plugins to parse the various parts of a packet header separately, + chaining down into other plugins as needed. + Changed Functionality --------------------- diff --git a/VERSION b/VERSION index 8735148bb1..b9ad602047 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.0-dev.285 +3.3.0-dev.329 diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 9def35753c..b7a2b1b80c 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -1225,10 +1225,6 @@ const rpc_timeout = 24 sec &redef; ## means "forever", which resists evasion, but can lead to state accrual. const frag_timeout = 0.0 sec &redef; -## If positive, indicates the encapsulation header size that should -## be skipped. This applies to all packets. -const encap_hdr_size = 0 &redef; - ## Whether to use the ``ConnSize`` analyzer to count the number of packets and ## IP-level bytes transferred by each endpoint. If true, these values are ## returned in the connection's :zeek:see:`endpoint` record value. @@ -5341,3 +5337,19 @@ event net_done(t: time) # execution would be another idea. @if ( __init_primary_bifs() ) @endif + +module PacketAnalyzer; + +export { + type DispatchEntry : record { + ## The analyzer to dispatch. + analyzer : PacketAnalyzer::Tag; + }; + + ## A packet analyzer may extract a numeric identifier, which can be found in the + ## packet data and denotes the encapsulated protocol. A DispatchMap allows to map + ## the identifier to a child analyzer, which is defined using a DispatchEntry. + type DispatchMap : table[count] of DispatchEntry; +} + +@load base/packet-protocols diff --git a/scripts/base/packet-protocols/__load__.zeek b/scripts/base/packet-protocols/__load__.zeek new file mode 100644 index 0000000000..572b1a0c0c --- /dev/null +++ b/scripts/base/packet-protocols/__load__.zeek @@ -0,0 +1,14 @@ +@load base/packet-protocols/root +@load base/packet-protocols/ip +@load base/packet-protocols/skip +@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/mpls diff --git a/scripts/base/packet-protocols/ethernet/__load__.zeek b/scripts/base/packet-protocols/ethernet/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/ethernet/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/ethernet/main.zeek b/scripts/base/packet-protocols/ethernet/main.zeek new file mode 100644 index 0000000000..6f1c31df90 --- /dev/null +++ b/scripts/base/packet-protocols/ethernet/main.zeek @@ -0,0 +1,28 @@ +module PacketAnalyzer::ETHERNET; + +export { + ## Default analyzer + const default_analyzer: PacketAnalyzer::Tag = PacketAnalyzer::ANALYZER_IP &redef; + + ## IEEE 802.2 SNAP analyzer + const snap_analyzer: PacketAnalyzer::Tag &redef; + ## Novell raw IEEE 802.3 analyzer + const novell_raw_analyzer: PacketAnalyzer::Tag &redef; + ## IEEE 802.2 LLC analyzer + const llc_analyzer: PacketAnalyzer::Tag &redef; + + ## Identifier mappings based on EtherType + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef dispatch_map += { + [0x8847] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_MPLS), + [0x0800] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [0x86DD] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6), + [0x0806] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP), + [0x8035] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP), + [0x8100] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_VLAN), + [0x88A8] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_VLAN), + [0x9100] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_VLAN), + [0x8864] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_PPPOE) +}; diff --git a/scripts/base/packet-protocols/fddi/__load__.zeek b/scripts/base/packet-protocols/fddi/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/fddi/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/fddi/main.zeek b/scripts/base/packet-protocols/fddi/main.zeek new file mode 100644 index 0000000000..3104682102 --- /dev/null +++ b/scripts/base/packet-protocols/fddi/main.zeek @@ -0,0 +1,6 @@ +module PacketAnalyzer::FDDI; + +export { + ## Default analyzer + const default_analyzer: PacketAnalyzer::Tag = PacketAnalyzer::ANALYZER_IP &redef; +} diff --git a/scripts/base/packet-protocols/ieee802_11/__load__.zeek b/scripts/base/packet-protocols/ieee802_11/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/ieee802_11/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/ieee802_11/main.zeek b/scripts/base/packet-protocols/ieee802_11/main.zeek new file mode 100644 index 0000000000..f46f89e377 --- /dev/null +++ b/scripts/base/packet-protocols/ieee802_11/main.zeek @@ -0,0 +1,13 @@ +module PacketAnalyzer::IEEE802_11; + +export { + ## Identifier mappings based on EtherType + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef dispatch_map += { + [0x0800] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [0x86DD] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6), + [0x0806] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP), + [0x8035] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP) +}; diff --git a/scripts/base/packet-protocols/ieee802_11_radio/__load__.zeek b/scripts/base/packet-protocols/ieee802_11_radio/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/ieee802_11_radio/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/ieee802_11_radio/main.zeek b/scripts/base/packet-protocols/ieee802_11_radio/main.zeek new file mode 100644 index 0000000000..483a80acf0 --- /dev/null +++ b/scripts/base/packet-protocols/ieee802_11_radio/main.zeek @@ -0,0 +1,12 @@ +module PacketAnalyzer::IEEE802_11_RADIO; + +export { + ## Identifier mappings + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +const DLT_IEEE802_11 : count = 105; + +redef dispatch_map += { + [DLT_IEEE802_11] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IEEE802_11) +}; diff --git a/scripts/base/packet-protocols/ip/__load__.zeek b/scripts/base/packet-protocols/ip/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/ip/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/ip/main.zeek b/scripts/base/packet-protocols/ip/main.zeek new file mode 100644 index 0000000000..feb5fde73b --- /dev/null +++ b/scripts/base/packet-protocols/ip/main.zeek @@ -0,0 +1,11 @@ +module PacketAnalyzer::IP; + +export { + ## Identifier mappings based on IP version (4 or 6) + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef dispatch_map += { + [4] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [6] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6) +}; diff --git a/scripts/base/packet-protocols/linux_sll/__load__.zeek b/scripts/base/packet-protocols/linux_sll/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/linux_sll/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/linux_sll/main.zeek b/scripts/base/packet-protocols/linux_sll/main.zeek new file mode 100644 index 0000000000..995c972ae6 --- /dev/null +++ b/scripts/base/packet-protocols/linux_sll/main.zeek @@ -0,0 +1,14 @@ +module PacketAnalyzer::LINUXSLL; + +export { + ## Identifier mappings based on EtherType + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef dispatch_map += { + [0x0800] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [0x86DD] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6), + [0x0806] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP), + # RARP + [0x8035] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP) +}; diff --git a/scripts/base/packet-protocols/mpls/__load__.zeek b/scripts/base/packet-protocols/mpls/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/mpls/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/mpls/main.zeek b/scripts/base/packet-protocols/mpls/main.zeek new file mode 100644 index 0000000000..a597ceea0b --- /dev/null +++ b/scripts/base/packet-protocols/mpls/main.zeek @@ -0,0 +1,6 @@ +module PacketAnalyzer::MPLS; + +export { + ## Default analyzer + const default_analyzer: PacketAnalyzer::Tag = PacketAnalyzer::ANALYZER_IP &redef; +} diff --git a/scripts/base/packet-protocols/nflog/__load__.zeek b/scripts/base/packet-protocols/nflog/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/nflog/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/nflog/main.zeek b/scripts/base/packet-protocols/nflog/main.zeek new file mode 100644 index 0000000000..cecc0d466b --- /dev/null +++ b/scripts/base/packet-protocols/nflog/main.zeek @@ -0,0 +1,14 @@ +module PacketAnalyzer::NFLOG; + +export { + ## Identifier mappings + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +const AF_INET : count = 2; +const AF_INET6 : count = 10; + +redef dispatch_map += { + [AF_INET] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [AF_INET6] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6) +}; diff --git a/scripts/base/packet-protocols/null/__load__.zeek b/scripts/base/packet-protocols/null/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/null/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/null/main.zeek b/scripts/base/packet-protocols/null/main.zeek new file mode 100644 index 0000000000..e1aff33dcd --- /dev/null +++ b/scripts/base/packet-protocols/null/main.zeek @@ -0,0 +1,25 @@ +module PacketAnalyzer::NULL; + +export { + ## Identifier mappings + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +const DLT_NULL : count = 0; + +redef PacketAnalyzer::ROOT::dispatch_map += { + [DLT_NULL] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_NULL) +}; + +redef dispatch_map += { + [2] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + + ## From the Wireshark Wiki: AF_INET6ANALYZER, unfortunately, has different values in + ## {NetBSD,OpenBSD,BSD/OS}, {FreeBSD,DragonFlyBSD}, and {Darwin/Mac OS X}, so an IPv6 + ## packet might have a link-layer header with 24, 28, or 30 as the AF_ value. As we + ## may be reading traces captured on platforms other than what we're running on, we + ## accept them all here. + [24] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6), + [28] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6), + [30] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6) +}; diff --git a/scripts/base/packet-protocols/ppp_serial/__load__.zeek b/scripts/base/packet-protocols/ppp_serial/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/ppp_serial/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/ppp_serial/main.zeek b/scripts/base/packet-protocols/ppp_serial/main.zeek new file mode 100644 index 0000000000..4c2ba042c0 --- /dev/null +++ b/scripts/base/packet-protocols/ppp_serial/main.zeek @@ -0,0 +1,18 @@ +module PacketAnalyzer::PPP_SERIAL; + +export { + ## Identifier mappings + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +const DLT_PPP_SERIAL : count = 50; + +redef PacketAnalyzer::ROOT::dispatch_map += { + [DLT_PPP_SERIAL] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_PPPSERIAL) +}; + +redef dispatch_map += { + [0x0281] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_MPLS), + [0x0021] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [0x0057] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6) +}; diff --git a/scripts/base/packet-protocols/pppoe/__load__.zeek b/scripts/base/packet-protocols/pppoe/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/pppoe/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/pppoe/main.zeek b/scripts/base/packet-protocols/pppoe/main.zeek new file mode 100644 index 0000000000..f8e8f76d44 --- /dev/null +++ b/scripts/base/packet-protocols/pppoe/main.zeek @@ -0,0 +1,11 @@ +module PacketAnalyzer::PPPOE; + +export { + ## Identifier mappings + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef dispatch_map += { + [0x0021] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [0x0057] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6) +}; diff --git a/scripts/base/packet-protocols/root/__load__.zeek b/scripts/base/packet-protocols/root/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/root/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/root/main.zeek b/scripts/base/packet-protocols/root/main.zeek new file mode 100644 index 0000000000..a53788804f --- /dev/null +++ b/scripts/base/packet-protocols/root/main.zeek @@ -0,0 +1,26 @@ +module PacketAnalyzer::ROOT; + +export { + ## Default analyzer (if we don't know the link type, we assume raw IP) + const default_analyzer: PacketAnalyzer::Tag = PacketAnalyzer::ANALYZER_IP &redef; + + ## Identifier mappings based on link type + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +const DLT_EN10MB : count = 1; +const DLT_FDDI : count = 10; +const DLT_IEEE802_11 : count = 105; +const DLT_IEEE802_11_RADIO : count = 127; +const DLT_LINUX_SLL : count = 113; +const DLT_NFLOG : count = 239; + +redef dispatch_map += { + [DLT_EN10MB] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ETHERNET), + [DLT_FDDI] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_FDDI), + [DLT_IEEE802_11] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IEEE802_11), + [DLT_IEEE802_11_RADIO] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IEEE802_11_RADIO), + [DLT_LINUX_SLL] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_LINUXSLL), + [DLT_NFLOG] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_NFLOG) + +}; diff --git a/scripts/base/packet-protocols/skip/__load__.zeek b/scripts/base/packet-protocols/skip/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/skip/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/skip/main.zeek b/scripts/base/packet-protocols/skip/main.zeek new file mode 100644 index 0000000000..f18050ce83 --- /dev/null +++ b/scripts/base/packet-protocols/skip/main.zeek @@ -0,0 +1,9 @@ +module PacketAnalyzer::SKIP; + +export { + ## Default analyzer + const default_analyzer: PacketAnalyzer::Tag = PacketAnalyzer::ANALYZER_IP &redef; + + ## Bytes to skip. + const skip_bytes: count = 0 &redef; +} diff --git a/scripts/base/packet-protocols/vlan/__load__.zeek b/scripts/base/packet-protocols/vlan/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/vlan/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/vlan/main.zeek b/scripts/base/packet-protocols/vlan/main.zeek new file mode 100644 index 0000000000..7f564cfa0d --- /dev/null +++ b/scripts/base/packet-protocols/vlan/main.zeek @@ -0,0 +1,16 @@ +module PacketAnalyzer::VLAN; + +export { + ## Identifier mappings based on EtherType + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef dispatch_map += { + [0x8847] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_MPLS), + [0x0800] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV4), + [0x86DD] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IPV6), + [0x0806] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP), + [0x8035] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_ARP), + [0x8100] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_VLAN), + [0x8864] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_PPPOE) +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb94d4a728..e851872b65 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -146,6 +146,7 @@ set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE) set(bro_PLUGIN_DEPS CACHE INTERNAL "plugin dependencies" FORCE) add_subdirectory(analyzer) +add_subdirectory(packet_analysis) add_subdirectory(broker) add_subdirectory(zeekygen) add_subdirectory(file_analysis) diff --git a/src/Conn.h b/src/Conn.h index ebd4087a9e..9be0afc8fe 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -349,8 +349,8 @@ protected: TransportProto proto; uint32_t orig_flow_label, resp_flow_label; // most recent IPv6 flow labels uint32_t vlan, inner_vlan; // VLAN this connection traverses, if available - u_char orig_l2_addr[Packet::l2_addr_len]; // Link-layer originator address, if available - u_char resp_l2_addr[Packet::l2_addr_len]; // Link-layer responder address, if available + u_char orig_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer originator address, if available + u_char resp_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer responder address, if available double start_time, last_time; double inactivity_timeout; RecordValPtr conn_val; diff --git a/src/DebugLogger.cc b/src/DebugLogger.cc index 5a4a468847..f2d0f75dd6 100644 --- a/src/DebugLogger.cc +++ b/src/DebugLogger.cc @@ -20,17 +20,18 @@ DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = { { "notifiers", 0, false }, { "main-loop", 0, false }, { "dpd", 0, false }, + { "packet_analysis", 0, false }, + { "file_analysis", 0, false }, { "tm", 0, false }, { "logging", 0, false }, - {"input", 0, false }, + { "input", 0, false }, { "threading", 0, false }, - { "file_analysis", 0, false }, { "plugins", 0, false }, { "zeekygen", 0, false }, { "pktio", 0, false }, { "broker", 0, false }, - { "scripts", 0, false}, - { "supervisor", 0, false} + { "scripts", 0, false }, + { "supervisor", 0, false } }; DebugLogger::DebugLogger() diff --git a/src/DebugLogger.h b/src/DebugLogger.h index 54257e1a6f..f7c3a04e55 100644 --- a/src/DebugLogger.h +++ b/src/DebugLogger.h @@ -30,25 +30,26 @@ namespace zeek { // an entry to DebugLogger::streams in DebugLogger.cc. enum DebugStream { - DBG_SERIAL, // Serialization - DBG_RULES, // Signature matching - DBG_STRING, // String code + DBG_SERIAL, // Serialization + DBG_RULES, // Signature matching + DBG_STRING, // String code DBG_NOTIFIERS, // Notifiers DBG_MAINLOOP, // Main IOSource loop DBG_ANALYZER, // Analyzer framework - DBG_TM, // Time-machine packet input via Brocolli + DBG_PACKET_ANALYSIS, // Packet analysis + DBG_FILE_ANALYSIS, // File analysis + DBG_TM, // Time-machine packet input via Brocolli DBG_LOGGING, // Logging streams - DBG_INPUT, // Input streams + DBG_INPUT, // Input streams DBG_THREADING, // Threading system - DBG_FILE_ANALYSIS, // File analysis DBG_PLUGINS, // Plugin system DBG_ZEEKYGEN, // Zeekygen - DBG_PKTIO, // Packet sources and dumpers. - DBG_BROKER, // Broker communication + DBG_PKTIO, // Packet sources and dumpers. + DBG_BROKER, // Broker communication DBG_SCRIPTS, // Script initialization DBG_SUPERVISOR, // Process supervisor - NUM_DBGS // Has to be last + NUM_DBGS // Has to be last }; namespace detail { diff --git a/src/NetVar.cc b/src/NetVar.cc index edd778fa92..dfc52e0ea4 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -113,8 +113,6 @@ int partial_connection_ok; int tcp_SYN_ack_ok; int tcp_match_undelivered; -int encap_hdr_size; - double frag_timeout; double tcp_SYN_timeout; @@ -261,8 +259,6 @@ void init_net_var() tcp_SYN_ack_ok = id::find_val("tcp_SYN_ack_ok")->AsBool(); tcp_match_undelivered = id::find_val("tcp_match_undelivered")->AsBool(); - encap_hdr_size = id::find_val("encap_hdr_size")->AsCount(); - frag_timeout = id::find_val("frag_timeout")->AsInterval(); tcp_SYN_timeout = id::find_val("tcp_SYN_timeout")->AsInterval(); @@ -365,7 +361,6 @@ int& ignore_checksums = zeek::detail::ignore_checksums; int& partial_connection_ok = zeek::detail::partial_connection_ok; int& tcp_SYN_ack_ok = zeek::detail::tcp_SYN_ack_ok; int& tcp_match_undelivered = zeek::detail::tcp_match_undelivered; -int& encap_hdr_size = zeek::detail::encap_hdr_size; double& frag_timeout = zeek::detail::frag_timeout; double& tcp_SYN_timeout = zeek::detail::tcp_SYN_timeout; double& tcp_session_timer = zeek::detail::tcp_session_timer; diff --git a/src/NetVar.h b/src/NetVar.h index 45199108b0..29a1bb55fc 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -17,8 +17,6 @@ extern int partial_connection_ok; extern int tcp_SYN_ack_ok; extern int tcp_match_undelivered; -extern int encap_hdr_size; - extern double frag_timeout; extern double tcp_SYN_timeout; @@ -117,7 +115,6 @@ extern int& ignore_checksums [[deprecated("Remove in v4.1. Use zeek::detail::ign extern int& partial_connection_ok [[deprecated("Remove in v4.1. Use zeek::detail::partial_connection_ok.")]]; extern int& tcp_SYN_ack_ok [[deprecated("Remove in v4.1. Use zeek::detail::tcp_SYN_ack_ok.")]]; extern int& tcp_match_undelivered [[deprecated("Remove in v4.1. Use zeek::detail::tcp_match_undelivered.")]]; -extern int& encap_hdr_size [[deprecated("Remove in v4.1. Use zeek::detail::encap_hdr_size.")]]; extern double& frag_timeout [[deprecated("Remove in v4.1. Use zeek::detail::frag_timeout.")]]; extern double& tcp_SYN_timeout [[deprecated("Remove in v4.1. Use zeek::detail::tcp_SYN_timeout.")]]; extern double& tcp_session_timer [[deprecated("Remove in v4.1. Use zeek::detail::tcp_session_timer.")]]; diff --git a/src/Sessions.cc b/src/Sessions.cc index afe817e2b5..79725bff5d 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -22,8 +22,6 @@ #include "analyzer/protocol/stepping-stone/SteppingStone.h" #include "analyzer/protocol/stepping-stone/events.bif.h" -#include "analyzer/protocol/arp/ARP.h" -#include "analyzer/protocol/arp/events.bif.h" #include "Discard.h" #include "RuleMatcher.h" @@ -33,6 +31,8 @@ #include "iosource/IOSource.h" #include "iosource/PktDumper.h" +#include "pcap.h" + // These represent NetBIOS services on ephemeral ports. They're numbered // so that we can use a single int to hold either an actual TCP/UDP server // port or one of these. @@ -85,7 +85,6 @@ NetSessions::NetSessions() packet_filter = nullptr; - dump_this_packet = false; num_packets_processed = 0; static auto pkt_profile_file = id::find_val("pkt_profile_file"); @@ -96,11 +95,6 @@ NetSessions::NetSessions() else pkt_profiler = nullptr; - if ( arp_request || arp_reply || bad_arp ) - arp_analyzer = new analyzer::arp::ARP_Analyzer(); - else - arp_analyzer = nullptr; - memset(&stats, 0, sizeof(SessionStats)); } @@ -108,7 +102,6 @@ NetSessions::~NetSessions() { delete packet_filter; delete pkt_profiler; - Unref(arp_analyzer); delete discarder; delete stp_manager; @@ -138,10 +131,15 @@ void NetSessions::NextPacket(double t, const Packet* pkt) ++num_packets_processed; - dump_this_packet = false; - - if ( zeek::detail::record_all_packets ) + bool dumped_packet = false; + if ( pkt->dump_packet || zeek::detail::record_all_packets ) + { DumpPacket(pkt); + dumped_packet = true; + } + + if ( ! pkt->session_analysis ) + return; if ( pkt->hdr_size > pkt->cap_len ) { @@ -159,7 +157,7 @@ void NetSessions::NextPacket(double t, const Packet* pkt) return; } - const struct ip* ip = (const struct ip*) (pkt->data + pkt->hdr_size); + auto ip = (const struct ip*) (pkt->data + pkt->hdr_size); IP_Hdr ip_hdr(ip, false); DoNextPacket(t, pkt, &ip_hdr, nullptr); } @@ -176,20 +174,14 @@ void NetSessions::NextPacket(double t, const Packet* pkt) DoNextPacket(t, pkt, &ip_hdr, nullptr); } - else if ( pkt->l3_proto == L3_ARP ) - { - if ( arp_analyzer ) - arp_analyzer->NextPacket(t, pkt); - } - else { Weird("unknown_packet_type", pkt); return; } - - if ( dump_this_packet && ! zeek::detail::record_all_packets ) + // Check whether packet should be recorded based on session analysis + if ( pkt->dump_packet && ! dumped_packet ) DumpPacket(pkt); } @@ -290,7 +282,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr if ( ip_hdr->IsFragment() ) { - dump_this_packet = true; // always record fragments + pkt->dump_packet = true; // always record fragments if ( caplen < len ) { @@ -333,7 +325,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr // there, it's always the last. if ( ip_hdr->LastHeader() == IPPROTO_ESP ) { - dump_this_packet = true; + pkt->dump_packet = true; if ( esp_packet ) event_mgr.Enqueue(esp_packet, ip_hdr->ToPktHdrVal()); @@ -346,7 +338,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr // last if present. if ( ip_hdr->LastHeader() == IPPROTO_MOBILITY ) { - dump_this_packet = true; + pkt->dump_packet = true; if ( ! ignore_checksums && mobility_header_checksum(ip_hdr) != 0xffff ) { @@ -735,7 +727,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr else if ( record_packet ) { if ( record_content ) - dump_this_packet = true; // save the whole thing + pkt->dump_packet = true; // save the whole thing else { @@ -810,7 +802,7 @@ void NetSessions::DoNextInnerPacket(double t, const Packet* pkt, Packet p; p.Init(link_type, &ts, caplen, len, data, false, ""); - if ( p.Layer2Valid() && (p.l3_proto == L3_IPV4 || p.l3_proto == L3_IPV6) ) + if ( p.l2_valid && (p.l3_proto == L3_IPV4 || p.l3_proto == L3_IPV6) ) { auto inner = p.IP(); DoNextPacket(t, &p, &inner, outer); @@ -1329,7 +1321,7 @@ void NetSessions::Weird(const char* name, const Packet* pkt, const EncapsulationStack* encap, const char* addl) { if ( pkt ) - dump_this_packet = true; + pkt->dump_packet = true; if ( encap && encap->LastType() != BifEnum::Tunnel::NONE ) reporter->Weird(util::fmt("%s_in_tunnel", name), addl); diff --git a/src/Sessions.h b/src/Sessions.h index fe483ca0b8..991eeacd5a 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -24,7 +24,6 @@ using ConnID [[deprecated("Remove in v4.1. Use zeek::ConnID.")]] = zeek::ConnID; ZEEK_FORWARD_DECLARE_NAMESPACED(Discarder, zeek::detail); ZEEK_FORWARD_DECLARE_NAMESPACED(SteppingStoneManager, zeek, analyzer::stepping_stone); -ZEEK_FORWARD_DECLARE_NAMESPACED(ARP_Analyzer, zeek, analyzer::arp); namespace zeek { @@ -234,14 +233,11 @@ protected: using IPTunnelMap = std::map; IPTunnelMap ip_tunnels; - analyzer::arp::ARP_Analyzer* arp_analyzer; - analyzer::stepping_stone::SteppingStoneManager* stp_manager; detail::Discarder* discarder; detail::PacketFilter* packet_filter; uint64_t num_packets_processed; detail::PacketProfiler* pkt_profiler; - bool dump_this_packet; // if true, current packet should be recorded }; namespace detail { diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index a6f091fa45..f63d021ccd 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -1,5 +1,4 @@ -add_subdirectory(arp) add_subdirectory(ayiya) add_subdirectory(bittorrent) add_subdirectory(conn-size) diff --git a/src/analyzer/protocol/arp/ARP.cc b/src/analyzer/protocol/arp/ARP.cc deleted file mode 100644 index f45e45b959..0000000000 --- a/src/analyzer/protocol/arp/ARP.cc +++ /dev/null @@ -1,244 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "ARP.h" -#include "Event.h" -#include "Reporter.h" -#include "Desc.h" - -#include "events.bif.h" - -namespace zeek::analyzer::arp { - -ARP_Analyzer::ARP_Analyzer() - { - } - -ARP_Analyzer::~ARP_Analyzer() - { - } - -// Argh! FreeBSD and Linux have almost completely different net/if_arp.h . -// ... and on Solaris we are missing half of the ARPOP codes, so define -// them here as necessary: - -#ifndef ARPOP_REQUEST -#define ARPOP_REQUEST 1 // ARP request. -#endif -#ifndef ARPOP_REPLY -#define ARPOP_REPLY 2 // ARP reply. -#endif -#ifndef ARPOP_PREQUEST -#define ARPOP_RREQUEST 3 // RARP request. -#endif -#ifndef ARPOP_RREPLY -#define ARPOP_RREPLY 4 // RARP reply. -#endif -#ifndef ARPOP_InREQUEST -#define ARPOP_InREQUEST 8 // InARP request. -#endif -#ifndef ARPOP_InREPLY -#define ARPOP_InREPLY 9 // InARP reply. -#endif -#ifndef ARPOP_NAK -#define ARPOP_NAK 10 // (ATM)ARP NAK. -#endif - -#ifndef ar_sha -#define ar_sha(ap) ((caddr_t((ap)+1)) + 0) -#endif - -#ifndef ar_spa -#define ar_spa(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln) -#endif - -#ifndef ar_tha -#define ar_tha(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln) -#endif - -#ifndef ar_tpa -#define ar_tpa(ap) ((caddr_t((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln) -#endif - -#ifndef ARPOP_REVREQUEST -#define ARPOP_REVREQUEST ARPOP_RREQUEST -#endif - -#ifndef ARPOP_REVREPLY -#define ARPOP_REVREPLY ARPOP_RREPLY -#endif - -#ifndef ARPOP_INVREQUEST -#define ARPOP_INVREQUEST ARPOP_InREQUEST -#endif - -#ifndef ARPOP_INVREPLY -#define ARPOP_INVREPLY ARPOP_InREPLY -#endif - - -void ARP_Analyzer::NextPacket(double t, const Packet* pkt) - { - const u_char *data = pkt->data; - // Check whether the packet is OK ("inspired" in tcpdump's print-arp.c). - const struct arp_pkthdr* ah = - (const struct arp_pkthdr*) (data + pkt->hdr_size); - - // Check the size. - int min_length = (ar_tpa(ah) - (char*) (data + pkt->hdr_size)) + ah->ar_pln; - int real_length = pkt->cap_len - pkt->hdr_size; - if ( min_length > real_length ) - { - Corrupted("truncated_ARP"); - return; - } - - char errbuf[1024]; - - // Check the address description fields. - switch ( ntohs(ah->ar_hrd) ) { - case ARPHRD_ETHER: - if ( ah->ar_hln != 6 ) - { // don't know how to handle the opcode - snprintf(errbuf, sizeof(errbuf), - "corrupt-arp-header (hrd=%i, hln=%i)", - ntohs(ah->ar_hrd), ah->ar_hln); - BadARP(ah, errbuf); - return; - } - break; - - default: - { // don't know how to proceed - snprintf(errbuf, sizeof(errbuf), - "unknown-arp-hw-address (hrd=%i)", ntohs(ah->ar_hrd)); - BadARP(ah, errbuf); - return; - } - } - - // ### Note, we don't support IPv6 addresses yet. - switch ( ntohs(ah->ar_pro) ) { - case ETHERTYPE_IP: - if ( ah->ar_pln != 4 ) - { // don't know how to handle the opcode - snprintf(errbuf, sizeof(errbuf), - "corrupt-arp-header (pro=%i, pln=%i)", - ntohs(ah->ar_pro), ah->ar_pln); - BadARP(ah, errbuf); - return; - } - break; - - default: - { // don't know how to proceed - snprintf(errbuf, sizeof(errbuf), - "unknown-arp-proto-address (pro=%i)", - ntohs(ah->ar_pro)); - BadARP(ah, errbuf); - return; - } - } - - - // Check MAC src address = ARP sender MAC address. - if ( memcmp(pkt->l2_src, ar_sha(ah), ah->ar_hln) ) - { - BadARP(ah, "weird-arp-sha"); - return; - } - - // Check the code is supported. - switch ( ntohs(ah->ar_op) ) { - case ARPOP_REQUEST: - RREvent(arp_request, pkt->l2_src, pkt->l2_dst, - ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah)); - break; - - case ARPOP_REPLY: - RREvent(arp_reply, pkt->l2_src, pkt->l2_dst, - ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah)); - break; - - case ARPOP_REVREQUEST: - case ARPOP_REVREPLY: - case ARPOP_INVREQUEST: - case ARPOP_INVREPLY: - { // don't know how to handle the opcode - snprintf(errbuf, sizeof(errbuf), - "unimplemented-arp-opcode (%i)", ntohs(ah->ar_op)); - BadARP(ah, errbuf); - break; - } - - default: - { // invalid opcode - snprintf(errbuf, sizeof(errbuf), - "invalid-arp-opcode (opcode=%i)", ntohs(ah->ar_op)); - BadARP(ah, errbuf); - return; - } - } - } - -void ARP_Analyzer::Describe(ODesc* d) const - { - d->Add(""); - d->NL(); - } - -void ARP_Analyzer::BadARP(const struct arp_pkthdr* hdr, const char* msg) - { - if ( ! bad_arp ) - return; - - event_mgr.Enqueue(bad_arp, - ToAddrVal(ar_spa(hdr)), - ToEthAddrStr((const u_char*) ar_sha(hdr)), - ToAddrVal(ar_tpa(hdr)), - ToEthAddrStr((const u_char*) ar_tha(hdr)), - make_intrusive(msg)); - } - -void ARP_Analyzer::Corrupted(const char* msg) - { - reporter->Weird(msg); - } - -void ARP_Analyzer::RREvent(EventHandlerPtr e, - const u_char* src, const u_char *dst, - const char* spa, const char* sha, - const char* tpa, const char* tha) - { - if ( ! e ) - return; - - event_mgr.Enqueue(e, - ToEthAddrStr(src), - ToEthAddrStr(dst), - ToAddrVal(spa), - ToEthAddrStr((const u_char*) sha), - ToAddrVal(tpa), - ToEthAddrStr((const u_char*) tha)); - } - -AddrVal* ARP_Analyzer::ConstructAddrVal(const void* addr) - { return ToAddrVal(addr).release(); } - -AddrValPtr ARP_Analyzer::ToAddrVal(const void* addr) - { - // ### For now, we only handle IPv4 addresses. - return make_intrusive(*(const uint32_t*) addr); - } - -StringVal* ARP_Analyzer::EthAddrToStr(const u_char* addr) - { return ToEthAddrStr(addr).release(); } - -StringValPtr ARP_Analyzer::ToEthAddrStr(const u_char* addr) - { - char buf[1024]; - snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - return make_intrusive(buf); - } - -} // namespace zeek::analyzer::arp diff --git a/src/analyzer/protocol/arp/ARP.h b/src/analyzer/protocol/arp/ARP.h deleted file mode 100644 index 8d2f1b5fed..0000000000 --- a/src/analyzer/protocol/arp/ARP.h +++ /dev/null @@ -1,66 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#pragma once - -#include "zeek-config.h" -#include -#include -#include -#include -#include -#ifdef HAVE_NET_ETHERNET_H -#include -#elif defined(HAVE_SYS_ETHERNET_H) -#include -#elif defined(HAVE_NETINET_IF_ETHER_H) -#include -#elif defined(HAVE_NET_ETHERTYPES_H) -#include -#endif - -#ifndef arp_pkthdr -#define arp_pkthdr arphdr -#endif - -#include "NetVar.h" - -ZEEK_FORWARD_DECLARE_NAMESPACED(Packet, zeek); - -extern "C" { -#include -} - -namespace zeek::analyzer::arp { - -class ARP_Analyzer : public Obj { -public: - ARP_Analyzer(); - ~ARP_Analyzer() override; - - void NextPacket(double t, const Packet* pkt); - - void Describe(ODesc* d) const override; - void RREvent(EventHandlerPtr e, const u_char* src, const u_char* dst, - const char* spa, const char* sha, - const char* tpa, const char* tha); - -protected: - - [[deprecated("Remove in v4.1. Use ToAddrVal().")]] - AddrVal* ConstructAddrVal(const void* addr); - [[deprecated("Remove in v4.1. Use ToEthAddrStr().")]] - StringVal* EthAddrToStr(const u_char* addr); - - AddrValPtr ToAddrVal(const void* addr); - StringValPtr ToEthAddrStr(const u_char* addr); - void BadARP(const struct arp_pkthdr* hdr, const char* string); - void Corrupted(const char* string); -}; - -} // namespace zeek::analyzer::arp - -namespace analyzer::arp { - -using ARP_Analyzer [[deprecated("Remove in v4.1. Use zeek::analyzer::arp::ARP_Analyzer.")]] = zeek::analyzer::arp::ARP_Analyzer; - -} // namespace analyzer::arp diff --git a/src/analyzer/protocol/arp/CMakeLists.txt b/src/analyzer/protocol/arp/CMakeLists.txt deleted file mode 100644 index 0b911b1979..0000000000 --- a/src/analyzer/protocol/arp/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ - -# This is not an actual analyzer, but used by the core. We still -# maintain it here along with the other analyzers because conceptually -# it's also parsing a protocol just like them. The current structure -# is merely a left-over from when this code was written. - -include(ZeekPlugin) - -include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - -zeek_plugin_begin(Zeek ARP) -zeek_plugin_cc(ARP.cc Plugin.cc) -zeek_plugin_bif(events.bif) -zeek_plugin_end() - diff --git a/src/analyzer/protocol/arp/Plugin.cc b/src/analyzer/protocol/arp/Plugin.cc deleted file mode 100644 index 1ff5f08c63..0000000000 --- a/src/analyzer/protocol/arp/Plugin.cc +++ /dev/null @@ -1,18 +0,0 @@ -// See the file in the main distribution directory for copyright. - -#include "plugin/Plugin.h" - -namespace zeek::plugin::detail::Zeek_ARP { - -class Plugin : public zeek::plugin::Plugin { -public: - zeek::plugin::Configuration Configure() override - { - zeek::plugin::Configuration config; - config.name = "Zeek::ARP"; - config.description = "ARP Parsing"; - return config; - } -} plugin; - -} // namespace zeek::plugin::detail::Zeek_ARP diff --git a/src/analyzer/protocol/vxlan/VXLAN.cc b/src/analyzer/protocol/vxlan/VXLAN.cc index 7fde0ce5ef..a28fe45798 100644 --- a/src/analyzer/protocol/vxlan/VXLAN.cc +++ b/src/analyzer/protocol/vxlan/VXLAN.cc @@ -65,7 +65,7 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, ts.tv_usec = (suseconds_t) ((run_state::current_timestamp - (double)ts.tv_sec) * 1000000); Packet pkt(DLT_EN10MB, &ts, caplen, len, data); - if ( ! pkt.Layer2Valid() ) + if ( ! pkt.l2_valid ) { ProtocolViolation("VXLAN invalid inner ethernet frame", (const char*) data, len); diff --git a/src/iosource/Packet.cc b/src/iosource/Packet.cc index c7bbb87412..152723f866 100644 --- a/src/iosource/Packet.cc +++ b/src/iosource/Packet.cc @@ -3,6 +3,7 @@ #include "Desc.h" #include "IP.h" #include "iosource/Manager.h" +#include "packet_analysis/Manager.h" #include "Var.h" extern "C" { @@ -44,8 +45,11 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen, else data = arg_data; + session_analysis = false; + dump_packet = false; + time = ts.tv_sec + double(ts.tv_usec) / 1e6; - hdr_size = GetLinkHeaderSize(arg_link_type); + hdr_size = 0; eth_type = 0; vlan = 0; inner_vlan = 0; @@ -58,14 +62,13 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen, l3_proto = L3_UNKNOWN; l3_checksummed = false; - if ( data && cap_len < hdr_size ) - { - Weird("truncated_link_header"); - return; - } - if ( data ) - ProcessLayer2(); + { + // From here we assume that layer 2 is valid. If the packet analysis fails, + // the packet manager will invalidate the packet. + l2_valid = true; + packet_mgr->ProcessPacket(this); + } } const IP_Hdr Packet::IP() const @@ -76,523 +79,8 @@ const IP_Hdr Packet::IP() const void Packet::Weird(const char* name) { sessions->Weird(name, this); - l2_valid = false; } -int Packet::GetLinkHeaderSize(int link_type) - { - switch ( link_type ) { - case DLT_NULL: - return 4; - - case DLT_EN10MB: - return 14; - - case DLT_FDDI: - return 13 + 8; // fddi_header + LLC - -#ifdef DLT_LINUX_SLL - case DLT_LINUX_SLL: - return 16; -#endif - - case DLT_PPP_SERIAL: // PPP_SERIAL - return 4; - - case DLT_IEEE802_11: // 802.11 monitor - return 34; - - case DLT_IEEE802_11_RADIO: // 802.11 plus RadioTap - return 59; - - case DLT_NFLOG: - // Linux netlink NETLINK NFLOG socket log messages - // The actual header size is variable, but we return the minimum - // expected size here, which is 4 bytes for the main header plus at - // least 2 bytes each for the type and length values assoicated with - // the final TLV carrying the packet payload. - return 8; - - case DLT_RAW: - return 0; - } - - return -1; - } - -void Packet::ProcessLayer2() - { - l2_valid = true; - - // Unfortunately some packets on the link might have MPLS labels - // while others don't. That means we need to ask the link-layer if - // labels are in place. - bool have_mpls = false; - - const u_char* pdata = data; - const u_char* end_of_data = data + cap_len; - - switch ( link_type ) { - case DLT_NULL: - { - int protocol = (pdata[3] << 24) + (pdata[2] << 16) + (pdata[1] << 8) + pdata[0]; - pdata += GetLinkHeaderSize(link_type); - - // From the Wireshark Wiki: "AF_INET6, unfortunately, has - // different values in {NetBSD,OpenBSD,BSD/OS}, - // {FreeBSD,DragonFlyBSD}, and {Darwin/Mac OS X}, so an IPv6 - // packet might have a link-layer header with 24, 28, or 30 - // as the AF_ value." As we may be reading traces captured on - // platforms other than what we're running on, we accept them - // all here. - - if ( protocol == AF_INET ) - l3_proto = L3_IPV4; - else if ( protocol == 24 || protocol == 28 || protocol == 30 ) - l3_proto = L3_IPV6; - else - { - Weird("non_ip_packet_in_null_transport"); - return; - } - - break; - } - - case DLT_EN10MB: - { - // Skip past Cisco FabricPath to encapsulated ethernet frame. - if ( pdata[12] == 0x89 && pdata[13] == 0x03 ) - { - auto constexpr cfplen = 16; - - if ( pdata + cfplen + GetLinkHeaderSize(link_type) >= end_of_data ) - { - Weird("truncated_link_header_cfp"); - return; - } - - pdata += cfplen; - } - - // Get protocol being carried from the ethernet frame. - int protocol = (pdata[12] << 8) + pdata[13]; - - eth_type = protocol; - l2_dst = pdata; - l2_src = pdata + 6; - - pdata += GetLinkHeaderSize(link_type); - - bool saw_vlan = false; - - while ( protocol == 0x8100 || protocol == 0x9100 || - protocol == 0x8864 ) - { - switch ( protocol ) - { - // VLAN carried over the ethernet frame. - // 802.1q / 802.1ad - case 0x8100: - case 0x9100: - { - if ( pdata + 4 >= end_of_data ) - { - Weird("truncated_link_header"); - return; - } - - auto& vlan_ref = saw_vlan ? inner_vlan : vlan; - vlan_ref = ((pdata[0] << 8) + pdata[1]) & 0xfff; - protocol = ((pdata[2] << 8) + pdata[3]); - pdata += 4; // Skip the vlan header - saw_vlan = true; - eth_type = protocol; - } - break; - - // PPPoE carried over the ethernet frame. - case 0x8864: - { - if ( pdata + 8 >= end_of_data ) - { - Weird("truncated_link_header"); - return; - } - - protocol = (pdata[6] << 8) + pdata[7]; - pdata += 8; // Skip the PPPoE session and PPP header - - if ( protocol == 0x0021 ) - l3_proto = L3_IPV4; - else if ( protocol == 0x0057 ) - l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("non_ip_packet_in_pppoe_encapsulation"); - return; - } - } - break; - } - } - - // Check for MPLS in VLAN. - if ( protocol == 0x8847 ) - have_mpls = true; - - // Normal path to determine Layer 3 protocol. - if ( ! have_mpls && l3_proto == L3_UNKNOWN ) - { - if ( protocol == 0x800 ) - l3_proto = L3_IPV4; - else if ( protocol == 0x86dd ) - l3_proto = L3_IPV6; - else if ( protocol == 0x0806 || protocol == 0x8035 ) - l3_proto = L3_ARP; - else - { - // Neither IPv4 nor IPv6. - Weird("non_ip_packet_in_ethernet"); - return; - } - } - - break; - } - - case DLT_PPP_SERIAL: - { - // Get PPP protocol. - int protocol = (pdata[2] << 8) + pdata[3]; - pdata += GetLinkHeaderSize(link_type); - - if ( protocol == 0x0281 ) - { - // MPLS Unicast. Remove the pdata link layer and - // denote a header size of zero before the IP header. - have_mpls = true; - } - else if ( protocol == 0x0021 ) - l3_proto = L3_IPV4; - else if ( protocol == 0x0057 ) - l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("non_ip_packet_in_ppp_encapsulation"); - return; - } - break; - } - - case DLT_IEEE802_11_RADIO: - { - if ( pdata + 3 >= end_of_data ) - { - Weird("truncated_radiotap_header"); - return; - } - - // Skip over the RadioTap header - int rtheader_len = (pdata[3] << 8) + pdata[2]; - - if ( pdata + rtheader_len >= end_of_data ) - { - Weird("truncated_radiotap_header"); - return; - } - - pdata += rtheader_len; - // fallthrough - } - - case DLT_IEEE802_11: - { - u_char len_80211 = 24; // minimal length of data frames - - if ( pdata + len_80211 >= end_of_data ) - { - Weird("truncated_802_11_header"); - return; - } - - u_char fc_80211 = pdata[0]; // Frame Control field - - // Skip non-data frame types (management & control). - if ( ! ((fc_80211 >> 2) & 0x02) ) - return; - - // Skip subtypes without data. - if ( (fc_80211 >> 4) & 0x04 ) - return; - - // 'To DS' and 'From DS' flags set indicate use of the 4th - // address field. - if ( (pdata[1] & 0x03) == 0x03 ) - len_80211 += l2_addr_len; - - // Look for the QoS indicator bit. - if ( (fc_80211 >> 4) & 0x08 ) - { - // Skip in case of A-MSDU subframes indicated by QoS - // control field. - if ( pdata[len_80211] & 0x80) - return; - - len_80211 += 2; - } - - if ( pdata + len_80211 >= end_of_data ) - { - Weird("truncated_802_11_header"); - return; - } - - // Determine link-layer addresses based - // on 'To DS' and 'From DS' flags - switch ( pdata[1] & 0x03 ) { - case 0x00: - l2_src = pdata + 10; - l2_dst = pdata + 4; - break; - - case 0x01: - l2_src = pdata + 10; - l2_dst = pdata + 16; - break; - - case 0x02: - l2_src = pdata + 16; - l2_dst = pdata + 4; - break; - - case 0x03: - l2_src = pdata + 24; - l2_dst = pdata + 16; - break; - } - - // skip 802.11 data header - pdata += len_80211; - - if ( pdata + 8 >= end_of_data ) - { - Weird("truncated_802_11_header"); - return; - } - // Check that the DSAP and SSAP are both SNAP and that the control - // field indicates that this is an unnumbered frame. - // The organization code (24bits) needs to also be zero to - // indicate that this is encapsulated ethernet. - if ( pdata[0] == 0xAA && pdata[1] == 0xAA && pdata[2] == 0x03 && - pdata[3] == 0 && pdata[4] == 0 && pdata[5] == 0 ) - { - pdata += 6; - } - else - { - // If this is a logical link control frame without the - // possibility of having a protocol we care about, we'll - // just skip it for now. - return; - } - - int protocol = (pdata[0] << 8) + pdata[1]; - if ( protocol == 0x0800 ) - l3_proto = L3_IPV4; - else if ( protocol == 0x86DD ) - l3_proto = L3_IPV6; - else if ( protocol == 0x0806 || protocol == 0x8035 ) - l3_proto = L3_ARP; - else - { - Weird("non_ip_packet_in_ieee802_11"); - return; - } - pdata += 2; - - break; - } - - case DLT_NFLOG: - { - // See https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html - - uint8_t protocol = pdata[0]; - - if ( protocol == AF_INET ) - l3_proto = L3_IPV4; - else if ( protocol == AF_INET6 ) - l3_proto = L3_IPV6; - else - { - Weird("non_ip_in_nflog"); - return; - } - - uint8_t version = pdata[1]; - - if ( version != 0 ) - { - Weird("unknown_nflog_version"); - return; - } - - // Skip to TLVs. - pdata += 4; - - uint16_t tlv_len; - uint16_t tlv_type; - - while ( true ) - { - if ( pdata + 4 >= end_of_data ) - { - Weird("nflog_no_pcap_payload"); - return; - } - - // TLV Type and Length values are specified in host byte order - // (libpcap should have done any needed byteswapping already). - - tlv_len = *(reinterpret_cast(pdata)); - tlv_type = *(reinterpret_cast(pdata + 2)); - - auto constexpr nflog_type_payload = 9; - - if ( tlv_type == nflog_type_payload ) - { - // The raw packet payload follows this TLV. - pdata += 4; - break; - } - else - { - // The Length value includes the 4 octets for the Type and - // Length values, but TLVs are also implicitly padded to - // 32-bit alignments (that padding may not be included in - // the Length value). - - if ( tlv_len < 4 ) - { - Weird("nflog_bad_tlv_len"); - return; - } - else - { - auto rem = tlv_len % 4; - - if ( rem != 0 ) - tlv_len += 4 - rem; - } - - pdata += tlv_len; - } - } - - break; - } - - default: - { - // Assume we're pointing at IP. Just figure out which version. - pdata += GetLinkHeaderSize(link_type); - if ( pdata + sizeof(struct ip) >= end_of_data ) - { - Weird("truncated_link_header"); - return; - } - - const struct ip* ip = (const struct ip *)pdata; - - if ( ip->ip_v == 4 ) - l3_proto = L3_IPV4; - else if ( ip->ip_v == 6 ) - l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("non_ip_packet"); - return; - } - - break; - } - } - - if ( have_mpls ) - { - // Skip the MPLS label stack. - bool end_of_stack = false; - - while ( ! end_of_stack ) - { - if ( pdata + 4 >= end_of_data ) - { - Weird("truncated_link_header"); - return; - } - - end_of_stack = *(pdata + 2) & 0x01; - pdata += 4; - } - - // We assume that what remains is IP - if ( pdata + sizeof(struct ip) >= end_of_data ) - { - Weird("no_ip_in_mpls_payload"); - return; - } - - const struct ip* ip = (const struct ip *)pdata; - - if ( ip->ip_v == 4 ) - l3_proto = L3_IPV4; - else if ( ip->ip_v == 6 ) - l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("no_ip_in_mpls_payload"); - return; - } - } - - else if ( zeek::detail::encap_hdr_size ) - { - // Blanket encapsulation. We assume that what remains is IP. - if ( pdata + zeek::detail::encap_hdr_size + sizeof(struct ip) >= end_of_data ) - { - Weird("no_ip_left_after_encap"); - return; - } - - pdata += zeek::detail::encap_hdr_size; - - const struct ip* ip = (const struct ip *)pdata; - - if ( ip->ip_v == 4 ) - l3_proto = L3_IPV4; - else if ( ip->ip_v == 6 ) - l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("no_ip_in_encap"); - return; - } - - } - - // We've now determined (a) L3_IPV4 vs (b) L3_IPV6 vs (c) L3_ARP vs - // (d) L3_UNKNOWN. - - // Calculate how much header we've used up. - hdr_size = (pdata - data); -} - RecordValPtr Packet::ToRawPktHdrVal() const { static auto raw_pkt_hdr_type = id::find_type("raw_pkt_hdr"); @@ -613,6 +101,7 @@ RecordValPtr Packet::ToRawPktHdrVal() const else if ( l3_proto == L3_ARP ) l3 = BifEnum::L3_ARP; + // TODO: Get rid of hardcoded l3 protocols. // l2_hdr layout: // encap: link_encap; ##< L2 link encapsulation // len: count; ##< Total frame length on wire @@ -683,12 +172,4 @@ ValPtr Packet::FmtEUI48(const u_char* mac) const return make_intrusive(buf); } -void Packet::Describe(ODesc* d) const - { - const IP_Hdr ip = IP(); - d->Add(ip.SrcAddr()); - d->Add("->"); - d->Add(ip.DstAddr()); - } - } // namespace zeek diff --git a/src/iosource/Packet.h b/src/iosource/Packet.h index 5ac6f1f876..8d4e5ba60d 100644 --- a/src/iosource/Packet.h +++ b/src/iosource/Packet.h @@ -116,18 +116,9 @@ public: uint32_t len, const u_char *data, bool copy = false, std::string tag = std::string("")); - /** - * Returns true if parsing the layer 2 fields failed, including when - * no data was passed into the constructor in the first place. - */ - bool Layer2Valid() const - { - return l2_valid; - } - /** * Interprets the Layer 3 of the packet as IP and returns a - * correspondign object. + * corresponding object. */ const IP_Hdr IP() const; @@ -140,25 +131,17 @@ public: [[deprecated("Remove in v4.1. Use ToRawPktHdrval() instead.")]] RecordVal* BuildPktHdrVal() const; - /** - * Static method returning the link-layer header size for a given - * link type. - * - * @param link_type The link tyoe. - * - * @return The header size in bytes, or -1 if not known. - */ - static int GetLinkHeaderSize(int link_type); - - /** - * Describes the packet, with standard signature. - */ - void Describe(ODesc* d) const; - /** * Maximal length of a layer 2 address. */ - static const int l2_addr_len = 6; + static const int L2_ADDR_LEN = 6; + + /** + * Empty layer 2 address to be used as default value. For example, the + * LinuxSLL packet analyzer doesn't have a destination address in the + * header and thus sets it to this default address. + */ + static constexpr const u_char L2_EMPTY_ADDR[L2_ADDR_LEN] = { 0 }; // These are passed in through the constructor. std::string tag; /// Used in serialization @@ -166,49 +149,50 @@ public: pkt_timeval ts; /// Capture timestamp const u_char* data; /// Packet data. uint32_t len; /// Actual length on wire - uint32_t cap_len; /// Captured packet length + uint32_t cap_len; /// Captured packet length uint32_t link_type; /// pcap link_type (DLT_EN10MB, DLT_RAW, etc) + // True if L2 processing succeeded. If data is set on initialization of + // the packet, L2 is assumed to be valid. The packet manager will then + // process the packet and set l2_valid to False if the analysis failed. + bool l2_valid; + // These are computed from Layer 2 data. These fields are only valid if - // Layer2Valid() returns true. + // l2_valid returns true. /** - * Layer 2 header size. Valid iff Layer2Valid() returns true. + * Layer 2 header size. Valid iff l2_valid is true. */ uint32_t hdr_size; /** - * Layer 3 protocol identified (if any). Valid iff Layer2Valid() - * returns true. + * Layer 3 protocol identified (if any). Valid iff l2_valid is true. */ Layer3Proto l3_proto; /** * If layer 2 is Ethernet, innermost ethertype field. Valid iff - * Layer2Valid() returns true. + * l2_valid is true. */ uint32_t eth_type; /** - * Layer 2 source address. Valid iff Layer2Valid() returns true. + * Layer 2 source address. Valid iff l2_valid is true. */ const u_char* l2_src; /** - * Layer 2 destination address. Valid iff Layer2Valid() returns - * true. + * Layer 2 destination address. Valid iff l2_valid is true. */ const u_char* l2_dst; /** - * (Outermost) VLAN tag if any, else 0. Valid iff Layer2Valid() - * returns true. + * (Outermost) VLAN tag if any, else 0. Valid iff l2_valid is true. */ uint32_t vlan; /** - * (Innermost) VLAN tag if any, else 0. Valid iff Layer2Valid() - * returns true. + * (Innermost) VLAN tag if any, else 0. Valid iff l2_valid is true. */ uint32_t inner_vlan; @@ -224,22 +208,27 @@ public: */ bool l3_checksummed; -private: - // Calculate layer 2 attributes. - void ProcessLayer2(); + /** + * Indicates whether the packet should be processed by zeek's + * session analysis in NetSessions. + */ + bool session_analysis; - // Wrapper to generate a packet-level weird. + /** + * Indicates whether this packet should be recorded. + */ + mutable bool dump_packet; + + // Wrapper to generate a packet-level weird. Has to be public for packet analyzers to use it. void Weird(const char* name); +private: // Renders an MAC address into its ASCII representation. ValPtr FmtEUI48(const u_char* mac) const; // True if we need to delete associated packet memory upon // destruction. bool copy; - - // True if L2 processing succeeded. - bool l2_valid; }; } // namespace zeek diff --git a/src/iosource/PktDumper.cc b/src/iosource/PktDumper.cc index 87e4c6cae7..336b5f7777 100644 --- a/src/iosource/PktDumper.cc +++ b/src/iosource/PktDumper.cc @@ -53,11 +53,6 @@ const char* PktDumper::ErrorMsg() const return errmsg.size() ? errmsg.c_str() : nullptr; } -int PktDumper::HdrSize() const - { - return is_open ? props.hdr_size : -1; - } - void PktDumper::Opened(const Properties& arg_props) { is_open = true; diff --git a/src/iosource/PktDumper.h b/src/iosource/PktDumper.h index c279a704f0..5210a3c98f 100644 --- a/src/iosource/PktDumper.h +++ b/src/iosource/PktDumper.h @@ -50,11 +50,6 @@ public: */ const char* ErrorMsg() const; - /** - * Returns the size of the link-layer headers with this dumper. - */ - int HdrSize() const; - // PktDumper interface for derived classes to implement. /** @@ -97,7 +92,6 @@ protected: */ struct Properties { std::string path; - int hdr_size; double open_time; }; diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index c20e29d35c..38fb51cefb 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -90,16 +90,6 @@ double PktSrc::CurrentPacketWallClock() void PktSrc::Opened(const Properties& arg_props) { - if ( Packet::GetLinkHeaderSize(arg_props.link_type) < 0 ) - { - char buf[512]; - snprintf(buf, sizeof(buf), - "unknown data link type 0x%x", arg_props.link_type); - Error(buf); - Close(); - return; - } - props = arg_props; SetClosed(false); @@ -199,7 +189,7 @@ void PktSrc::Process() if ( ! ExtractNextPacketInternal() ) return; - if ( current_packet.Layer2Valid() ) + if ( current_packet.l2_valid ) { if ( run_state::pseudo_realtime ) { diff --git a/src/iosource/pcap/Dumper.cc b/src/iosource/pcap/Dumper.cc index 78e3f97cf8..b7a47756ce 100644 --- a/src/iosource/pcap/Dumper.cc +++ b/src/iosource/pcap/Dumper.cc @@ -82,7 +82,6 @@ void PcapDumper::Open() } props.open_time = run_state::network_time; - props.hdr_size = Packet::GetLinkHeaderSize(pcap_datalink(pd)); Opened(props); } diff --git a/src/packet_analysis/Analyzer.cc b/src/packet_analysis/Analyzer.cc new file mode 100644 index 0000000000..9587423ea2 --- /dev/null +++ b/src/packet_analysis/Analyzer.cc @@ -0,0 +1,135 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Analyzer.h" + +#include "Dict.h" +#include "DebugLogger.h" + +namespace zeek::packet_analysis { + +Analyzer::Analyzer(std::string name) + { + Tag t = packet_mgr->GetComponentTag(name); + + if ( ! t ) + reporter->InternalError("unknown packet_analysis name %s", name.c_str()); + + Init(t); + } + +Analyzer::Analyzer(const Tag& tag) + { + Init(tag); + } + +void Analyzer::Init(const Tag& _tag) + { + tag = _tag; + } + +void Analyzer::Initialize() + { + default_analyzer = LoadAnalyzer("default_analyzer"); + + // Create dispatcher based on configuration + auto& mapping_id = zeek::id::find(GetModuleName() + "dispatch_map"); + if ( ! mapping_id ) + return; + + auto mapping_val = mapping_id->GetVal()->AsTableVal(); + auto mapping_tbl = mapping_val->AsTable(); + auto c = mapping_tbl->InitForIteration(); + + zeek::detail::HashKey* k = nullptr; + TableEntryVal* v; + while ( (v = mapping_tbl->NextEntry(k, c)) ) + { + auto key = mapping_val->RecreateIndex(*k); + delete k; + + auto identifier = key->Idx(0)->AsCount(); + auto config_entry_val = v->GetVal()->AsRecordVal(); + + auto mapped_tag = config_entry_val->GetField("analyzer")->AsEnumVal(); + auto mapped_analyzer = packet_mgr->GetAnalyzer(mapped_tag); + + dispatcher.Register(identifier, std::move(mapped_analyzer)); + } + } + +zeek::packet_analysis::AnalyzerPtr Analyzer::LoadAnalyzer(const std::string &name) + { + auto& analyzer = zeek::id::find(GetModuleName() + name); + if ( ! analyzer ) + return nullptr; + + auto& analyzer_val = analyzer->GetVal(); + if ( ! analyzer_val ) + return nullptr; + + return packet_mgr->GetAnalyzer(analyzer_val->AsEnumVal()); + } + +const Tag Analyzer::GetAnalyzerTag() const + { + assert(tag); + return tag; + } + +const char* Analyzer::GetAnalyzerName() const + { + assert(tag); + return packet_mgr->GetComponentName(tag).c_str(); + } + +bool Analyzer::IsAnalyzer(const char* name) + { + assert(tag); + return packet_mgr->GetComponentName(tag) == name; + } + +AnalyzerPtr Analyzer::Lookup(uint32_t identifier) const + { + return dispatcher.Lookup(identifier); + } + +bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet, + uint32_t identifier) const + { + auto inner_analyzer = Lookup(identifier); + if ( ! inner_analyzer ) + inner_analyzer = default_analyzer; + + if ( inner_analyzer == nullptr ) + { + 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 false; + } + + DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.", + GetAnalyzerName(), identifier); + return inner_analyzer->AnalyzePacket(len, data, packet); + } + +bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet) const + { + if ( default_analyzer ) + return default_analyzer->AnalyzePacket(len, data, packet); + + DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s stopped, no default analyzer available.", + GetAnalyzerName()); + packet->Weird("no_suitable_analyzer_found"); + return true; + } + +void Analyzer::DumpDebug() const + { +#ifdef DEBUG + DBG_LOG(DBG_PACKET_ANALYSIS, "Dispatcher for %s", this->GetAnalyzerName()); + dispatcher.DumpDebug(); +#endif + } + +} diff --git a/src/packet_analysis/Analyzer.h b/src/packet_analysis/Analyzer.h new file mode 100644 index 0000000000..241787135e --- /dev/null +++ b/src/packet_analysis/Analyzer.h @@ -0,0 +1,150 @@ +// See the file "COPYING" in the main distribution directory for copyright. +#pragma once + +#include "Manager.h" +#include "Tag.h" +#include + +namespace zeek::packet_analysis { + +/** + * Main packet analyzer interface. + */ +class Analyzer { +public: + /** + * Constructor. + * + * @param name The name for the type of analyzer. The name must match + * the one the corresponding Component registers. + */ + explicit Analyzer(std::string name); + + /** + * Constructor. + * + * @param tag The tag for the type of analyzer. The tag must map to + * the name the corresponding Component registers. + */ + explicit Analyzer(const Tag& tag); + + /** + * Destructor. + */ + virtual ~Analyzer() = default; + + /** + * Initialize the analyzer. This method is called after the configuration + * was read. Derived classes can override this method to implement custom + * initialization. + * When overriding this methods, always make sure to call the base-class + * version to ensure proper initialization. + */ + virtual void Initialize(); + + /** + * Returns the tag associated with the analyzer's type. + */ + const Tag GetAnalyzerTag() const; + + /** + * Returns a textual description of the analyzer's type. This is + * what's passed to the constructor and usually corresponds to the + * protocol name, e.g., "ARP". + */ + const char* GetAnalyzerName() const; + + /** + * Returns true if this analyzer's type matches the name passes in. + * This is shortcut for comparing GetAnalyzerName() with the given + * name. + * + * @param name The name to check. + */ + bool IsAnalyzer(const char* name); + + /** + * Analyzes the given packet. A common case is that the analyzed protocol + * encapsulates another protocol, which can be determined by an identifier + * in the header. In this case, derived classes may use ForwardPacket() to + * forward the payload to the corresponding analyzer. + * + * @param len The number of bytes passed in. + * @param data Pointer to the input to process. + * @param packet Object that maintains the packet's meta data. + * + * @return false if the analysis failed, else true. + */ + virtual bool AnalyzePacket(size_t len, const uint8_t* data, + Packet* packet) = 0; + + /** + * Dumps out debug information to the \c analyzer debug stream. + */ + void DumpDebug() const; + +protected: + friend class Manager; + + /** + * Looks up the analyzer for the encapsulated protocol based on the given + * identifier. + * + * @param identifier Identifier for the encapsulated protocol. + * @return The analyzer registered for the given identifier. Returns a + * nullptr if no analyzer is registered. + */ + AnalyzerPtr Lookup(uint32_t identifier) const; + + /** + * Returns an analyzer based on a script-land definition. + * + * @param name The script-land identifier for a PacketAnalyzer::Tag value. + * @return The defined analyzer if available, else nullptr. + */ + AnalyzerPtr LoadAnalyzer(const std::string& name); + + /** + * Returns the module name corresponding to the analyzer, i.e. its script-land + * namespace. Configuration values for the analyzer are expected in this module. + * @return Analyzer's module name. + */ + std::string GetModuleName() const { + return util::fmt("PacketAnalyzer::%s::", GetAnalyzerName()); + }; + + /** + * 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 false if the analysis failed, else true. + */ + bool ForwardPacket(size_t len, const uint8_t* data, Packet* packet, + uint32_t identifier) const; + + /** + * Triggers default analysis of the encapsulated packet if the default analyzer + * is set. + * + * @param packet The packet to analyze. + * @param data Reference to the payload pointer into the raw packet. + * + * @return false if the analysis failed, else true. + */ + bool ForwardPacket(size_t len, const uint8_t* data, Packet* packet) const; + +private: + Tag tag; + Dispatcher dispatcher; + AnalyzerPtr default_analyzer = nullptr; + + void Init(const Tag& tag); +}; + +using AnalyzerPtr = std::shared_ptr; + +} diff --git a/src/packet_analysis/CMakeLists.txt b/src/packet_analysis/CMakeLists.txt new file mode 100644 index 0000000000..6ece492dce --- /dev/null +++ b/src/packet_analysis/CMakeLists.txt @@ -0,0 +1,20 @@ + +include(ZeekSubdir) + +include_directories(BEFORE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +add_subdirectory(protocol) + +set(packet_analysis_SRCS + Analyzer.cc + Dispatcher.cc + Manager.cc + Component.cc + Tag.cc +) + +bro_add_subdir_library(packet_analysis ${packet_analysis_SRCS}) +add_dependencies(bro_packet_analysis generate_outputs) diff --git a/src/packet_analysis/Component.cc b/src/packet_analysis/Component.cc new file mode 100644 index 0000000000..0fec613648 --- /dev/null +++ b/src/packet_analysis/Component.cc @@ -0,0 +1,29 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Component.h" +#include "Desc.h" +#include "Manager.h" + +using namespace zeek::packet_analysis; + +Component::Component(const std::string& name, factory_callback arg_factory, Tag::subtype_t arg_subtype) + : plugin::Component(plugin::component::PACKET_ANALYZER, name), + plugin::TaggedComponent(arg_subtype) + { + factory = arg_factory; + } + +void Component::Initialize() + { + InitializeTag(); + packet_mgr->RegisterComponent(this, "ANALYZER_"); + } + +void Component::DoDescribe(ODesc* d) const + { + if ( factory ) + { + d->Add("ANALYZER_"); + d->Add(CanonicalName()); + } + } diff --git a/src/packet_analysis/Component.h b/src/packet_analysis/Component.h new file mode 100644 index 0000000000..61986719f7 --- /dev/null +++ b/src/packet_analysis/Component.h @@ -0,0 +1,47 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include "zeek-config.h" +#include "util.h" +#include "Tag.h" + +#include "plugin/Component.h" +#include "plugin/TaggedComponent.h" + +namespace zeek::packet_analysis { + +class Analyzer; +using AnalyzerPtr = std::shared_ptr; + +class Component : public plugin::Component, + public plugin::TaggedComponent { +public: + typedef AnalyzerPtr (*factory_callback)(); + + Component(const std::string& name, factory_callback factory, Tag::subtype_t subtype = 0); + ~Component() override = default; + + /** + * Initialization function. This function has to be called before any + * plugin component functionality is used; it is used to add the + * plugin component to the list of components and to initialize tags + */ + void Initialize() override; + + /** + * Returns the analyzer's factory function. + */ + factory_callback Factory() const { return factory; } + +protected: + /** + * Overriden from plugin::Component. + */ + void DoDescribe(ODesc* d) const override; + +private: + factory_callback factory; // The analyzer's factory callback. +}; + +} diff --git a/src/packet_analysis/Dispatcher.cc b/src/packet_analysis/Dispatcher.cc new file mode 100644 index 0000000000..d1b169045b --- /dev/null +++ b/src/packet_analysis/Dispatcher.cc @@ -0,0 +1,97 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include + +#include "Dispatcher.h" +#include "Analyzer.h" +#include "Reporter.h" +#include "DebugLogger.h" + +namespace zeek::packet_analysis { + +Dispatcher::~Dispatcher() + { + FreeValues(); + } + +void Dispatcher::Register(uint32_t identifier, AnalyzerPtr analyzer) + { + // If the table has size 1 and the entry is nullptr, there was nothing added yet. Just add it. + if ( table.size() == 1 && table[0] == nullptr ) + { + table[0] = std::move(analyzer); + lowest_identifier = identifier; + return; + } + + // If highestIdentifier == identifier, overwrite would happen -> no check needed, will return false + if ( GetHighestIdentifier() < identifier ) + { + table.resize(table.size() + (identifier - GetHighestIdentifier()), nullptr); + } + else if ( identifier < lowest_identifier ) + { + // Lower than the lowest registered identifier. Shift up by lowerBound - identifier + uint32_t distance = lowest_identifier - identifier; + table.resize(table.size() + distance, nullptr); + + // Shift values + for ( ssize_t i = table.size() - 1; i >= 0; i-- ) + { + if ( table[i] != nullptr ) + { + table.at(i + distance) = std::move(table.at(i)); + table.at(i) = nullptr; + } + } + + lowest_identifier = identifier; + } + + int64_t index = identifier - lowest_identifier; + if ( table[index] != nullptr ) + reporter->InternalWarning("Overwriting packet analyzer mapping %#8" PRIx64 " => %s with %s", + index+lowest_identifier, table[index]->GetAnalyzerName(), analyzer->GetAnalyzerName()); + table[index] = std::move(analyzer); + } + +AnalyzerPtr Dispatcher::Lookup(uint32_t identifier) const + { + int64_t index = identifier - lowest_identifier; + if ( index >= 0 && index < static_cast(table.size()) && table[index] != nullptr ) + return table[index]; + + return nullptr; + } + +size_t Dispatcher::Count() const + { + return std::count_if(table.begin(), table.end(), [](AnalyzerPtr a) { return a != nullptr; }); + } + +void Dispatcher::Clear() + { + FreeValues(); + table.clear(); + } + +void Dispatcher::FreeValues() + { + for ( auto& current : table ) + current = nullptr; + } + +void Dispatcher::DumpDebug() const + { +#ifdef DEBUG + DBG_LOG(DBG_PACKET_ANALYSIS, "Dispatcher elements (used/total): %lu/%lu", Count(), table.size()); + for ( size_t i = 0; i < table.size(); i++ ) + { + if ( table[i] != nullptr ) + DBG_LOG(DBG_PACKET_ANALYSIS, "%#8lx => %s", + i+lowest_identifier, table[i]->GetAnalyzerName()); + } +#endif + } + +} diff --git a/src/packet_analysis/Dispatcher.h b/src/packet_analysis/Dispatcher.h new file mode 100644 index 0000000000..2c556e074c --- /dev/null +++ b/src/packet_analysis/Dispatcher.h @@ -0,0 +1,68 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include +#include +#include + +namespace zeek::packet_analysis { + +class Analyzer; // Forward declaration for Value +using AnalyzerPtr = std::shared_ptr; + +/** + * The Dispatcher class manages identifier-to-analyzer mappings. + */ +class Dispatcher { +public: + Dispatcher() : table(std::vector(1, nullptr)) { }; + ~Dispatcher(); + + /** + * Register an analyzer for a given identifier. + * + * @param identifier The identifier. + * @param analyzer The analyzer to register. + */ + void Register(uint32_t identifier, AnalyzerPtr analyzer); + + /** + * Looks up the analyzer for an identifier. + * + * @param identifier The identifier to look up. + * @return The analyzer registered for the given identifier. Returns a + * nullptr if no analyzer is registered. + */ + AnalyzerPtr Lookup(uint32_t identifier) const; + + /** + * Returns the number of registered analyzers. + * @return Number of registered analyzers. + */ + size_t Count() const; + + /** + * Removes all mappings from the dispatcher. + */ + void Clear(); + + /** + * Dumps out the data structure to the \c analyzer debug stream. + */ + void DumpDebug() const; + +private: + uint32_t lowest_identifier = 0; + std::vector table; + + void FreeValues(); + + inline uint32_t GetHighestIdentifier() const + { + return lowest_identifier + table.size() - 1; + } +}; + +} diff --git a/src/packet_analysis/Manager.cc b/src/packet_analysis/Manager.cc new file mode 100644 index 0000000000..4229bfb33a --- /dev/null +++ b/src/packet_analysis/Manager.cc @@ -0,0 +1,114 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Manager.h" + +#include "Analyzer.h" +#include "Dispatcher.h" + +using namespace zeek::packet_analysis; + +Manager::Manager() + : plugin::ComponentManager("PacketAnalyzer", "Tag") + { + } + +void Manager::InitPostScript() + { + // Instantiate objects for all available analyzers + for ( const auto& analyzerComponent : GetComponents() ) + { + if ( AnalyzerPtr newAnalyzer = InstantiateAnalyzer(analyzerComponent->Tag()) ) + analyzers.emplace(analyzerComponent->Name(), newAnalyzer); + } + + // Initialize all analyzers + for ( auto& [name, analyzer] : analyzers ) + analyzer->Initialize(); + + root_analyzer = analyzers["Root"]; + } + +void Manager::Done() + { + } + +void Manager::DumpDebug() + { +#ifdef DEBUG + DBG_LOG(DBG_PACKET_ANALYSIS, "Available packet analyzers after zeek_init():"); + for ( auto& current : GetComponents() ) + DBG_LOG(DBG_PACKET_ANALYSIS, " %s", current->Name().c_str()); + + DBG_LOG(DBG_PACKET_ANALYSIS, "Packet analyzer debug information:"); + for ( auto& [name, analyzer] : analyzers ) + analyzer->DumpDebug(); +#endif + } + +AnalyzerPtr Manager::GetAnalyzer(EnumVal *val) + { + auto analyzer_comp = Lookup(val); + if ( ! analyzer_comp ) + return nullptr; + + return GetAnalyzer(analyzer_comp->Name()); + } + +AnalyzerPtr Manager::GetAnalyzer(const std::string& name) + { + auto analyzer_it = analyzers.find(name); + if ( analyzer_it == analyzers.end() ) + return nullptr; + + return analyzer_it->second; + } + +void Manager::ProcessPacket(Packet* packet) + { +#ifdef DEBUG + static size_t counter = 0; + DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time); +#endif + // Start packet analysis + packet->l2_valid = root_analyzer->ForwardPacket(packet->cap_len, packet->data, + packet, packet->link_type); + } + +AnalyzerPtr Manager::InstantiateAnalyzer(const Tag& tag) + { + Component* c = Lookup(tag); + + if ( ! c ) + { + reporter->InternalWarning("request to instantiate unknown packet_analysis"); + return nullptr; + } + + if ( ! c->Factory() ) + { + reporter->InternalWarning("analyzer %s cannot be instantiated dynamically", GetComponentName(tag).c_str()); + return nullptr; + } + + AnalyzerPtr a = c->Factory()(); + + if ( ! a ) + { + reporter->InternalWarning("analyzer instantiation failed"); + return nullptr; + } + + if ( tag != a->GetAnalyzerTag() ) + { + reporter->InternalError("Mismatch of requested analyzer %s and instantiated analyzer %s. This usually means that the plugin author made a mistake.", + GetComponentName(tag).c_str(), GetComponentName(a->GetAnalyzerTag()).c_str()); + } + + return a; + } + +AnalyzerPtr Manager::InstantiateAnalyzer(const std::string& name) + { + Tag tag = GetComponentTag(name); + return tag ? InstantiateAnalyzer(tag) : nullptr; + } diff --git a/src/packet_analysis/Manager.h b/src/packet_analysis/Manager.h new file mode 100644 index 0000000000..7030c8fc05 --- /dev/null +++ b/src/packet_analysis/Manager.h @@ -0,0 +1,98 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include "Tag.h" +#include "Component.h" +#include "plugin/ComponentManager.h" +#include "iosource/Packet.h" +#include "Dispatcher.h" + +namespace zeek::packet_analysis { + +class Analyzer; +using AnalyzerPtr = std::shared_ptr; + +class Manager : public plugin::ComponentManager { +public: + /** + * Constructor. + */ + Manager(); + + /** + * Destructor. + */ + ~Manager() = default; + + /** + * Second-stage initialization of the manager. This is called late + * during Zeek's initialization after any scripts are processed. + */ + void InitPostScript(); + + /** + * Finished the manager's operations. + */ + void Done(); + + /** + * Dumps out the state of all registered analyzers to the \c analyzer + * debug stream. Should be called only after any \c zeek_init events + * have executed to ensure that any of their changes are applied. + */ + void DumpDebug(); // Called after zeek_init() events. + + /** + * Looks up an analyzer instance. + * + * @param val The analyzer's tag value. + * + * @return The analyzer instance or nullptr if no instance is found. + */ + AnalyzerPtr GetAnalyzer(EnumVal *val); + + /** + * Looks up an analyzer instance. + * + * @param name The name of the analyzer. + * + * @return The analyzer instance or nullptr if no instance is found. + */ + AnalyzerPtr GetAnalyzer(const std::string& name); + + /** + * Processes a packet by applying the configured packet analyzers. + * + * @param packet The packet to process. + */ + void ProcessPacket(Packet* packet); + +private: + /** + * Instantiates a new analyzer instance. + * + * @param tag The analyzer's tag. + * + * @return The new analyzer instance. Returns null if tag is invalid, the + * requested analyzer is disabled, or the analyzer can't be instantiated. + */ + AnalyzerPtr InstantiateAnalyzer(const Tag& tag); + + /** + * Instantiates a new analyzer. + * + * @param name The name of the analyzer. + * + * @return The new analyzer instance. Returns null if the name is not known + * or if the requested analyzer that is disabled. + */ + AnalyzerPtr InstantiateAnalyzer(const std::string& name); + + std::map analyzers; + AnalyzerPtr root_analyzer = nullptr; +}; + +} + +extern zeek::packet_analysis::Manager* packet_mgr; diff --git a/src/packet_analysis/Tag.cc b/src/packet_analysis/Tag.cc new file mode 100644 index 0000000000..8a3cc89ea6 --- /dev/null +++ b/src/packet_analysis/Tag.cc @@ -0,0 +1,31 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Tag.h" +#include "Manager.h" + +namespace zeek::packet_analysis { + +Tag Tag::Error; + +Tag::Tag(type_t type, subtype_t subtype) + : zeek::Tag(packet_mgr->GetTagType(), type, subtype) + { + } + +Tag& Tag::operator=(const Tag& other) + { + zeek::Tag::operator=(other); + return *this; + } + +const IntrusivePtr& Tag::AsVal() const + { + return zeek::Tag::AsVal(packet_mgr->GetTagType()); + } + +Tag::Tag(IntrusivePtr val) + : zeek::Tag(std::move(val)) + { + } + +} diff --git a/src/packet_analysis/Tag.h b/src/packet_analysis/Tag.h new file mode 100644 index 0000000000..6233f6d89e --- /dev/null +++ b/src/packet_analysis/Tag.h @@ -0,0 +1,110 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include "zeek-config.h" +#include "../Tag.h" + +namespace zeek::plugin { + template class TaggedComponent; + template class ComponentManager; +} + +namespace zeek::packet_analysis { + +class Manager; +class Component; + +/** + * Class to identify a protocol analyzer type. + */ +class Tag : public zeek::Tag { +public: + /* + * Copy constructor. + */ + Tag(const Tag& other) : zeek::Tag(other) { } + + /** + * Default constructor. This initializes the tag with an error value + * that will make \c operator \c bool return false. + */ + Tag() : zeek::Tag() { } + + /** + * Destructor. + */ + ~Tag() = default; + + /** + * Returns false if the tag represents an error value rather than a + * legal analyzer type. + */ + explicit operator bool() const { return *this != Tag(); } + + /** + * Assignment operator. + */ + Tag& operator=(const Tag& other); + + /** + * Compares two tags for equality. + */ + bool operator==(const Tag& other) const + { + return zeek::Tag::operator==(other); + } + + /** + * Compares two tags for inequality. + */ + bool operator!=(const Tag& other) const + { + return zeek::Tag::operator!=(other); + } + + /** + * Compares two tags for less-than relationship. + */ + bool operator<(const Tag& other) const + { + return zeek::Tag::operator<(other); + } + + /** + * Returns the \c Analyzer::Tag enum that corresponds to this tag. + * The returned value does not have its ref-count increased. + * + * @param etype the script-layer enum type associated with the tag. + */ + const IntrusivePtr& AsVal() const; + + static Tag Error; + +protected: + + friend class packet_analysis::Manager; + friend class plugin::ComponentManager; + friend class plugin::TaggedComponent; + + /** + * Constructor. + * + * @param type The main type. Note that the \a zeek::packet_analysis::Manager + * manages the value space internally, so noone else should assign any main + * types. + * + * @param subtype The sub type, which is left to an analyzer for + * interpretation. By default it's set to zero. + */ + explicit Tag(type_t type, subtype_t subtype = 0); + + /** + * Constructor. + * + * @param val An enum value of script type \c Analyzer::Tag. + */ + explicit Tag(IntrusivePtr val); +}; + +} diff --git a/src/packet_analysis/protocol/CMakeLists.txt b/src/packet_analysis/protocol/CMakeLists.txt new file mode 100644 index 0000000000..10103d7dca --- /dev/null +++ b/src/packet_analysis/protocol/CMakeLists.txt @@ -0,0 +1,19 @@ +add_subdirectory(root) +add_subdirectory(skip) + +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(ip) +add_subdirectory(ipv4) +add_subdirectory(ipv6) diff --git a/src/packet_analysis/protocol/arp/ARP.cc b/src/packet_analysis/protocol/arp/ARP.cc new file mode 100644 index 0000000000..651c29d167 --- /dev/null +++ b/src/packet_analysis/protocol/arp/ARP.cc @@ -0,0 +1,229 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "ARP.h" +#include "Event.h" + +#include "events.bif.h" + +#include "zeek-config.h" +#ifdef HAVE_NET_ETHERNET_H +#include +#elif defined(HAVE_SYS_ETHERNET_H) +#include +#elif defined(HAVE_NETINET_IF_ETHER_H) +#include +#elif defined(HAVE_NET_ETHERTYPES_H) +#include +#endif + +using namespace zeek::packet_analysis::ARP; + +ARPAnalyzer::ARPAnalyzer() + : zeek::packet_analysis::Analyzer("ARP") + { + } + +// Argh! FreeBSD and Linux have almost completely different net/if_arp.h . +// ... and on Solaris we are missing half of the ARPOP codes, so define +// them here as necessary: + +#ifndef ARPOP_REQUEST +#define ARPOP_REQUEST 1 // ARP request. +#endif +#ifndef ARPOP_REPLY +#define ARPOP_REPLY 2 // ARP reply. +#endif +#ifndef ARPOP_PREQUEST +#define ARPOP_RREQUEST 3 // RARP request. +#endif +#ifndef ARPOP_RREPLY +#define ARPOP_RREPLY 4 // RARP reply. +#endif +#ifndef ARPOP_InREQUEST +#define ARPOP_InREQUEST 8 // InARP request. +#endif +#ifndef ARPOP_InREPLY +#define ARPOP_InREPLY 9 // InARP reply. +#endif +#ifndef ARPOP_NAK +#define ARPOP_NAK 10 // (ATM)ARP NAK. +#endif + +#ifndef ar_sha +#define ar_sha(ap) ((caddr_t((ap)+1)) + 0) +#endif + +#ifndef ar_spa +#define ar_spa(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln) +#endif + +#ifndef ar_tha +#define ar_tha(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln) +#endif + +#ifndef ar_tpa +#define ar_tpa(ap) ((caddr_t((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln) +#endif + +#ifndef ARPOP_REVREQUEST +#define ARPOP_REVREQUEST ARPOP_RREQUEST +#endif + +#ifndef ARPOP_REVREPLY +#define ARPOP_REVREPLY ARPOP_RREPLY +#endif + +#ifndef ARPOP_INVREQUEST +#define ARPOP_INVREQUEST ARPOP_InREQUEST +#endif + +#ifndef ARPOP_INVREPLY +#define ARPOP_INVREPLY ARPOP_InREPLY +#endif + +bool ARPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + packet->l3_proto = L3_ARP; + + // Check whether the header is complete. + if ( sizeof(struct arp_pkthdr) > len ) + { + packet->Weird("truncated_ARP"); + return false; + } + + // Check whether the packet is OK ("inspired" in tcpdump's print-arp.c). + auto ah = (const struct arp_pkthdr*) data; + + // Check the size. + size_t min_length = (ar_tpa(ah) - (char*) data) + ah->ar_pln; + if ( min_length > len ) + { + packet->Weird("truncated_ARP"); + return false; + } + + // Check the address description fields. + switch ( ntohs(ah->ar_hrd) ) { + case ARPHRD_ETHER: + if ( ah->ar_hln != 6 ) + { + // don't know how to handle the opcode + BadARPEvent(ah, "corrupt-arp-header (hrd=%i, hln=%i)", + ntohs(ah->ar_hrd), ah->ar_hln); + return false; + } + break; + + default: + { + // don't know how to proceed + BadARPEvent(ah, "unknown-arp-hw-address (hrd=%i)", ntohs(ah->ar_hrd)); + return false; + } + } + + // Note: We don't support IPv6 addresses. + switch ( ntohs(ah->ar_pro) ) { + case ETHERTYPE_IP: + if ( ah->ar_pln != 4 ) + { + // don't know how to handle the opcode + BadARPEvent(ah,"corrupt-arp-header (pro=%i, pln=%i)", + ntohs(ah->ar_pro), ah->ar_pln); + return false; + } + break; + + default: + { + // don't know how to proceed + BadARPEvent(ah,"unknown-arp-proto-address (pro=%i)", ntohs(ah->ar_pro)); + return false; + } + } + + + // Check MAC src address = ARP sender MAC address. + if ( memcmp(packet->l2_src, ar_sha(ah), ah->ar_hln) != 0 ) + { + BadARPEvent(ah, "weird-arp-sha"); + return false; + } + + // Check the code is supported. + switch ( ntohs(ah->ar_op) ) { + case ARPOP_REQUEST: + RequestReplyEvent(arp_request, packet->l2_src, packet->l2_dst, + ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah)); + break; + + case ARPOP_REPLY: + RequestReplyEvent(arp_reply, packet->l2_src, packet->l2_dst, + ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah)); + break; + + case ARPOP_REVREQUEST: + case ARPOP_REVREPLY: + case ARPOP_INVREQUEST: + case ARPOP_INVREPLY: + { + // don't know how to handle the opcode + BadARPEvent(ah, "unimplemented-arp-opcode (%i)", ntohs(ah->ar_op)); + return false; + } + + default: + { + // invalid opcode + BadARPEvent(ah, "invalid-arp-opcode (opcode=%i)", ntohs(ah->ar_op)); + return false; + } + } + + + // Leave packet analyzer land + return true; + } + +zeek::AddrValPtr ARPAnalyzer::ToAddrVal(const void* addr) + { + //Note: We only handle IPv4 addresses. + return zeek::make_intrusive(*(const uint32_t*) addr); + } + +zeek::StringValPtr ARPAnalyzer::ToEthAddrStr(const u_char* addr) + { + char buf[1024]; + snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + return zeek::make_intrusive(buf); + } + +void ARPAnalyzer::BadARPEvent(const struct arp_pkthdr* hdr, const char* fmt, ...) + { + if ( ! bad_arp ) + return; + + char msg[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(msg, sizeof(msg), fmt, args); + va_end(args); + + event_mgr.Enqueue(bad_arp, + ToAddrVal(ar_spa(hdr)), ToEthAddrStr((const u_char*) ar_sha(hdr)), + ToAddrVal(ar_tpa(hdr)), ToEthAddrStr((const u_char*) ar_tha(hdr)), + zeek::make_intrusive(msg)); + } + +void ARPAnalyzer::RequestReplyEvent(EventHandlerPtr e, const u_char *src, const u_char *dst, + const char *spa, const char *sha, const char *tpa, const char *tha) + { + if ( ! e ) + return; + + event_mgr.Enqueue(e, ToEthAddrStr(src), ToEthAddrStr(dst), + ToAddrVal(spa), ToEthAddrStr((const u_char*) sha), + ToAddrVal(tpa), ToEthAddrStr((const u_char*) tha)); + } diff --git a/src/packet_analysis/protocol/arp/ARP.h b/src/packet_analysis/protocol/arp/ARP.h new file mode 100644 index 0000000000..c4de038876 --- /dev/null +++ b/src/packet_analysis/protocol/arp/ARP.h @@ -0,0 +1,39 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +#include +#include + +#ifndef arp_pkthdr +#define arp_pkthdr arphdr +#endif + +namespace zeek::packet_analysis::ARP { + +class ARPAnalyzer : public Analyzer { +public: + ARPAnalyzer(); + ~ARPAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } + +private: + zeek::AddrValPtr ToAddrVal(const void* addr); + zeek::StringValPtr ToEthAddrStr(const u_char* addr); + + void BadARPEvent(const struct arp_pkthdr* hdr, const char* fmt, ...) + __attribute__((format(printf, 3, 4))); + void RequestReplyEvent(EventHandlerPtr e, const u_char* src, const u_char* dst, + const char* spa, const char* sha, const char* tpa, const char* tha); +}; + +} diff --git a/src/packet_analysis/protocol/arp/CMakeLists.txt b/src/packet_analysis/protocol/arp/CMakeLists.txt new file mode 100644 index 0000000000..ad3c7f732f --- /dev/null +++ b/src/packet_analysis/protocol/arp/CMakeLists.txt @@ -0,0 +1,9 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(Zeek ARP) +zeek_plugin_cc(ARP.cc Plugin.cc) +zeek_plugin_bif(events.bif) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/arp/Plugin.cc b/src/packet_analysis/protocol/arp/Plugin.cc new file mode 100644 index 0000000000..e2808cffb3 --- /dev/null +++ b/src/packet_analysis/protocol/arp/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "plugin/Plugin.h" +#include "ARP.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_ARP { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("ARP", + zeek::packet_analysis::ARP::ARPAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::ARP"; + config.description = "ARP packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/analyzer/protocol/arp/events.bif b/src/packet_analysis/protocol/arp/events.bif similarity index 100% rename from src/analyzer/protocol/arp/events.bif rename to src/packet_analysis/protocol/arp/events.bif diff --git a/src/packet_analysis/protocol/ethernet/CMakeLists.txt b/src/packet_analysis/protocol/ethernet/CMakeLists.txt new file mode 100644 index 0000000000..a852c8f3f3 --- /dev/null +++ b/src/packet_analysis/protocol/ethernet/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer Ethernet) +zeek_plugin_cc(Ethernet.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ethernet/Ethernet.cc b/src/packet_analysis/protocol/ethernet/Ethernet.cc new file mode 100644 index 0000000000..68dd5b935f --- /dev/null +++ b/src/packet_analysis/protocol/ethernet/Ethernet.cc @@ -0,0 +1,92 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Ethernet.h" +#include "NetVar.h" +#include "Manager.h" + +using namespace zeek::packet_analysis::Ethernet; + +EthernetAnalyzer::EthernetAnalyzer() + : zeek::packet_analysis::Analyzer("Ethernet") + { + } + +void EthernetAnalyzer::Initialize() + { + Analyzer::Initialize(); + + SNAPAnalyzer = LoadAnalyzer("snap_analyzer"); + NovellRawAnalyzer = LoadAnalyzer("novell_raw_analyzer"); + LLCAnalyzer = LoadAnalyzer("llc_analyzer"); + } + +bool EthernetAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + // Make sure that we actually got an entire ethernet header before trying + // to pull bytes out of it. + if ( 16 >= len ) + { + packet->Weird("truncated_ethernet_frame"); + return false; + } + + // Skip past Cisco FabricPath to encapsulated ethernet frame. + if ( data[12] == 0x89 && data[13] == 0x03 ) + { + auto constexpr cfplen = 16; + + if ( cfplen + 14 >= len ) + { + packet->Weird("truncated_link_header_cfp"); + return false; + } + + data += cfplen; + len -= cfplen; + } + + // Get protocol being carried from the ethernet frame. + uint32_t protocol = (data[12] << 8) + data[13]; + + packet->eth_type = protocol; + packet->l2_dst = data; + packet->l2_src = data + 6; + + // Ethernet II frames + if ( protocol >= 1536 ) + return ForwardPacket(len - 14, data + 14, packet, protocol); + + // Other ethernet frame types + if ( protocol <= 1500 ) + { + if ( 16 >= len ) + { + packet->Weird("truncated_ethernet_frame"); + return false; + } + + // Let specialized analyzers take over for non Ethernet II frames. + // Note that pdata remains at the start of the ethernet frame. + + AnalyzerPtr eth_analyzer = nullptr; + + if ( data[14] == 0xAA && data[15] == 0xAA) + // IEEE 802.2 SNAP + eth_analyzer = SNAPAnalyzer; + else if ( data[14] == 0xFF && data[15] == 0xFF) + // Novell raw IEEE 802.3 + eth_analyzer = NovellRawAnalyzer; + else + // IEEE 802.2 LLC + eth_analyzer = LLCAnalyzer; + + if ( eth_analyzer ) + return eth_analyzer->AnalyzePacket(len, data, packet); + + return true; + } + + // Undefined (1500 < EtherType < 1536) + packet->Weird("undefined_ether_type"); + return false; + } diff --git a/src/packet_analysis/protocol/ethernet/Ethernet.h b/src/packet_analysis/protocol/ethernet/Ethernet.h new file mode 100644 index 0000000000..ea003d27ab --- /dev/null +++ b/src/packet_analysis/protocol/ethernet/Ethernet.h @@ -0,0 +1,29 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::Ethernet { + +class EthernetAnalyzer : public Analyzer { +public: + EthernetAnalyzer(); + ~EthernetAnalyzer() override = default; + + void Initialize() override; + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } + +private: + AnalyzerPtr SNAPAnalyzer = nullptr; + AnalyzerPtr NovellRawAnalyzer = nullptr; + AnalyzerPtr LLCAnalyzer = nullptr; +}; + +} diff --git a/src/packet_analysis/protocol/ethernet/Plugin.cc b/src/packet_analysis/protocol/ethernet/Plugin.cc new file mode 100644 index 0000000000..409292b3ac --- /dev/null +++ b/src/packet_analysis/protocol/ethernet/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Ethernet.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_Ethernet { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("Ethernet", + zeek::packet_analysis::Ethernet::EthernetAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::Ethernet"; + config.description = "Ethernet packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/fddi/CMakeLists.txt b/src/packet_analysis/protocol/fddi/CMakeLists.txt new file mode 100644 index 0000000000..2e68aa92d9 --- /dev/null +++ b/src/packet_analysis/protocol/fddi/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer FDDI) +zeek_plugin_cc(FDDI.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/fddi/FDDI.cc b/src/packet_analysis/protocol/fddi/FDDI.cc new file mode 100644 index 0000000000..5466ab2dad --- /dev/null +++ b/src/packet_analysis/protocol/fddi/FDDI.cc @@ -0,0 +1,25 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "FDDI.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::FDDI; + +FDDIAnalyzer::FDDIAnalyzer() + : zeek::packet_analysis::Analyzer("FDDI") + { + } + +bool FDDIAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + size_t hdr_size = 13 + 8; // FDDI header + LLC + + if ( hdr_size >= len ) + { + packet->Weird("FDDI_analyzer_failed"); + return false; + } + + // We just skip the header and hope for default analysis + return ForwardPacket(len - hdr_size, data + hdr_size, packet); + } diff --git a/src/packet_analysis/protocol/fddi/FDDI.h b/src/packet_analysis/protocol/fddi/FDDI.h new file mode 100644 index 0000000000..080834ae71 --- /dev/null +++ b/src/packet_analysis/protocol/fddi/FDDI.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::FDDI { + +class FDDIAnalyzer : public zeek::packet_analysis::Analyzer { +public: + FDDIAnalyzer(); + ~FDDIAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/fddi/Plugin.cc b/src/packet_analysis/protocol/fddi/Plugin.cc new file mode 100644 index 0000000000..8154e7f915 --- /dev/null +++ b/src/packet_analysis/protocol/fddi/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "FDDI.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_FDDI { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("FDDI", + zeek::packet_analysis::FDDI::FDDIAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::FDDI"; + config.description = "FDDI packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/ieee802_11/CMakeLists.txt b/src/packet_analysis/protocol/ieee802_11/CMakeLists.txt new file mode 100644 index 0000000000..bd6c43c6ea --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer IEEE802_11) +zeek_plugin_cc(IEEE802_11.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ieee802_11/IEEE802_11.cc b/src/packet_analysis/protocol/ieee802_11/IEEE802_11.cc new file mode 100644 index 0000000000..c7e6b32982 --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11/IEEE802_11.cc @@ -0,0 +1,111 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IEEE802_11.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::IEEE802_11; + +IEEE802_11Analyzer::IEEE802_11Analyzer() + : zeek::packet_analysis::Analyzer("IEEE802_11") + { + } + +bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + u_char len_80211 = 24; // minimal length of data frames + + if ( len_80211 >= len ) + { + packet->Weird("truncated_802_11_header"); + return false; + } + + u_char fc_80211 = data[0]; // Frame Control field + + // Skip non-data frame types (management & control). + if ( ! ((fc_80211 >> 2) & 0x02) ) + return false; + + // Skip subtypes without data. + if ( (fc_80211 >> 4) & 0x04 ) + return false; + + // 'To DS' and 'From DS' flags set indicate use of the 4th + // address field. + if ( (data[1] & 0x03) == 0x03 ) + len_80211 += packet->L2_ADDR_LEN; + + // Look for the QoS indicator bit. + if ( (fc_80211 >> 4) & 0x08 ) + { + // Skip in case of A-MSDU subframes indicated by QoS + // control field. + if ( data[len_80211] & 0x80 ) + return false; + + len_80211 += 2; + } + + if ( len_80211 >= len ) + { + packet->Weird("truncated_802_11_header"); + return false; + } + + // Determine link-layer addresses based + // on 'To DS' and 'From DS' flags + switch ( data[1] & 0x03 ) + { + case 0x00: + packet->l2_src = data + 10; + packet->l2_dst = data + 4; + break; + + case 0x01: + packet->l2_src = data + 10; + packet->l2_dst = data + 16; + break; + + case 0x02: + packet->l2_src = data + 16; + packet->l2_dst = data + 4; + break; + + case 0x03: + packet->l2_src = data + 24; + packet->l2_dst = data + 16; + break; + } + + // skip 802.11 data header + data += len_80211; + + len_80211 += 8; + if ( len_80211 >= len ) + { + packet->Weird("truncated_802_11_header"); + return false; + } + + // Check that the DSAP and SSAP are both SNAP and that the control + // field indicates that this is an unnumbered frame. + // The organization code (24bits) needs to also be zero to + // indicate that this is encapsulated ethernet. + if ( data[0] == 0xAA && data[1] == 0xAA && data[2] == 0x03 && + data[3] == 0 && data[4] == 0 && data[5] == 0 ) + { + data += 6; + } + else + { + // If this is a logical link control frame without the + // possibility of having a protocol we care about, we'll + // just skip it for now. + return false; + } + + uint32_t protocol = (data[0] << 8) + data[1]; + data += 2; + + return ForwardPacket(len - len_80211, data, packet, protocol); + } diff --git a/src/packet_analysis/protocol/ieee802_11/IEEE802_11.h b/src/packet_analysis/protocol/ieee802_11/IEEE802_11.h new file mode 100644 index 0000000000..e919f9676c --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11/IEEE802_11.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::IEEE802_11 { + +class IEEE802_11Analyzer : public Analyzer { +public: + IEEE802_11Analyzer(); + ~IEEE802_11Analyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/ieee802_11/Plugin.cc b/src/packet_analysis/protocol/ieee802_11/Plugin.cc new file mode 100644 index 0000000000..11efda40c4 --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IEEE802_11.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_IEEE802_11 { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("IEEE802_11", + zeek::packet_analysis::IEEE802_11::IEEE802_11Analyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::IEEE802_11"; + config.description = "IEEE 802.11 packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/ieee802_11_radio/CMakeLists.txt b/src/packet_analysis/protocol/ieee802_11_radio/CMakeLists.txt new file mode 100644 index 0000000000..e063cbecca --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11_radio/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer IEEE802_11_Radio) +zeek_plugin_cc(IEEE802_11_Radio.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ieee802_11_radio/IEEE802_11_Radio.cc b/src/packet_analysis/protocol/ieee802_11_radio/IEEE802_11_Radio.cc new file mode 100644 index 0000000000..19fcc052a7 --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11_radio/IEEE802_11_Radio.cc @@ -0,0 +1,33 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include + +#include "IEEE802_11_Radio.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::IEEE802_11_Radio; + +IEEE802_11_RadioAnalyzer::IEEE802_11_RadioAnalyzer() + : zeek::packet_analysis::Analyzer("IEEE802_11_Radio") + { + } + +bool IEEE802_11_RadioAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + if ( 3 >= len ) + { + packet->Weird("truncated_radiotap_header"); + return false; + } + + // Skip over the RadioTap header + size_t rtheader_len = (data[3] << 8) + data[2]; + + if ( rtheader_len >= len ) + { + packet->Weird("truncated_radiotap_header"); + return false; + } + + return ForwardPacket(len - rtheader_len, data + rtheader_len, packet, DLT_IEEE802_11); + } diff --git a/src/packet_analysis/protocol/ieee802_11_radio/IEEE802_11_Radio.h b/src/packet_analysis/protocol/ieee802_11_radio/IEEE802_11_Radio.h new file mode 100644 index 0000000000..bbd06d2b0f --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11_radio/IEEE802_11_Radio.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::IEEE802_11_Radio { + +class IEEE802_11_RadioAnalyzer : public Analyzer { +public: + IEEE802_11_RadioAnalyzer(); + ~IEEE802_11_RadioAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/ieee802_11_radio/Plugin.cc b/src/packet_analysis/protocol/ieee802_11_radio/Plugin.cc new file mode 100644 index 0000000000..0b566f6d5f --- /dev/null +++ b/src/packet_analysis/protocol/ieee802_11_radio/Plugin.cc @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IEEE802_11_Radio.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_IEEE802_11_Radio { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("IEEE802_11_Radio", + zeek::packet_analysis::IEEE802_11_Radio::IEEE802_11_RadioAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::IEEE802_11_Radio"; + config.description = "IEEE 802.11 Radiotap packet analyzer"; + return config; + } + +} plugin; +} diff --git a/src/packet_analysis/protocol/ip/CMakeLists.txt b/src/packet_analysis/protocol/ip/CMakeLists.txt new file mode 100644 index 0000000000..3be79005d9 --- /dev/null +++ b/src/packet_analysis/protocol/ip/CMakeLists.txt @@ -0,0 +1,8 @@ + +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_end() diff --git a/src/packet_analysis/protocol/ip/IP.cc b/src/packet_analysis/protocol/ip/IP.cc new file mode 100644 index 0000000000..2153ee0ebb --- /dev/null +++ b/src/packet_analysis/protocol/ip/IP.cc @@ -0,0 +1,37 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IP.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::IP; + +IPAnalyzer::IPAnalyzer() + : zeek::packet_analysis::Analyzer("IP") + { + } + +bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + // Assume we're pointing at IP. Just figure out which version. + if ( sizeof(struct ip) >= len ) + { + packet->Weird("packet_analyzer_truncated_header"); + return false; + } + + auto ip = (const struct ip *)data; + uint32_t protocol = ip->ip_v; + + auto inner_analyzer = Lookup(protocol); + if ( inner_analyzer == nullptr ) + { + DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s failed, could not find analyzer for identifier %#x.", + GetAnalyzerName(), protocol); + packet->Weird("no_suitable_analyzer_found"); + return false; + } + + DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.", + GetAnalyzerName(), protocol); + return inner_analyzer->AnalyzePacket(len, data, packet); + } \ No newline at end of file diff --git a/src/packet_analysis/protocol/ip/IP.h b/src/packet_analysis/protocol/ip/IP.h new file mode 100644 index 0000000000..22f3b015b7 --- /dev/null +++ b/src/packet_analysis/protocol/ip/IP.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::IP { + +class IPAnalyzer : public Analyzer { +public: + IPAnalyzer(); + ~IPAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/ip/Plugin.cc b/src/packet_analysis/protocol/ip/Plugin.cc new file mode 100644 index 0000000000..c24a880c60 --- /dev/null +++ b/src/packet_analysis/protocol/ip/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IP.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_IP { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("IP", + zeek::packet_analysis::IP::IPAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::IP"; + config.description = "Packet analyzer for IP fallback (v4 or v6)"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/ipv4/CMakeLists.txt b/src/packet_analysis/protocol/ipv4/CMakeLists.txt new file mode 100644 index 0000000000..80c8d9c5c0 --- /dev/null +++ b/src/packet_analysis/protocol/ipv4/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer IPv4) +zeek_plugin_cc(IPv4.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ipv4/IPv4.cc b/src/packet_analysis/protocol/ipv4/IPv4.cc new file mode 100644 index 0000000000..1121ea437d --- /dev/null +++ b/src/packet_analysis/protocol/ipv4/IPv4.cc @@ -0,0 +1,20 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IPv4.h" + +using namespace zeek::packet_analysis::IPv4; + +IPv4Analyzer::IPv4Analyzer() + : zeek::packet_analysis::Analyzer("IPv4") + { + } + +bool IPv4Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + packet->l3_proto = L3_IPV4; + packet->hdr_size = static_cast(data - packet->data); + packet->session_analysis = true; + + // Leave packet analyzer land + return true; + } diff --git a/src/packet_analysis/protocol/ipv4/IPv4.h b/src/packet_analysis/protocol/ipv4/IPv4.h new file mode 100644 index 0000000000..4a4833abef --- /dev/null +++ b/src/packet_analysis/protocol/ipv4/IPv4.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::IPv4 { + +class IPv4Analyzer : public Analyzer { +public: + IPv4Analyzer(); + ~IPv4Analyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/ipv4/Plugin.cc b/src/packet_analysis/protocol/ipv4/Plugin.cc new file mode 100644 index 0000000000..ec865917da --- /dev/null +++ b/src/packet_analysis/protocol/ipv4/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IPv4.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_IPv4 { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("IPv4", + zeek::packet_analysis::IPv4::IPv4Analyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::IPv4"; + config.description = "IPv4 packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/ipv6/CMakeLists.txt b/src/packet_analysis/protocol/ipv6/CMakeLists.txt new file mode 100644 index 0000000000..f2614beedf --- /dev/null +++ b/src/packet_analysis/protocol/ipv6/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer IPv6) +zeek_plugin_cc(IPv6.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ipv6/IPv6.cc b/src/packet_analysis/protocol/ipv6/IPv6.cc new file mode 100644 index 0000000000..5da788d4b7 --- /dev/null +++ b/src/packet_analysis/protocol/ipv6/IPv6.cc @@ -0,0 +1,20 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "IPv6.h" + +using namespace zeek::packet_analysis::IPv6; + +IPv6Analyzer::IPv6Analyzer() + : zeek::packet_analysis::Analyzer("IPv6") + { + } + +bool IPv6Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + packet->l3_proto = L3_IPV6; + packet->hdr_size = static_cast(data - packet->data); + packet->session_analysis = true; + + // Leave packet analyzer land + return true; + } diff --git a/src/packet_analysis/protocol/ipv6/IPv6.h b/src/packet_analysis/protocol/ipv6/IPv6.h new file mode 100644 index 0000000000..a640b3beff --- /dev/null +++ b/src/packet_analysis/protocol/ipv6/IPv6.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::IPv6 { + +class IPv6Analyzer : public Analyzer { +public: + IPv6Analyzer(); + ~IPv6Analyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/ipv6/Plugin.cc b/src/packet_analysis/protocol/ipv6/Plugin.cc new file mode 100644 index 0000000000..474926e000 --- /dev/null +++ b/src/packet_analysis/protocol/ipv6/Plugin.cc @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "plugin/Plugin.h" +#include "IPv6.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_IPv6 { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("IPv6", + zeek::packet_analysis::IPv6::IPv6Analyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::IPv6"; + config.description = "IPv6 packet analyzer"; + return config; + } +} plugin; + +} diff --git a/src/packet_analysis/protocol/linux_sll/CMakeLists.txt b/src/packet_analysis/protocol/linux_sll/CMakeLists.txt new file mode 100644 index 0000000000..8e00b95609 --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer LinuxSLL) +zeek_plugin_cc(LinuxSLL.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/linux_sll/LinuxSLL.cc b/src/packet_analysis/protocol/linux_sll/LinuxSLL.cc new file mode 100644 index 0000000000..9f3dd25787 --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll/LinuxSLL.cc @@ -0,0 +1,33 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "LinuxSLL.h" + +using namespace zeek::packet_analysis::LinuxSLL; + +LinuxSLLAnalyzer::LinuxSLLAnalyzer() + : zeek::packet_analysis::Analyzer("LinuxSLL") + { + } + +bool LinuxSLLAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + auto len_sll_hdr = sizeof(SLLHeader); + if ( len_sll_hdr >= len ) + { + packet->Weird("truncated_Linux_SLL_header"); + return false; + } + + // Note: We assume to see an Ethertype and don't consider different ARPHRD_types + // (see https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html) + auto hdr = (const SLLHeader*)data; + + uint32_t protocol = ntohs(hdr->protocol_type); + packet->l2_src = (u_char*) &(hdr->addr); + + // SLL doesn't include a destination address in the header, but not setting l2_dst to something + // here will cause crashes elsewhere. + packet->l2_dst = Packet::L2_EMPTY_ADDR; + + return ForwardPacket(len - len_sll_hdr, data + len_sll_hdr, packet, protocol); + } diff --git a/src/packet_analysis/protocol/linux_sll/LinuxSLL.h b/src/packet_analysis/protocol/linux_sll/LinuxSLL.h new file mode 100644 index 0000000000..ec18d92eb1 --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll/LinuxSLL.h @@ -0,0 +1,35 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::LinuxSLL { + +class LinuxSLLAnalyzer : public Analyzer { +public: + LinuxSLLAnalyzer(); + ~LinuxSLLAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } + +private: + + // Structure layout is based on https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html + struct SLLHeader + { + uint16_t packet_type; + uint16_t arphrd_type; + uint16_t addr_len; + uint64_t addr; + uint16_t protocol_type; + } __attribute__((__packed__)); +}; + +} diff --git a/src/packet_analysis/protocol/linux_sll/Plugin.cc b/src/packet_analysis/protocol/linux_sll/Plugin.cc new file mode 100644 index 0000000000..a0cf4583be --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "plugin/Plugin.h" +#include "LinuxSLL.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_LinuxSLL { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("LinuxSLL", + zeek::packet_analysis::LinuxSLL::LinuxSLLAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::LinuxSLL"; + config.description = "Linux cooked capture (SLL) packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/mpls/CMakeLists.txt b/src/packet_analysis/protocol/mpls/CMakeLists.txt new file mode 100644 index 0000000000..a72da68f3f --- /dev/null +++ b/src/packet_analysis/protocol/mpls/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer MPLS) +zeek_plugin_cc(MPLS.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/mpls/MPLS.cc b/src/packet_analysis/protocol/mpls/MPLS.cc new file mode 100644 index 0000000000..4ec72ad4b6 --- /dev/null +++ b/src/packet_analysis/protocol/mpls/MPLS.cc @@ -0,0 +1,33 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "MPLS.h" + +using namespace zeek::packet_analysis::MPLS; + +MPLSAnalyzer::MPLSAnalyzer() + : zeek::packet_analysis::Analyzer("MPLS") + { + } + +bool MPLSAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + // Skip the MPLS label stack. + bool end_of_stack = false; + + while ( ! end_of_stack ) + { + if ( 4 >= len ) + { + packet->Weird("truncated_link_header"); + return false; + } + + end_of_stack = *(data + 2u) & 0x01; + data += 4; + len -= 4; + } + + // According to RFC3032 the encapsulated protocol is not encoded. + // We use the configured default analyzer. + return ForwardPacket(len, data, packet); + } diff --git a/src/packet_analysis/protocol/mpls/MPLS.h b/src/packet_analysis/protocol/mpls/MPLS.h new file mode 100644 index 0000000000..b536b934d0 --- /dev/null +++ b/src/packet_analysis/protocol/mpls/MPLS.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::MPLS { + +class MPLSAnalyzer : public zeek::packet_analysis::Analyzer { +public: + MPLSAnalyzer(); + ~MPLSAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/mpls/Plugin.cc b/src/packet_analysis/protocol/mpls/Plugin.cc new file mode 100644 index 0000000000..ef29566623 --- /dev/null +++ b/src/packet_analysis/protocol/mpls/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "MPLS.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_MPLS { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("MPLS", + zeek::packet_analysis::MPLS::MPLSAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::MPLS"; + config.description = "MPLS packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/nflog/CMakeLists.txt b/src/packet_analysis/protocol/nflog/CMakeLists.txt new file mode 100644 index 0000000000..ada26faa3c --- /dev/null +++ b/src/packet_analysis/protocol/nflog/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer NFLog) +zeek_plugin_cc(NFLog.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/nflog/NFLog.cc b/src/packet_analysis/protocol/nflog/NFLog.cc new file mode 100644 index 0000000000..55a09dc147 --- /dev/null +++ b/src/packet_analysis/protocol/nflog/NFLog.cc @@ -0,0 +1,87 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "NFLog.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::NFLog; + +NFLogAnalyzer::NFLogAnalyzer() + : zeek::packet_analysis::Analyzer("NFLog") + { + } + +bool NFLogAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + if ( 4 >= len ) + { + packet->Weird("truncated_nflog_header"); + return false; + } + + // See https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html + uint32_t protocol = data[0]; + uint8_t version = data[1]; + + if ( version != 0 ) + { + packet->Weird("unknown_nflog_version"); + return false; + } + + // Skip to TLVs. + data += 4; + len -= 4; + + uint16_t tlv_len; + uint16_t tlv_type; + + while ( true ) + { + if ( 4 >= len ) + { + packet->Weird("nflog_no_pcap_payload"); + return false; + } + + // TLV Type and Length values are specified in host byte order + // (libpcap should have done any needed byteswapping already). + + tlv_len = *(reinterpret_cast(data)); + tlv_type = *(reinterpret_cast(data + 2)); + + auto constexpr nflog_type_payload = 9; + + if ( tlv_type == nflog_type_payload ) + { + // The raw packet payload follows this TLV. + data += 4; + len -= 4; + break; + } + else + { + // The Length value includes the 4 octets for the Type and + // Length values, but TLVs are also implicitly padded to + // 32-bit alignments (that padding may not be included in + // the Length value). + + if ( tlv_len < 4 ) + { + packet->Weird("nflog_bad_tlv_len"); + return false; + } + else + { + auto rem = tlv_len % 4; + + if ( rem != 0 ) + tlv_len += 4 - rem; + } + + data += tlv_len; + len -= tlv_len; + } + } + + return ForwardPacket(len, data, packet, protocol); + } diff --git a/src/packet_analysis/protocol/nflog/NFLog.h b/src/packet_analysis/protocol/nflog/NFLog.h new file mode 100644 index 0000000000..9e7dfecfea --- /dev/null +++ b/src/packet_analysis/protocol/nflog/NFLog.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::NFLog { + +class NFLogAnalyzer : public Analyzer { +public: + NFLogAnalyzer(); + ~NFLogAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/nflog/Plugin.cc b/src/packet_analysis/protocol/nflog/Plugin.cc new file mode 100644 index 0000000000..94997fe96a --- /dev/null +++ b/src/packet_analysis/protocol/nflog/Plugin.cc @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "NFLog.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_NFLog { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("NFLog", + zeek::packet_analysis::NFLog::NFLogAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::NFLog"; + config.description = "NFLog packet analyzer"; + return config; + } +} plugin; + +} diff --git a/src/packet_analysis/protocol/null/CMakeLists.txt b/src/packet_analysis/protocol/null/CMakeLists.txt new file mode 100644 index 0000000000..960c1dd031 --- /dev/null +++ b/src/packet_analysis/protocol/null/CMakeLists.txt @@ -0,0 +1,7 @@ +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer Null) +zeek_plugin_cc(Null.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/null/Null.cc b/src/packet_analysis/protocol/null/Null.cc new file mode 100644 index 0000000000..92ecb29315 --- /dev/null +++ b/src/packet_analysis/protocol/null/Null.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Null.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::Null; + +NullAnalyzer::NullAnalyzer() + : zeek::packet_analysis::Analyzer("Null") + { + } + +bool NullAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + if ( 4 >= len ) + { + packet->Weird("null_analyzer_failed"); + return false; + } + + uint32_t protocol = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; + // skip link header + return ForwardPacket(len - 4, data + 4, packet, protocol); + } diff --git a/src/packet_analysis/protocol/null/Null.h b/src/packet_analysis/protocol/null/Null.h new file mode 100644 index 0000000000..4179130690 --- /dev/null +++ b/src/packet_analysis/protocol/null/Null.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::Null { + +class NullAnalyzer : public Analyzer { +public: + NullAnalyzer(); + ~NullAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/null/Plugin.cc b/src/packet_analysis/protocol/null/Plugin.cc new file mode 100644 index 0000000000..ab568641db --- /dev/null +++ b/src/packet_analysis/protocol/null/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "plugin/Plugin.h" +#include "Null.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_Null { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("Null", + zeek::packet_analysis::Null::NullAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::Null"; + config.description = "Null packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/ppp_serial/CMakeLists.txt b/src/packet_analysis/protocol/ppp_serial/CMakeLists.txt new file mode 100644 index 0000000000..25917e191b --- /dev/null +++ b/src/packet_analysis/protocol/ppp_serial/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer PPPSerial) +zeek_plugin_cc(PPPSerial.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ppp_serial/PPPSerial.cc b/src/packet_analysis/protocol/ppp_serial/PPPSerial.cc new file mode 100644 index 0000000000..8ddf60ac82 --- /dev/null +++ b/src/packet_analysis/protocol/ppp_serial/PPPSerial.cc @@ -0,0 +1,25 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "PPPSerial.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::PPPSerial; + +PPPSerialAnalyzer::PPPSerialAnalyzer() + : zeek::packet_analysis::Analyzer("PPPSerial") + { + } + +bool PPPSerialAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + if ( 4 >= len ) + { + packet->Weird("truncated_ppp_serial_header"); + return false; + } + + // Extract protocol identifier + uint32_t protocol = (data[2] << 8) + data[3]; + // skip link header + return ForwardPacket(len - 4, data + 4, packet, protocol); + } diff --git a/src/packet_analysis/protocol/ppp_serial/PPPSerial.h b/src/packet_analysis/protocol/ppp_serial/PPPSerial.h new file mode 100644 index 0000000000..9029e1d378 --- /dev/null +++ b/src/packet_analysis/protocol/ppp_serial/PPPSerial.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::PPPSerial { + +class PPPSerialAnalyzer : public Analyzer { +public: + PPPSerialAnalyzer(); + ~PPPSerialAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/ppp_serial/Plugin.cc b/src/packet_analysis/protocol/ppp_serial/Plugin.cc new file mode 100644 index 0000000000..e45923c311 --- /dev/null +++ b/src/packet_analysis/protocol/ppp_serial/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "PPPSerial.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_PPPSerial { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("PPPSerial", + zeek::packet_analysis::PPPSerial::PPPSerialAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::PPPSerial"; + config.description = "PPPSerial packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/pppoe/CMakeLists.txt b/src/packet_analysis/protocol/pppoe/CMakeLists.txt new file mode 100644 index 0000000000..460f43856c --- /dev/null +++ b/src/packet_analysis/protocol/pppoe/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer PPPoE) +zeek_plugin_cc(PPPoE.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/pppoe/PPPoE.cc b/src/packet_analysis/protocol/pppoe/PPPoE.cc new file mode 100644 index 0000000000..8a7454479d --- /dev/null +++ b/src/packet_analysis/protocol/pppoe/PPPoE.cc @@ -0,0 +1,25 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "PPPoE.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::PPPoE; + +PPPoEAnalyzer::PPPoEAnalyzer() + : zeek::packet_analysis::Analyzer("PPPoE") + { + } + +bool PPPoEAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + if ( 8 >= len ) + { + packet->Weird("truncated_pppoe_header"); + return false; + } + + // Extract protocol identifier + uint32_t protocol = (data[6] << 8u) + data[7]; + // Skip the PPPoE session and PPP header + return ForwardPacket(len - 8, data + 8, packet, protocol); + } diff --git a/src/packet_analysis/protocol/pppoe/PPPoE.h b/src/packet_analysis/protocol/pppoe/PPPoE.h new file mode 100644 index 0000000000..cb21a80760 --- /dev/null +++ b/src/packet_analysis/protocol/pppoe/PPPoE.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::PPPoE { + +class PPPoEAnalyzer : public Analyzer { +public: + PPPoEAnalyzer(); + ~PPPoEAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/pppoe/Plugin.cc b/src/packet_analysis/protocol/pppoe/Plugin.cc new file mode 100644 index 0000000000..b70e7e5af1 --- /dev/null +++ b/src/packet_analysis/protocol/pppoe/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "PPPoE.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_PPPoE { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("PPPoE", + zeek::packet_analysis::PPPoE::PPPoEAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::PPPoE"; + config.description = "PPPoE packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/root/CMakeLists.txt b/src/packet_analysis/protocol/root/CMakeLists.txt new file mode 100644 index 0000000000..3ea75189f3 --- /dev/null +++ b/src/packet_analysis/protocol/root/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer Root) +zeek_plugin_cc(Root.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/root/Plugin.cc b/src/packet_analysis/protocol/root/Plugin.cc new file mode 100644 index 0000000000..1d3432b627 --- /dev/null +++ b/src/packet_analysis/protocol/root/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Root.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_Root { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("Root", + zeek::packet_analysis::Root::RootAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::Root"; + config.description = "Root packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/root/Root.cc b/src/packet_analysis/protocol/root/Root.cc new file mode 100644 index 0000000000..21ad3eec7e --- /dev/null +++ b/src/packet_analysis/protocol/root/Root.cc @@ -0,0 +1,16 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Root.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::Root; + +RootAnalyzer::RootAnalyzer() + : zeek::packet_analysis::Analyzer("Root") + { + } + +bool RootAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + reporter->InternalError("AnalyzePacket() was called for the root analyzer."); + } diff --git a/src/packet_analysis/protocol/root/Root.h b/src/packet_analysis/protocol/root/Root.h new file mode 100644 index 0000000000..fc1543bbb8 --- /dev/null +++ b/src/packet_analysis/protocol/root/Root.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::Root { + +class RootAnalyzer : public Analyzer { +public: + RootAnalyzer(); + ~RootAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/skip/CMakeLists.txt b/src/packet_analysis/protocol/skip/CMakeLists.txt new file mode 100644 index 0000000000..982cf42edd --- /dev/null +++ b/src/packet_analysis/protocol/skip/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer Skip) +zeek_plugin_cc(Skip.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/skip/Plugin.cc b/src/packet_analysis/protocol/skip/Plugin.cc new file mode 100644 index 0000000000..ed3d70a564 --- /dev/null +++ b/src/packet_analysis/protocol/skip/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Skip.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_Skip { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("Skip", + zeek::packet_analysis::Skip::SkipAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::Skip"; + config.description = "Skip packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/skip/Skip.cc b/src/packet_analysis/protocol/skip/Skip.cc new file mode 100644 index 0000000000..bb2a71330a --- /dev/null +++ b/src/packet_analysis/protocol/skip/Skip.cc @@ -0,0 +1,27 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Skip.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::Skip; + +SkipAnalyzer::SkipAnalyzer() + : zeek::packet_analysis::Analyzer("Skip") + { + } + +void SkipAnalyzer::Initialize() + { + Analyzer::Initialize(); + + auto& skip_val = zeek::id::find_val("PacketAnalyzer::SKIP::skip_bytes"); + if ( ! skip_val ) + return; + + skip_bytes = skip_val->AsCount(); + } + +bool SkipAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + return ForwardPacket(len - skip_bytes, data + skip_bytes, packet); + } diff --git a/src/packet_analysis/protocol/skip/Skip.h b/src/packet_analysis/protocol/skip/Skip.h new file mode 100644 index 0000000000..544d2ac43a --- /dev/null +++ b/src/packet_analysis/protocol/skip/Skip.h @@ -0,0 +1,27 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::Skip { + +class SkipAnalyzer : public Analyzer { +public: + SkipAnalyzer(); + ~SkipAnalyzer() override = default; + + void Initialize() override; + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } + +private: + bro_uint_t skip_bytes = 0; +}; + +} diff --git a/src/packet_analysis/protocol/vlan/CMakeLists.txt b/src/packet_analysis/protocol/vlan/CMakeLists.txt new file mode 100644 index 0000000000..8f1c86ae55 --- /dev/null +++ b/src/packet_analysis/protocol/vlan/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer VLAN) +zeek_plugin_cc(VLAN.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/vlan/Plugin.cc b/src/packet_analysis/protocol/vlan/Plugin.cc new file mode 100644 index 0000000000..7a6222c9b3 --- /dev/null +++ b/src/packet_analysis/protocol/vlan/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "VLAN.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_VLAN { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("VLAN", + zeek::packet_analysis::VLAN::VLANAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::VLAN"; + config.description = "VLAN packet analyzer"; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/vlan/VLAN.cc b/src/packet_analysis/protocol/vlan/VLAN.cc new file mode 100644 index 0000000000..5dc3fe1874 --- /dev/null +++ b/src/packet_analysis/protocol/vlan/VLAN.cc @@ -0,0 +1,28 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "VLAN.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::VLAN; + +VLANAnalyzer::VLANAnalyzer() + : zeek::packet_analysis::Analyzer("VLAN") + { + } + +bool VLANAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + if ( 4 >= len ) + { + packet->Weird("truncated_VLAN_header"); + return false; + } + + auto& vlan_ref = packet->vlan != 0 ? packet->inner_vlan : packet->vlan; + vlan_ref = ((data[0] << 8u) + data[1]) & 0xfff; + + uint32_t protocol = ((data[2] << 8u) + data[3]); + packet->eth_type = protocol; + // Skip the VLAN header + return ForwardPacket(len - 4, data + 4, packet, protocol); + } diff --git a/src/packet_analysis/protocol/vlan/VLAN.h b/src/packet_analysis/protocol/vlan/VLAN.h new file mode 100644 index 0000000000..bde045b552 --- /dev/null +++ b/src/packet_analysis/protocol/vlan/VLAN.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::VLAN { + +class VLANAnalyzer : public Analyzer { +public: + VLANAnalyzer(); + ~VLANAnalyzer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/packet_analysis/protocol/wrapper/CMakeLists.txt b/src/packet_analysis/protocol/wrapper/CMakeLists.txt new file mode 100644 index 0000000000..76b59fc30a --- /dev/null +++ b/src/packet_analysis/protocol/wrapper/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer Wrapper) +zeek_plugin_cc(Wrapper.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/wrapper/Plugin.cc b/src/packet_analysis/protocol/wrapper/Plugin.cc new file mode 100644 index 0000000000..c6e9fd5334 --- /dev/null +++ b/src/packet_analysis/protocol/wrapper/Plugin.cc @@ -0,0 +1,24 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Wrapper.h" +#include "plugin/Plugin.h" +#include "packet_analysis/Component.h" + +namespace zeek::plugin::Zeek_Wrapper { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("Wrapper", + zeek::packet_analysis::Wrapper::WrapperAnalyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::Wrapper"; + config.description = "A wrapper for the original zeek code."; + return config; + } + +} plugin; + +} diff --git a/src/packet_analysis/protocol/wrapper/Wrapper.cc b/src/packet_analysis/protocol/wrapper/Wrapper.cc new file mode 100644 index 0000000000..5d431af2c6 --- /dev/null +++ b/src/packet_analysis/protocol/wrapper/Wrapper.cc @@ -0,0 +1,162 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "Wrapper.h" +#include "NetVar.h" + +using namespace zeek::packet_analysis::Wrapper; + +WrapperAnalyzer::WrapperAnalyzer() + : zeek::packet_analysis::Analyzer("Wrapper") + { + } + +bool WrapperAnalyzer::Analyze(Packet* packet, const uint8_t*& data) + { + // Unfortunately some packets on the link might have MPLS labels + // while others don't. That means we need to ask the link-layer if + // labels are in place. + bool have_mpls = false; + + auto end_of_data = packet->GetEndOfData(); + + // Skip past Cisco FabricPath to encapsulated ethernet frame. + if ( data[12] == 0x89 && data[13] == 0x03 ) + { + auto constexpr cfplen = 16; + + if ( data + cfplen + 14 >= end_of_data ) + { + packet->Weird("truncated_link_header_cfp"); + return false; + } + + data += cfplen; + } + + // Extract protocol identifier + uint32_t protocol = (data[12] << 8u) + data[13]; + + packet->eth_type = protocol; + packet->l2_dst = data; + packet->l2_src = data + 6; + + data += 14; + + bool saw_vlan = false; + + while ( protocol == 0x8100 || protocol == 0x9100 || + protocol == 0x8864 ) + { + switch ( protocol ) + { + // VLAN carried over the ethernet frame. + // 802.1q / 802.1ad + case 0x8100: + case 0x9100: + { + if ( data + 4 >= end_of_data ) + { + packet->Weird("truncated_link_header"); + return false; + } + + auto& vlan_ref = saw_vlan ? packet->inner_vlan : packet->vlan; + vlan_ref = ((data[0] << 8u) + data[1]) & 0xfff; + protocol = ((data[2] << 8u) + data[3]); + data += 4; // Skip the vlan header + saw_vlan = true; + packet->eth_type = protocol; + } + break; + + // PPPoE carried over the ethernet frame. + case 0x8864: + { + if ( data + 8 >= end_of_data ) + { + packet->Weird("truncated_link_header"); + return false; + } + + protocol = (data[6] << 8u) + data[7]; + data += 8; // Skip the PPPoE session and PPP header + + if ( protocol == 0x0021 ) + packet->l3_proto = L3_IPV4; + else if ( protocol == 0x0057 ) + packet->l3_proto = L3_IPV6; + else + { + // Neither IPv4 nor IPv6. + packet->Weird("non_ip_packet_in_pppoe_encapsulation"); + return false; + } + } + break; + } + } + + // Check for MPLS in VLAN. + if ( protocol == 0x8847 ) + have_mpls = true; + + // Normal path to determine Layer 3 protocol. + if ( ! have_mpls && packet->l3_proto == L3_UNKNOWN ) + { + if ( protocol == 0x800 ) + packet->l3_proto = L3_IPV4; + else if ( protocol == 0x86dd ) + packet->l3_proto = L3_IPV6; + else if ( protocol == 0x0806 || protocol == 0x8035 ) + packet->l3_proto = L3_ARP; + else + { + // Neither IPv4 nor IPv6. + packet->Weird("non_ip_packet_in_ethernet"); + return false; + } + } + + if ( have_mpls ) + { + // Skip the MPLS label stack. + bool end_of_stack = false; + + while ( ! end_of_stack ) + { + if ( data + 4 >= end_of_data ) + { + packet->Weird("truncated_link_header"); + return false; + } + + end_of_stack = *(data + 2u) & 0x01; + data += 4; + } + + // We assume that what remains is IP + if ( data + sizeof(struct ip) >= end_of_data ) + { + packet->Weird("no_ip_in_mpls_payload"); + return false; + } + + const struct ip* ip = (const struct ip*)data; + + if ( ip->ip_v == 4 ) + packet->l3_proto = L3_IPV4; + else if ( ip->ip_v == 6 ) + packet->l3_proto = L3_IPV6; + else + { + // Neither IPv4 nor IPv6. + packet->Weird("no_ip_in_mpls_payload"); + return false; + } + } + + // Calculate how much header we've used up. + packet->hdr_size = (data - packet->data); + + return AnalyzeInnerPacket(packet, data, protocol); + } diff --git a/src/packet_analysis/protocol/wrapper/Wrapper.h b/src/packet_analysis/protocol/wrapper/Wrapper.h new file mode 100644 index 0000000000..28bc073832 --- /dev/null +++ b/src/packet_analysis/protocol/wrapper/Wrapper.h @@ -0,0 +1,23 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include + +namespace zeek::packet_analysis::Wrapper { + +class WrapperAnalyzer : public Analyzer { +public: + WrapperAnalyzer(); + ~WrapperAnalyzer() override = default; + + bool Analyze(Packet* packet, const uint8_t*& data) override; + + static zeek::packet_analysis::AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/src/plugin/Component.cc b/src/plugin/Component.cc index df9b048f76..a0bc21cfb8 100644 --- a/src/plugin/Component.cc +++ b/src/plugin/Component.cc @@ -46,6 +46,10 @@ void Component::Describe(ODesc* d) const d->Add("Analyzer"); break; + case component::PACKET_ANALYZER: + d->Add("Packet Analyzer"); + break; + case component::FILE_ANALYZER: d->Add("File Analyzer"); break; diff --git a/src/plugin/Component.h b/src/plugin/Component.h index 72237adac7..52068f68ce 100644 --- a/src/plugin/Component.h +++ b/src/plugin/Component.h @@ -15,13 +15,14 @@ namespace component { * Component types. */ enum Type { - READER, /// An input reader (not currently used). - WRITER, /// A logging writer (not currenly used). - ANALYZER, /// A protocol analyzer. - FILE_ANALYZER, /// A file analyzer. - IOSOURCE, /// An I/O source, excluding packet sources. - PKTSRC, /// A packet source. - PKTDUMPER /// A packet dumper. + READER, /// An input reader (not currently used). + WRITER, /// A logging writer (not currently used). + ANALYZER, /// A protocol analyzer. + PACKET_ANALYZER, /// A packet analyzer. + FILE_ANALYZER, /// A file analyzer. + IOSOURCE, /// An I/O source, excluding packet sources. + PKTSRC, /// A packet source. + PKTDUMPER /// A packet dumper. }; } // namespace component diff --git a/src/plugin/TaggedComponent.h b/src/plugin/TaggedComponent.h index d1a37a5794..3852ffeea6 100644 --- a/src/plugin/TaggedComponent.h +++ b/src/plugin/TaggedComponent.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace zeek::plugin { diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index aa9cb09643..c748e02d84 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -55,6 +55,7 @@ extern "C" { #include "input/readers/raw/Raw.h" #include "analyzer/Manager.h" #include "analyzer/Tag.h" +#include "packet_analysis/Manager.h" #include "plugin/Manager.h" #include "file_analysis/Manager.h" #include "zeekygen/Manager.h" @@ -92,6 +93,7 @@ zeek::ValManager* zeek::val_mgr = nullptr; zeek::ValManager*& val_mgr = zeek::val_mgr; zeek::analyzer::Manager* zeek::analyzer_mgr = nullptr; zeek::analyzer::Manager*& analyzer_mgr = zeek::analyzer_mgr; +zeek::packet_analysis::Manager* packet_mgr = nullptr; zeek::plugin::Manager* zeek::plugin_mgr = nullptr; zeek::plugin::Manager*& plugin_mgr = zeek::plugin_mgr; @@ -265,6 +267,7 @@ static void done_with_network() run_state::terminating = true; analyzer_mgr->Done(); + packet_mgr->Done(); timer_mgr->Expire(); dns_mgr->Flush(); event_mgr.Drain(); @@ -335,6 +338,7 @@ static void terminate_bro() delete zeekygen_mgr; delete analyzer_mgr; + delete packet_mgr; delete file_mgr; // broker_mgr, timer_mgr, and supervisor are deleted via iosource_mgr delete iosource_mgr; @@ -581,6 +585,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) iosource_mgr = new iosource::Manager(); event_registry = new EventRegistry(); analyzer_mgr = new analyzer::Manager(); + packet_mgr = new packet_analysis::Manager(); log_mgr = new logging::Manager(); input_mgr = new input::Manager(); file_mgr = new file_analysis::Manager(); @@ -689,6 +694,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) } analyzer_mgr->InitPostScript(); + packet_mgr->InitPostScript(); file_mgr->InitPostScript(); dns_mgr->InitPostScript(); @@ -889,6 +895,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) broker_mgr->ZeekInitDone(); reporter->ZeekInitDone(); analyzer_mgr->DumpDebug(); + packet_mgr->DumpDebug(); run_state::detail::have_pending_timers = ! run_state::reading_traces && timer_mgr->Size() > 0; diff --git a/testing/btest/Baseline/core.raw_packet/output b/testing/btest/Baseline/core.raw_packet/output index b9e82f8b70..c642d3cd0b 100644 --- a/testing/btest/Baseline/core.raw_packet/output +++ b/testing/btest/Baseline/core.raw_packet/output @@ -1,15 +1,18 @@ [l2=[encap=LINK_ETHERNET, len=215, cap_len=215, src=e8:de:27:ff:c0:78, dst=ff:ff:ff:ff:ff:ff, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=201, id=0, ttl=64, p=17, src=192.168.1.1, dst=255.255.255.255], ip6=, tcp=, udp=[sport=40190/udp, dport=7437/udp, ulen=181], icmp=] [l2=[encap=LINK_ETHERNET, len=68, cap_len=68, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=54, id=52261, ttl=64, p=6, src=192.168.1.103, dst=64.4.23.176], ip6=, tcp=[sport=65493/tcp, dport=40031/tcp, seq=2642773190, ack=2891276360, hl=32, dl=2, reserved=0, flags=24, win=4096], udp=, icmp=] +[l2=[encap=LINK_ETHERNET, len=60, cap_len=60, src=e8:de:27:ff:c0:77, dst=01:80:c2:00:00:00, vlan=, inner_vlan=, eth_type=38, proto=L3_UNKNOWN], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=78, cap_len=78, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=64, id=32575, ttl=64, p=17, src=192.168.1.103, dst=192.168.1.1], ip6=, tcp=, udp=[sport=65170/udp, dport=53/udp, ulen=44], icmp=] [l2=[encap=LINK_ETHERNET, len=78, cap_len=78, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=64, id=55466, ttl=64, p=17, src=192.168.1.103, dst=192.168.1.1], ip6=, tcp=, udp=[sport=53129/udp, dport=53/udp, ulen=44], icmp=] [l2=[encap=LINK_ETHERNET, len=92, cap_len=92, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=78, id=32240, ttl=64, p=17, src=192.168.1.103, dst=192.168.1.1], ip6=, tcp=, udp=[sport=53129/udp, dport=53/udp, ulen=58], icmp=] [l2=[encap=LINK_ETHERNET, len=85, cap_len=85, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=71, id=53895, ttl=64, p=17, src=192.168.1.103, dst=192.168.1.1], ip6=, tcp=, udp=[sport=57932/udp, dport=53/udp, ulen=51], icmp=] +[l2=[encap=LINK_ETHERNET, len=60, cap_len=60, src=e8:de:27:ff:c0:77, dst=01:80:c2:00:00:00, vlan=, inner_vlan=, eth_type=38, proto=L3_UNKNOWN], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=42, cap_len=42, src=00:50:56:3e:93:6b, dst=ff:ff:ff:ff:ff:ff, vlan=, inner_vlan=, eth_type=2054, proto=L3_ARP], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=42, cap_len=42, src=00:50:56:3e:93:6b, dst=ff:ff:ff:ff:ff:ff, vlan=, inner_vlan=, eth_type=2054, proto=L3_ARP], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=307, cap_len=307, src=e8:de:27:ff:c0:78, dst=01:00:5e:7f:ff:fa, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=293, id=0, ttl=4, p=17, src=192.168.1.1, dst=239.255.255.250], ip6=, tcp=, udp=[sport=45335/udp, dport=1900/udp, ulen=273], icmp=] [l2=[encap=LINK_ETHERNET, len=316, cap_len=316, src=e8:de:27:ff:c0:78, dst=01:00:5e:7f:ff:fa, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=302, id=0, ttl=4, p=17, src=192.168.1.1, dst=239.255.255.250], ip6=, tcp=, udp=[sport=45335/udp, dport=1900/udp, ulen=282], icmp=] [l2=[encap=LINK_ETHERNET, len=379, cap_len=379, src=e8:de:27:ff:c0:78, dst=01:00:5e:7f:ff:fa, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=365, id=0, ttl=4, p=17, src=192.168.1.1, dst=239.255.255.250], ip6=, tcp=, udp=[sport=45335/udp, dport=1900/udp, ulen=345], icmp=] [l2=[encap=LINK_ETHERNET, len=371, cap_len=371, src=e8:de:27:ff:c0:78, dst=01:00:5e:7f:ff:fa, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=357, id=0, ttl=4, p=17, src=192.168.1.1, dst=239.255.255.250], ip6=, tcp=, udp=[sport=45335/udp, dport=1900/udp, ulen=337], icmp=] +[l2=[encap=LINK_ETHERNET, len=60, cap_len=60, src=e8:de:27:ff:c0:77, dst=01:80:c2:00:00:00, vlan=, inner_vlan=, eth_type=38, proto=L3_UNKNOWN], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=355, cap_len=355, src=e8:de:27:ff:c0:78, dst=01:00:5e:7f:ff:fa, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=341, id=0, ttl=4, p=17, src=192.168.1.1, dst=239.255.255.250], ip6=, tcp=, udp=[sport=45335/udp, dport=1900/udp, ulen=321], icmp=] [l2=[encap=LINK_ETHERNET, len=42, cap_len=42, src=00:50:56:3e:93:6b, dst=ff:ff:ff:ff:ff:ff, vlan=, inner_vlan=, eth_type=2054, proto=L3_ARP], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=387, cap_len=387, src=e8:de:27:ff:c0:78, dst=01:00:5e:7f:ff:fa, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=373, id=0, ttl=4, p=17, src=192.168.1.1, dst=239.255.255.250], ip6=, tcp=, udp=[sport=45335/udp, dport=1900/udp, ulen=353], icmp=] @@ -27,6 +30,7 @@ [l2=[encap=LINK_ETHERNET, len=112, cap_len=112, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=98, id=85, ttl=64, p=6, src=192.168.1.103, dst=74.125.21.138], ip6=, tcp=[sport=49171/tcp, dport=443/tcp, seq=3725176077, ack=445274652, hl=32, dl=46, reserved=0, flags=24, win=4096], udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=97, cap_len=97, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=83, id=28558, ttl=64, p=6, src=192.168.1.103, dst=74.125.21.138], ip6=, tcp=[sport=49171/tcp, dport=443/tcp, seq=3725176123, ack=445274652, hl=32, dl=31, reserved=0, flags=24, win=4096], udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=66, cap_len=66, src=60:f8:1d:c9:8c:fa, dst=e8:de:27:ff:c0:78, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=52, id=36529, ttl=64, p=6, src=192.168.1.103, dst=74.125.21.138], ip6=, tcp=[sport=49171/tcp, dport=443/tcp, seq=3725176154, ack=445274652, hl=32, dl=0, reserved=0, flags=17, win=4096], udp=, icmp=] +[l2=[encap=LINK_ETHERNET, len=60, cap_len=60, src=e8:de:27:ff:c0:77, dst=01:80:c2:00:00:00, vlan=, inner_vlan=, eth_type=38, proto=L3_UNKNOWN], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=64, cap_len=64, src=00:19:06:ea:b8:c1, dst=ff:ff:ff:ff:ff:ff, vlan=123, inner_vlan=, eth_type=2054, proto=L3_ARP], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=64, cap_len=64, src=00:18:73:de:57:c1, dst=ff:ff:ff:ff:ff:ff, vlan=123, inner_vlan=, eth_type=2054, proto=L3_ARP], ip=, ip6=, tcp=, udp=, icmp=] [l2=[encap=LINK_ETHERNET, len=64, cap_len=64, src=00:18:73:de:57:c1, dst=ff:ff:ff:ff:ff:ff, vlan=123, inner_vlan=, eth_type=2054, proto=L3_ARP], ip=, ip6=, tcp=, udp=, icmp=] diff --git a/testing/btest/Baseline/core.skip_analyzer/conn.log b/testing/btest/Baseline/core.skip_analyzer/conn.log new file mode 100644 index 0000000000..7de75363cf --- /dev/null +++ b/testing/btest/Baseline/core.skip_analyzer/conn.log @@ -0,0 +1,16 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2020-08-26-12-05-07 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1055289978.756932 C4J4Th3PJpwUYZZ6gc 66.59.111.190 40264 172.28.2.3 22 tcp - 3.157831 952 1671 SF - - 0 ShAdDaFf 12 1584 10 2199 - +1055289973.849878 ClEkJM2Vm5giqnMf4h 66.59.111.190 123 18.26.4.105 123 udp - 0.074086 48 48 SF - - 0 Dd 1 76 1 76 - +1055289992.849231 CmES5u32sYpV7JYN 66.59.111.190 123 66.59.111.182 123 udp - 0.056629 48 48 SF - - 0 Dd 1 76 1 76 - +1055289996.849099 CP5puj4I8PtEU4qzYg 66.59.111.190 123 129.170.17.4 123 udp - 0.072374 48 48 SF - - 0 Dd 1 76 1 76 - +1055289987.055189 CtPZjS20MLrsMUOJi2 66.59.111.190 37675 172.28.2.3 53 udp - 5.001141 66 0 S0 - - 0 D 2 122 0 0 - +1055289968.793044 CHhAvVGS1DHFjwGM9 66.59.111.190 8 172.28.2.3 0 icmp - 3.061298 224 224 OTH - - 0 - 4 336 4 336 - +1055289987.106744 CUM0KZ3MLUfNB0cl11 172.28.2.3 3 66.59.111.190 3 icmp - 4.994662 122 0 OTH - - 0 - 2 178 0 0 - +#close 2020-08-26-12-05-07 diff --git a/testing/btest/Baseline/core.truncation/output b/testing/btest/Baseline/core.truncation/output index 8ef1ff8e9d..9625b3a1bb 100644 --- a/testing/btest/Baseline/core.truncation/output +++ b/testing/btest/Baseline/core.truncation/output @@ -3,78 +3,78 @@ #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-03 +#open 2020-07-14-01-19-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1334160095.895421 - - - - - truncated_IP - F zeek -#close 2019-06-07-02-20-03 +#close 2020-07-14-01-19-19 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-03 +#open 2020-07-14-01-19-20 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1334156241.519125 - - - - - truncated_IP - F zeek -#close 2019-06-07-02-20-03 +#close 2020-07-14-01-19-20 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-04 +#open 2020-07-14-01-19-21 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1334094648.590126 - - - - - truncated_IP - F zeek -#close 2019-06-07-02-20-04 +#close 2020-07-14-01-19-21 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-05 +#open 2020-07-14-01-19-23 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1338328954.078361 - - - - - internally_truncated_header - F zeek -#close 2019-06-07-02-20-05 +#close 2020-07-14-01-19-23 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-05 +#open 2020-07-14-01-19-24 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string -0.000000 - - - - - truncated_link_header - F zeek -#close 2019-06-07-02-20-05 +0.000000 - - - - - truncated_ethernet_frame - F zeek +#close 2020-07-14-01-19-24 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-06 +#open 2020-07-14-01-19-25 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1508360735.834163 - 163.253.48.183 0 192.150.187.43 0 invalid_IP_header_size - F zeek -#close 2019-06-07-02-20-06 +#close 2020-07-14-01-19-25 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-06 +#open 2020-07-14-01-19-26 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1508360735.834163 - 163.253.48.183 0 192.150.187.43 0 internally_truncated_header - F zeek -#close 2019-06-07-02-20-06 +#close 2020-07-14-01-19-26 #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path weird -#open 2019-06-07-02-20-07 +#open 2020-07-14-01-19-27 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1500557630.000000 - 0.255.0.255 0 15.254.2.1 0 invalid_IP_header_size_in_tunnel - F zeek -#close 2019-06-07-02-20-07 +#close 2020-07-14-01-19-27 diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index 382bb30cb2..8af64df840 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2019-10-15-01-48-24 +#open 2020-09-08-08-14-03 #fields name #types string scripts/base/init-bare.zeek @@ -19,6 +19,35 @@ scripts/base/init-bare.zeek build/scripts/base/bif/plugins/Zeek_SNMP.types.bif.zeek build/scripts/base/bif/plugins/Zeek_KRB.types.bif.zeek build/scripts/base/bif/event.bif.zeek + scripts/base/packet-protocols/__load__.zeek + scripts/base/packet-protocols/root/__load__.zeek + scripts/base/packet-protocols/root/main.zeek + scripts/base/packet-protocols/ip/__load__.zeek + scripts/base/packet-protocols/ip/main.zeek + scripts/base/packet-protocols/skip/__load__.zeek + scripts/base/packet-protocols/skip/main.zeek + scripts/base/packet-protocols/ethernet/__load__.zeek + scripts/base/packet-protocols/ethernet/main.zeek + scripts/base/packet-protocols/fddi/__load__.zeek + scripts/base/packet-protocols/fddi/main.zeek + scripts/base/packet-protocols/ieee802_11/__load__.zeek + scripts/base/packet-protocols/ieee802_11/main.zeek + scripts/base/packet-protocols/ieee802_11_radio/__load__.zeek + scripts/base/packet-protocols/ieee802_11_radio/main.zeek + scripts/base/packet-protocols/linux_sll/__load__.zeek + scripts/base/packet-protocols/linux_sll/main.zeek + scripts/base/packet-protocols/nflog/__load__.zeek + scripts/base/packet-protocols/nflog/main.zeek + scripts/base/packet-protocols/null/__load__.zeek + scripts/base/packet-protocols/null/main.zeek + scripts/base/packet-protocols/ppp_serial/__load__.zeek + scripts/base/packet-protocols/ppp_serial/main.zeek + scripts/base/packet-protocols/pppoe/__load__.zeek + scripts/base/packet-protocols/pppoe/main.zeek + scripts/base/packet-protocols/vlan/__load__.zeek + scripts/base/packet-protocols/vlan/main.zeek + scripts/base/packet-protocols/mpls/__load__.zeek + scripts/base/packet-protocols/mpls/main.zeek scripts/base/init-frameworks-and-bifs.zeek scripts/base/frameworks/logging/__load__.zeek scripts/base/frameworks/logging/main.zeek @@ -66,7 +95,6 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/cardinality-counter.bif.zeek build/scripts/base/bif/top-k.bif.zeek build/scripts/base/bif/plugins/__load__.zeek - build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_BitTorrent.events.bif.zeek build/scripts/base/bif/plugins/Zeek_ConnSize.events.bif.zeek build/scripts/base/bif/plugins/Zeek_ConnSize.functions.bif.zeek @@ -165,6 +193,7 @@ scripts/base/init-frameworks-and-bifs.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_XMPP.events.bif.zeek + build/scripts/base/bif/plugins/Zeek_ARP.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.functions.bif.zeek @@ -187,4 +216,4 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_SQLiteWriter.sqlite.bif.zeek scripts/policy/misc/loaded-scripts.zeek scripts/base/utils/paths.zeek -#close 2019-10-15-01-48-24 +#close 2020-09-08-08-14-03 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 0f83430933..c38a701e86 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2020-09-11-03-21-10 +#open 2020-09-22-17-14-48 #fields name #types string scripts/base/init-bare.zeek @@ -19,6 +19,35 @@ scripts/base/init-bare.zeek build/scripts/base/bif/plugins/Zeek_SNMP.types.bif.zeek build/scripts/base/bif/plugins/Zeek_KRB.types.bif.zeek build/scripts/base/bif/event.bif.zeek + scripts/base/packet-protocols/__load__.zeek + scripts/base/packet-protocols/root/__load__.zeek + scripts/base/packet-protocols/root/main.zeek + scripts/base/packet-protocols/ip/__load__.zeek + scripts/base/packet-protocols/ip/main.zeek + scripts/base/packet-protocols/skip/__load__.zeek + scripts/base/packet-protocols/skip/main.zeek + scripts/base/packet-protocols/ethernet/__load__.zeek + scripts/base/packet-protocols/ethernet/main.zeek + scripts/base/packet-protocols/fddi/__load__.zeek + scripts/base/packet-protocols/fddi/main.zeek + scripts/base/packet-protocols/ieee802_11/__load__.zeek + scripts/base/packet-protocols/ieee802_11/main.zeek + scripts/base/packet-protocols/ieee802_11_radio/__load__.zeek + scripts/base/packet-protocols/ieee802_11_radio/main.zeek + scripts/base/packet-protocols/linux_sll/__load__.zeek + scripts/base/packet-protocols/linux_sll/main.zeek + scripts/base/packet-protocols/nflog/__load__.zeek + scripts/base/packet-protocols/nflog/main.zeek + scripts/base/packet-protocols/null/__load__.zeek + scripts/base/packet-protocols/null/main.zeek + scripts/base/packet-protocols/ppp_serial/__load__.zeek + scripts/base/packet-protocols/ppp_serial/main.zeek + scripts/base/packet-protocols/pppoe/__load__.zeek + scripts/base/packet-protocols/pppoe/main.zeek + scripts/base/packet-protocols/vlan/__load__.zeek + scripts/base/packet-protocols/vlan/main.zeek + scripts/base/packet-protocols/mpls/__load__.zeek + scripts/base/packet-protocols/mpls/main.zeek scripts/base/init-frameworks-and-bifs.zeek scripts/base/frameworks/logging/__load__.zeek scripts/base/frameworks/logging/main.zeek @@ -66,7 +95,6 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/cardinality-counter.bif.zeek build/scripts/base/bif/top-k.bif.zeek build/scripts/base/bif/plugins/__load__.zeek - build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_BitTorrent.events.bif.zeek build/scripts/base/bif/plugins/Zeek_ConnSize.events.bif.zeek build/scripts/base/bif/plugins/Zeek_ConnSize.functions.bif.zeek @@ -165,6 +193,7 @@ scripts/base/init-frameworks-and-bifs.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_XMPP.events.bif.zeek + build/scripts/base/bif/plugins/Zeek_ARP.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.functions.bif.zeek @@ -383,4 +412,4 @@ scripts/base/init-default.zeek scripts/base/misc/find-filtered-trace.zeek scripts/base/misc/version.zeek scripts/policy/misc/loaded-scripts.zeek -#close 2020-09-11-03-21-10 +#close 2020-09-22-17-14-48 diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index e75cba3f3c..1dec4d4ae8 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -283,7 +283,7 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Weird::LOG, [columns=Weird::Info, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (X509::LOG, [columns=X509::Info, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (mysql::LOG, [columns=MySQL::Info, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Broker::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Cluster::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Config::LOG)) -> @@ -464,7 +464,7 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Weird::LOG, [columns=Weird::Info, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (X509::LOG, [columns=X509::Info, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (mysql::LOG, [columns=MySQL::Info, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(NetControl::check_plugins, , ()) -> 0.000000 MetaHookPost CallFunction(NetControl::init, , ()) -> 0.000000 MetaHookPost CallFunction(Notice::want_pp, , ()) -> @@ -834,9 +834,11 @@ 0.000000 MetaHookPost LoadFile(0, base<...>/dns) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/dpd) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/email.zeek) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/ethernet) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/event.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/exec.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/extract) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/fddi) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/file_analysis.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/files) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/files.zeek) -> -1 @@ -847,34 +849,44 @@ 0.000000 MetaHookPost LoadFile(0, base<...>/hash) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/hash_hrw.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/http) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/ieee802_11) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/ieee802_11_radio) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/imap) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/init-default.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/init-frameworks-and-bifs.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/input) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/input.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/intel) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/ip) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/irc) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/krb) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/linux_sll) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/logging) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/logging.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/main.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/messaging.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/modbus) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/mpls) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/mqtt) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/mysql) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/netcontrol) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/nflog) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/notice) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/ntlm) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/ntp) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/null) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/numbers.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/openflow) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/option.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/packet-filter) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/packet-protocols) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/paths.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/patterns.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/pe) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/plugins) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/pop3) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/ppp_serial) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/pppoe) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/queue.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/radius) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/rdp) -> -1 @@ -882,9 +894,11 @@ 0.000000 MetaHookPost LoadFile(0, base<...>/reporter) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/reporter.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/rfb) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/root) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/signatures) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/sip) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/site.zeek) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/skip) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/smb) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/smtp) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/snmp) -> -1 @@ -907,6 +921,7 @@ 0.000000 MetaHookPost LoadFile(0, base<...>/urls.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/utils.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/version.zeek) -> -1 +0.000000 MetaHookPost LoadFile(0, base<...>/vlan) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/weird.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/x509) -> -1 0.000000 MetaHookPost LoadFile(0, base<...>/xmpp) -> -1 @@ -1213,7 +1228,7 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Weird::LOG, [columns=Weird::Info, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (X509::LOG, [columns=X509::Info, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (mysql::LOG, [columns=MySQL::Info, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Broker::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Config::LOG)) @@ -1394,7 +1409,7 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Weird::LOG, [columns=Weird::Info, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (X509::LOG, [columns=X509::Info, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (mysql::LOG, [columns=MySQL::Info, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(NetControl::check_plugins, , ()) 0.000000 MetaHookPre CallFunction(NetControl::init, , ()) 0.000000 MetaHookPre CallFunction(Notice::want_pp, , ()) @@ -1764,9 +1779,11 @@ 0.000000 MetaHookPre LoadFile(0, base<...>/dns) 0.000000 MetaHookPre LoadFile(0, base<...>/dpd) 0.000000 MetaHookPre LoadFile(0, base<...>/email.zeek) +0.000000 MetaHookPre LoadFile(0, base<...>/ethernet) 0.000000 MetaHookPre LoadFile(0, base<...>/event.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/exec.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/extract) +0.000000 MetaHookPre LoadFile(0, base<...>/fddi) 0.000000 MetaHookPre LoadFile(0, base<...>/file_analysis.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/files) 0.000000 MetaHookPre LoadFile(0, base<...>/files.zeek) @@ -1777,34 +1794,44 @@ 0.000000 MetaHookPre LoadFile(0, base<...>/hash) 0.000000 MetaHookPre LoadFile(0, base<...>/hash_hrw.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/http) +0.000000 MetaHookPre LoadFile(0, base<...>/ieee802_11) +0.000000 MetaHookPre LoadFile(0, base<...>/ieee802_11_radio) 0.000000 MetaHookPre LoadFile(0, base<...>/imap) 0.000000 MetaHookPre LoadFile(0, base<...>/init-default.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/init-frameworks-and-bifs.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/input) 0.000000 MetaHookPre LoadFile(0, base<...>/input.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/intel) +0.000000 MetaHookPre LoadFile(0, base<...>/ip) 0.000000 MetaHookPre LoadFile(0, base<...>/irc) 0.000000 MetaHookPre LoadFile(0, base<...>/krb) +0.000000 MetaHookPre LoadFile(0, base<...>/linux_sll) 0.000000 MetaHookPre LoadFile(0, base<...>/logging) 0.000000 MetaHookPre LoadFile(0, base<...>/logging.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/main.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/messaging.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/modbus) +0.000000 MetaHookPre LoadFile(0, base<...>/mpls) 0.000000 MetaHookPre LoadFile(0, base<...>/mqtt) 0.000000 MetaHookPre LoadFile(0, base<...>/mysql) 0.000000 MetaHookPre LoadFile(0, base<...>/netcontrol) +0.000000 MetaHookPre LoadFile(0, base<...>/nflog) 0.000000 MetaHookPre LoadFile(0, base<...>/notice) 0.000000 MetaHookPre LoadFile(0, base<...>/ntlm) 0.000000 MetaHookPre LoadFile(0, base<...>/ntp) +0.000000 MetaHookPre LoadFile(0, base<...>/null) 0.000000 MetaHookPre LoadFile(0, base<...>/numbers.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/openflow) 0.000000 MetaHookPre LoadFile(0, base<...>/option.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/packet-filter) +0.000000 MetaHookPre LoadFile(0, base<...>/packet-protocols) 0.000000 MetaHookPre LoadFile(0, base<...>/paths.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/patterns.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/pe) 0.000000 MetaHookPre LoadFile(0, base<...>/plugins) 0.000000 MetaHookPre LoadFile(0, base<...>/pop3) +0.000000 MetaHookPre LoadFile(0, base<...>/ppp_serial) +0.000000 MetaHookPre LoadFile(0, base<...>/pppoe) 0.000000 MetaHookPre LoadFile(0, base<...>/queue.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/radius) 0.000000 MetaHookPre LoadFile(0, base<...>/rdp) @@ -1812,9 +1839,11 @@ 0.000000 MetaHookPre LoadFile(0, base<...>/reporter) 0.000000 MetaHookPre LoadFile(0, base<...>/reporter.bif.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/rfb) +0.000000 MetaHookPre LoadFile(0, base<...>/root) 0.000000 MetaHookPre LoadFile(0, base<...>/signatures) 0.000000 MetaHookPre LoadFile(0, base<...>/sip) 0.000000 MetaHookPre LoadFile(0, base<...>/site.zeek) +0.000000 MetaHookPre LoadFile(0, base<...>/skip) 0.000000 MetaHookPre LoadFile(0, base<...>/smb) 0.000000 MetaHookPre LoadFile(0, base<...>/smtp) 0.000000 MetaHookPre LoadFile(0, base<...>/snmp) @@ -1837,6 +1866,7 @@ 0.000000 MetaHookPre LoadFile(0, base<...>/urls.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/utils.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/version.zeek) +0.000000 MetaHookPre LoadFile(0, base<...>/vlan) 0.000000 MetaHookPre LoadFile(0, base<...>/weird.zeek) 0.000000 MetaHookPre LoadFile(0, base<...>/x509) 0.000000 MetaHookPre LoadFile(0, base<...>/xmpp) @@ -2142,7 +2172,7 @@ 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=Weird::Info, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=X509::Info, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=MySQL::Info, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::add_default_filter(Broker::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Config::LOG) @@ -2323,7 +2353,7 @@ 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=Weird::Info, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=X509::Info, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=MySQL::Info, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction NetControl::check_plugins() 0.000000 | HookCallFunction NetControl::init() 0.000000 | HookCallFunction Notice::want_pp() @@ -2705,9 +2735,11 @@ 0.000000 | HookLoadFile base<...>/dns 0.000000 | HookLoadFile base<...>/dpd 0.000000 | HookLoadFile base<...>/email.zeek +0.000000 | HookLoadFile base<...>/ethernet 0.000000 | HookLoadFile base<...>/event.bif.zeek 0.000000 | HookLoadFile base<...>/exec.zeek 0.000000 | HookLoadFile base<...>/extract +0.000000 | HookLoadFile base<...>/fddi 0.000000 | HookLoadFile base<...>/file_analysis.bif.zeek 0.000000 | HookLoadFile base<...>/files 0.000000 | HookLoadFile base<...>/files.zeek @@ -2718,34 +2750,44 @@ 0.000000 | HookLoadFile base<...>/hash 0.000000 | HookLoadFile base<...>/hash_hrw.zeek 0.000000 | HookLoadFile base<...>/http +0.000000 | HookLoadFile base<...>/ieee802_11 +0.000000 | HookLoadFile base<...>/ieee802_11_radio 0.000000 | HookLoadFile base<...>/imap 0.000000 | HookLoadFile base<...>/init-default.zeek 0.000000 | HookLoadFile base<...>/init-frameworks-and-bifs.zeek 0.000000 | HookLoadFile base<...>/input 0.000000 | HookLoadFile base<...>/input.bif.zeek 0.000000 | HookLoadFile base<...>/intel +0.000000 | HookLoadFile base<...>/ip 0.000000 | HookLoadFile base<...>/irc 0.000000 | HookLoadFile base<...>/krb +0.000000 | HookLoadFile base<...>/linux_sll 0.000000 | HookLoadFile base<...>/logging 0.000000 | HookLoadFile base<...>/logging.bif.zeek 0.000000 | HookLoadFile base<...>/main.zeek 0.000000 | HookLoadFile base<...>/messaging.bif.zeek 0.000000 | HookLoadFile base<...>/modbus +0.000000 | HookLoadFile base<...>/mpls 0.000000 | HookLoadFile base<...>/mqtt 0.000000 | HookLoadFile base<...>/mysql 0.000000 | HookLoadFile base<...>/netcontrol +0.000000 | HookLoadFile base<...>/nflog 0.000000 | HookLoadFile base<...>/notice 0.000000 | HookLoadFile base<...>/ntlm 0.000000 | HookLoadFile base<...>/ntp +0.000000 | HookLoadFile base<...>/null 0.000000 | HookLoadFile base<...>/numbers.zeek 0.000000 | HookLoadFile base<...>/openflow 0.000000 | HookLoadFile base<...>/option.bif.zeek 0.000000 | HookLoadFile base<...>/packet-filter +0.000000 | HookLoadFile base<...>/packet-protocols 0.000000 | HookLoadFile base<...>/paths.zeek 0.000000 | HookLoadFile base<...>/patterns.zeek 0.000000 | HookLoadFile base<...>/pe 0.000000 | HookLoadFile base<...>/plugins 0.000000 | HookLoadFile base<...>/pop3 +0.000000 | HookLoadFile base<...>/ppp_serial +0.000000 | HookLoadFile base<...>/pppoe 0.000000 | HookLoadFile base<...>/queue.zeek 0.000000 | HookLoadFile base<...>/radius 0.000000 | HookLoadFile base<...>/rdp @@ -2753,9 +2795,11 @@ 0.000000 | HookLoadFile base<...>/reporter 0.000000 | HookLoadFile base<...>/reporter.bif.zeek 0.000000 | HookLoadFile base<...>/rfb +0.000000 | HookLoadFile base<...>/root 0.000000 | HookLoadFile base<...>/signatures 0.000000 | HookLoadFile base<...>/sip 0.000000 | HookLoadFile base<...>/site.zeek +0.000000 | HookLoadFile base<...>/skip 0.000000 | HookLoadFile base<...>/smb 0.000000 | HookLoadFile base<...>/smtp 0.000000 | HookLoadFile base<...>/snmp @@ -2778,12 +2822,13 @@ 0.000000 | HookLoadFile base<...>/urls.zeek 0.000000 | HookLoadFile base<...>/utils.zeek 0.000000 | HookLoadFile base<...>/version.zeek +0.000000 | HookLoadFile base<...>/vlan 0.000000 | HookLoadFile base<...>/weird.zeek 0.000000 | HookLoadFile base<...>/x509 0.000000 | HookLoadFile base<...>/xmpp 0.000000 | HookLoadFile base<...>/zeek.bif.zeek 0.000000 | HookLogInit packet_filter 1/1 {ts (time), node (string), filter (string), init (bool), success (bool)} -0.000000 | HookLogWrite packet_filter [ts=1599794475.539113, node=zeek, filter=ip or not ip, init=T, success=T] +0.000000 | HookLogWrite packet_filter [ts=1600794881.771065, node=zeek, filter=ip or not ip, init=T, success=T] 0.000000 | HookQueueEvent NetControl::init() 0.000000 | HookQueueEvent filter_change_tracking() 0.000000 | HookQueueEvent zeek_init() diff --git a/testing/btest/Baseline/plugins.packet-protocol/output_build b/testing/btest/Baseline/plugins.packet-protocol/output_build new file mode 100644 index 0000000000..a5aa53185b --- /dev/null +++ b/testing/btest/Baseline/plugins.packet-protocol/output_build @@ -0,0 +1,6 @@ +PacketDemo::Bar - Demo packet analyzers (RawLayer, LLC). (dynamic, version 1.0.0) + [Packet Analyzer] LLC_Demo (ANALYZER_LLC_DEMO) + [Packet Analyzer] Raw_Layer (ANALYZER_RAW_LAYER) + [Event] raw_layer_message + [Event] llc_demo_message + diff --git a/testing/btest/Baseline/plugins.packet-protocol/output_llc b/testing/btest/Baseline/plugins.packet-protocol/output_llc new file mode 100644 index 0000000000..2d25cc574d --- /dev/null +++ b/testing/btest/Baseline/plugins.packet-protocol/output_llc @@ -0,0 +1,4 @@ +llc_demo_message (DSAP = 42, SSAP = 42, Control = 3) +llc_demo_message (DSAP = 42, SSAP = 42, Control = 3) +llc_demo_message (DSAP = 42, SSAP = 42, Control = 3) +llc_demo_message (DSAP = 42, SSAP = 42, Control = 3) diff --git a/testing/btest/Baseline/plugins.packet-protocol/output_orig b/testing/btest/Baseline/plugins.packet-protocol/output_orig new file mode 100644 index 0000000000..576ab517dd --- /dev/null +++ b/testing/btest/Baseline/plugins.packet-protocol/output_orig @@ -0,0 +1,20 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2020-09-02-18-56-02 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1599068759.619112 CHhAvVGS1DHFjwGM9 172.22.214.60 8 192.0.78.212 0 icmp - - - - OTH - - 0 - 1 28 0 0 - +#close 2020-09-02-18-56-02 +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open 2020-09-02-18-56-02 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer +#types time string addr port addr port string string bool string +1599068759.647566 - - - - - truncated_IP - F zeek +#close 2020-09-02-18-56-02 diff --git a/testing/btest/Baseline/plugins.packet-protocol/output_raw b/testing/btest/Baseline/plugins.packet-protocol/output_raw new file mode 100644 index 0000000000..621f8054ee --- /dev/null +++ b/testing/btest/Baseline/plugins.packet-protocol/output_raw @@ -0,0 +1,12 @@ +raw_layer_message (Message = 'I am encapsulating IP', Protocol = 4950) +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2020-09-03-17-54-45 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1599068759.647566 ClEkJM2Vm5giqnMf4h 172.22.214.60 8 192.0.78.150 0 icmp - - - - OTH - - 0 - 1 28 0 0 - +1599068759.619112 CHhAvVGS1DHFjwGM9 172.22.214.60 8 192.0.78.212 0 icmp - - - - OTH - - 0 - 1 28 0 0 - +#close 2020-09-03-17-54-45 diff --git a/testing/btest/Baseline/scripts.base.protocols.arp.linuxsll/.stdout b/testing/btest/Baseline/scripts.base.protocols.arp.linuxsll/.stdout new file mode 100644 index 0000000000..971bacd567 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.arp.linuxsll/.stdout @@ -0,0 +1,12 @@ +cc:2d:e0:26:19:99, 00:00:00:00:00:00, 192.168.22.1, cc:2d:e0:26:19:99, 192.168.22.160, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:3f:0d, 00:00:00:00:00:00, 192.168.22.81, 00:50:56:8b:3f:0d, 192.168.22.81, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:3f:0d, 00:00:00:00:00:00, 192.168.22.81, 00:50:56:8b:3f:0d, 192.168.22.81, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 +00:50:56:8b:cf:fa, 00:00:00:00:00:00, 10.1.10.100, 00:50:56:8b:cf:fa, 10.1.10.1, 00:00:00:00:00:00 diff --git a/testing/btest/Traces/http/get_nosyn.trace b/testing/btest/Traces/http/get_nosyn.trace new file mode 100644 index 0000000000..9a1d08ce69 Binary files /dev/null and b/testing/btest/Traces/http/get_nosyn.trace differ diff --git a/testing/btest/Traces/linuxsll-arp.pcap b/testing/btest/Traces/linuxsll-arp.pcap new file mode 100644 index 0000000000..7898d55a40 Binary files /dev/null and b/testing/btest/Traces/linuxsll-arp.pcap differ diff --git a/testing/btest/Traces/raw_layer.pcap b/testing/btest/Traces/raw_layer.pcap new file mode 100644 index 0000000000..5e4ed891dc Binary files /dev/null and b/testing/btest/Traces/raw_layer.pcap differ diff --git a/testing/btest/core/skip_analyzer.zeek b/testing/btest/core/skip_analyzer.zeek new file mode 100644 index 0000000000..62652d0373 --- /dev/null +++ b/testing/btest/core/skip_analyzer.zeek @@ -0,0 +1,14 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/tunnels/gre-sample.pcap %INPUT +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: test ! -e tunnel.log + +# Test the skip analyzer by skipping everything outside the GRE tunnel. + +@load base/protocols/conn +@load base/frameworks/tunnels + +redef PacketAnalyzer::ROOT::dispatch_map += { + [1] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_SKIP) +}; + +redef PacketAnalyzer::SKIP::skip_bytes: count = 38; diff --git a/testing/btest/plugins/packet-protocol-plugin/.btest-ignore b/testing/btest/plugins/packet-protocol-plugin/.btest-ignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/plugins/packet-protocol-plugin/CMakeLists.txt b/testing/btest/plugins/packet-protocol-plugin/CMakeLists.txt new file mode 100644 index 0000000000..4a58a114c5 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/CMakeLists.txt @@ -0,0 +1,19 @@ + +project(Zeek-Packet-Plugin-Demo) + +cmake_minimum_required(VERSION 2.6.3) + +if ( NOT ZEEK_DIST ) + message(FATAL_ERROR "ZEEK_DIST not set") +endif () + +set(CMAKE_MODULE_PATH ${ZEEK_DIST}/cmake) + +include(ZeekPlugin) + +zeek_plugin_begin(PacketDemo Bar) +zeek_plugin_cc(src/Plugin.cc) +zeek_plugin_cc(src/RawLayer.cc) +zeek_plugin_cc(src/LLCDemo.cc) +zeek_plugin_bif(src/events.bif) +zeek_plugin_end() diff --git a/testing/btest/plugins/packet-protocol-plugin/scripts/PacketDemo/LLCDemo/base/main.zeek b/testing/btest/plugins/packet-protocol-plugin/scripts/PacketDemo/LLCDemo/base/main.zeek new file mode 100644 index 0000000000..6269c4ff99 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/scripts/PacketDemo/LLCDemo/base/main.zeek @@ -0,0 +1,3 @@ +module PacketAnalyzer::LLC_DEMO; + +redef PacketAnalyzer::ETHERNET::llc_analyzer = PacketAnalyzer::ANALYZER_LLC_DEMO; \ No newline at end of file diff --git a/testing/btest/plugins/packet-protocol-plugin/scripts/PacketDemo/RawLayer/base/main.zeek b/testing/btest/plugins/packet-protocol-plugin/scripts/PacketDemo/RawLayer/base/main.zeek new file mode 100644 index 0000000000..be32149e59 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/scripts/PacketDemo/RawLayer/base/main.zeek @@ -0,0 +1,14 @@ +module PacketAnalyzer::RAW_LAYER; + +export { + ## Identifier mapping + const dispatch_map: PacketAnalyzer::DispatchMap = {} &redef; +} + +redef PacketAnalyzer::ETHERNET::dispatch_map += { + [0x88B5] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_RAW_LAYER) +}; + +redef dispatch_map += { + [0x4950] = PacketAnalyzer::DispatchEntry($analyzer=PacketAnalyzer::ANALYZER_IP) +}; diff --git a/testing/btest/plugins/packet-protocol-plugin/scripts/__load__.zeek b/testing/btest/plugins/packet-protocol-plugin/scripts/__load__.zeek new file mode 100644 index 0000000000..80083daff0 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/scripts/__load__.zeek @@ -0,0 +1,2 @@ +@load PacketDemo/RawLayer/base/main +@load PacketDemo/LLCDemo/base/main diff --git a/testing/btest/plugins/packet-protocol-plugin/src/LLCDemo.cc b/testing/btest/plugins/packet-protocol-plugin/src/LLCDemo.cc new file mode 100644 index 0000000000..f8bc8be53f --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/src/LLCDemo.cc @@ -0,0 +1,32 @@ +#include "LLCDemo.h" +#include "Event.h" +#include "Val.h" +#include "events.bif.h" + +using namespace zeek::packet_analysis::PacketDemo; + +LLCDemo::LLCDemo() + : zeek::packet_analysis::Analyzer("LLC_Demo") + { + } + +bool LLCDemo::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + // Rudimentary parsing of 802.2 LLC + if ( 17 >= len ) + { + packet->Weird("truncated_llc_header"); + return false; + } + + auto dsap = data[14]; + auto ssap = data[15]; + auto control = data[16]; + + event_mgr.Enqueue(llc_demo_message, + val_mgr->Count(dsap), + val_mgr->Count(ssap), + val_mgr->Count(control)); + + return true; + } diff --git a/testing/btest/plugins/packet-protocol-plugin/src/LLCDemo.h b/testing/btest/plugins/packet-protocol-plugin/src/LLCDemo.h new file mode 100644 index 0000000000..a649970e85 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/src/LLCDemo.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace zeek::packet_analysis::PacketDemo { + +class LLCDemo : public Analyzer { +public: + LLCDemo(); + ~LLCDemo() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/testing/btest/plugins/packet-protocol-plugin/src/Plugin.cc b/testing/btest/plugins/packet-protocol-plugin/src/Plugin.cc new file mode 100644 index 0000000000..af88a438fa --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/src/Plugin.cc @@ -0,0 +1,29 @@ +#include "Plugin.h" +#include "packet_analysis/Component.h" + +#include "RawLayer.h" +#include "LLCDemo.h" + +namespace zeek::plugin::PacketDemo_Bar { + +class Plugin : public zeek::plugin::Plugin { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component("Raw_Layer", + zeek::packet_analysis::PacketDemo::RawLayer::Instantiate)); + AddComponent(new zeek::packet_analysis::Component("LLC_Demo", + zeek::packet_analysis::PacketDemo::LLCDemo::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "PacketDemo::Bar"; + config.description = "Demo packet analyzers (RawLayer, LLC)."; + config.version.major = 1; + config.version.minor = 0; + config.version.patch = 0; + return config; + } + +} plugin; + +} diff --git a/testing/btest/plugins/packet-protocol-plugin/src/RawLayer.cc b/testing/btest/plugins/packet-protocol-plugin/src/RawLayer.cc new file mode 100644 index 0000000000..a1bb9af237 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/src/RawLayer.cc @@ -0,0 +1,29 @@ +#include "RawLayer.h" +#include "Event.h" +#include "Val.h" +#include "events.bif.h" + +using namespace zeek::packet_analysis::PacketDemo; + +RawLayer::RawLayer() + : zeek::packet_analysis::Analyzer("Raw_Layer") + { + } + +bool RawLayer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + constexpr auto layer_size = 21; + if ( layer_size >= len ) + { + packet->Weird("truncated_raw_layer"); + return false; + } + + uint16_t protocol = ntohs(*((const uint16_t*)(data + layer_size -2))); + + event_mgr.Enqueue(raw_layer_message, + make_intrusive(layer_size, reinterpret_cast(data)), + val_mgr->Count(protocol)); + + return ForwardPacket(len - layer_size, data + layer_size, packet, protocol); + } diff --git a/testing/btest/plugins/packet-protocol-plugin/src/RawLayer.h b/testing/btest/plugins/packet-protocol-plugin/src/RawLayer.h new file mode 100644 index 0000000000..bf47e933ab --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/src/RawLayer.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace zeek::packet_analysis::PacketDemo { + +class RawLayer : public Analyzer { +public: + RawLayer(); + ~RawLayer() override = default; + + bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) override; + + static AnalyzerPtr Instantiate() + { + return std::make_shared(); + } +}; + +} diff --git a/testing/btest/plugins/packet-protocol-plugin/src/events.bif b/testing/btest/plugins/packet-protocol-plugin/src/events.bif new file mode 100644 index 0000000000..d70f3e1ea1 --- /dev/null +++ b/testing/btest/plugins/packet-protocol-plugin/src/events.bif @@ -0,0 +1,3 @@ + +event raw_layer_message%(message: string, protocol: count%); +event llc_demo_message%(dsap: count, ssap: count, control: count%); diff --git a/testing/btest/plugins/packet-protocol.zeek b/testing/btest/plugins/packet-protocol.zeek new file mode 100644 index 0000000000..4ac25356a0 --- /dev/null +++ b/testing/btest/plugins/packet-protocol.zeek @@ -0,0 +1,32 @@ +# @TEST-EXEC: zeek -r $TRACES/raw_layer.pcap +# @TEST-EXEC: cat conn.log > output_orig +# @TEST-EXEC: cat weird.log >> output_orig +# @TEST-EXEC: btest-diff output_orig +# @TEST-EXEC: rm -f *.log +# +# @TEST-EXEC: ${DIST}/auxil/zeek-aux/plugin-support/init-plugin -u . PacketDemo Bar +# @TEST-EXEC: cp -r %DIR/packet-protocol-plugin/* . +# @TEST-EXEC: ./configure --zeek-dist=${DIST} && make +# @TEST-EXEC: ZEEK_PLUGIN_PATH=`pwd` zeek -NN PacketDemo::Bar > output_build +# @TEST-EXEC: btest-diff output_build +# +# @TEST-EXEC: ZEEK_PLUGIN_PATH=`pwd` zeek -r $TRACES/raw_layer.pcap %INPUT > output_raw +# @TEST-EXEC: cat conn.log >> output_raw +# @TEST-EXEC: test ! -e weird.log +# @TEST-EXEC: btest-diff output_raw +# @TEST-EXEC: rm -f *.log +# +# @TEST-EXEC: ZEEK_PLUGIN_PATH=`pwd` zeek -r $TRACES/raw_packets.trace %INPUT > output_llc +# @TEST-EXEC: btest-diff output_llc + +event raw_layer_message(msg: string, protocol: count) + { + print fmt("raw_layer_message (Message = '%s', Protocol = %x)", msg, protocol); + } + +event llc_demo_message(dsap: count, ssap: count, control: count) + { + print fmt("llc_demo_message (DSAP = %x, SSAP = %x, Control = %x)", + dsap, ssap, control); + } + diff --git a/testing/btest/plugins/pktdumper-plugin/src/Foo.cc b/testing/btest/plugins/pktdumper-plugin/src/Foo.cc index 75dc5d990b..9f0ad925dd 100644 --- a/testing/btest/plugins/pktdumper-plugin/src/Foo.cc +++ b/testing/btest/plugins/pktdumper-plugin/src/Foo.cc @@ -20,7 +20,6 @@ Foo::~Foo() void Foo::Open() { props.open_time = zeek::run_state::network_time; - props.hdr_size = 0; Opened(props); } diff --git a/testing/btest/scripts/base/protocols/arp/linuxsll.test b/testing/btest/scripts/base/protocols/arp/linuxsll.test new file mode 100644 index 0000000000..01922961cb --- /dev/null +++ b/testing/btest/scripts/base/protocols/arp/linuxsll.test @@ -0,0 +1,12 @@ +# @TEST-EXEC: zeek -r $TRACES/linuxsll-arp.pcap %INPUT +# @TEST-EXEC: btest-diff .stdout + +event arp_request(mac_src: string, mac_dst: string, SPA: addr, SHA: string, TPA: addr, THA: string) + { + print mac_src, mac_dst, SPA, SHA, TPA, THA; + } + +event arp_reply(mac_src: string, mac_dst: string, SPA: addr, SHA: string, TPA: addr, THA: string) + { + print mac_src, mac_dst, SPA, SHA, TPA, THA; + } diff --git a/testing/external/commit-hash.zeek-testing b/testing/external/commit-hash.zeek-testing index 1ad188ee12..05520f90d5 100644 --- a/testing/external/commit-hash.zeek-testing +++ b/testing/external/commit-hash.zeek-testing @@ -1 +1 @@ -fecd17b3e3d886fccc9277b1394e84499649fc53 +4f492329f46bd3fb2992b09ce4c299b1f7237d45 diff --git a/testing/external/commit-hash.zeek-testing-private b/testing/external/commit-hash.zeek-testing-private index 24b4e069ff..271a66b118 100644 --- a/testing/external/commit-hash.zeek-testing-private +++ b/testing/external/commit-hash.zeek-testing-private @@ -1 +1 @@ -418c0cdd93a298eaa7c02bc8b7db7037269a2ba4 +d57bbaabc12dad1f56b22b93cf290deae6862020