From b8f0acb5f1fca56c444cef6886e06f7f795749f8 Mon Sep 17 00:00:00 2001 From: Simeon Miteff Date: Mon, 15 Aug 2022 15:32:20 +1000 Subject: [PATCH] Add support for DLT_LINUX_SLL2 PCAP link-type --- scripts/base/packet-protocols/__load__.zeek | 1 + .../packet-protocols/linux_sll2/__load__.zeek | 1 + .../packet-protocols/linux_sll2/main.zeek | 11 +++++ scripts/base/packet-protocols/root/main.zeek | 2 + src/iosource/Packet.h | 4 +- src/packet_analysis/protocol/CMakeLists.txt | 1 + .../protocol/linux_sll2/CMakeLists.txt | 8 ++++ .../protocol/linux_sll2/LinuxSLL2.cc | 30 ++++++++++++++ .../protocol/linux_sll2/LinuxSLL2.h | 38 ++++++++++++++++++ .../protocol/linux_sll2/Plugin.cc | 27 +++++++++++++ testing/btest/Baseline/core.linuxsll2/.stdout | 6 +++ testing/btest/Traces/linux_dlt_sll2.pcap | Bin 0 -> 672 bytes testing/btest/core/linuxsll2.zeek | 17 ++++++++ 13 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 scripts/base/packet-protocols/linux_sll2/__load__.zeek create mode 100644 scripts/base/packet-protocols/linux_sll2/main.zeek create mode 100644 src/packet_analysis/protocol/linux_sll2/CMakeLists.txt create mode 100644 src/packet_analysis/protocol/linux_sll2/LinuxSLL2.cc create mode 100644 src/packet_analysis/protocol/linux_sll2/LinuxSLL2.h create mode 100644 src/packet_analysis/protocol/linux_sll2/Plugin.cc create mode 100644 testing/btest/Baseline/core.linuxsll2/.stdout create mode 100644 testing/btest/Traces/linux_dlt_sll2.pcap create mode 100644 testing/btest/core/linuxsll2.zeek diff --git a/scripts/base/packet-protocols/__load__.zeek b/scripts/base/packet-protocols/__load__.zeek index 5ea4cb93ef..08905878bd 100644 --- a/scripts/base/packet-protocols/__load__.zeek +++ b/scripts/base/packet-protocols/__load__.zeek @@ -8,6 +8,7 @@ @load base/packet-protocols/ieee802_11 @load base/packet-protocols/ieee802_11_radio @load base/packet-protocols/linux_sll +@load base/packet-protocols/linux_sll2 @load base/packet-protocols/nflog @load base/packet-protocols/null @load base/packet-protocols/ppp_serial diff --git a/scripts/base/packet-protocols/linux_sll2/__load__.zeek b/scripts/base/packet-protocols/linux_sll2/__load__.zeek new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/packet-protocols/linux_sll2/__load__.zeek @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/packet-protocols/linux_sll2/main.zeek b/scripts/base/packet-protocols/linux_sll2/main.zeek new file mode 100644 index 0000000000..353dcab8b6 --- /dev/null +++ b/scripts/base/packet-protocols/linux_sll2/main.zeek @@ -0,0 +1,11 @@ +module PacketAnalyzer::LINUXSLL2; + +event zeek_init() &priority=20 + { + PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL2, 0x0800, PacketAnalyzer::ANALYZER_IP); + PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL2, 0x86DD, PacketAnalyzer::ANALYZER_IP); + PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL2, 0x0806, PacketAnalyzer::ANALYZER_ARP); + + # RARP + PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL2, 0x8035, PacketAnalyzer::ANALYZER_ARP); + } diff --git a/scripts/base/packet-protocols/root/main.zeek b/scripts/base/packet-protocols/root/main.zeek index f823e9f6c2..daca642329 100644 --- a/scripts/base/packet-protocols/root/main.zeek +++ b/scripts/base/packet-protocols/root/main.zeek @@ -10,6 +10,7 @@ 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_LINUX_SLL2 : count = 276; const DLT_NFLOG : count = 239; event zeek_init() &priority=20 @@ -19,5 +20,6 @@ event zeek_init() &priority=20 PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_ROOT, DLT_IEEE802_11, PacketAnalyzer::ANALYZER_IEEE802_11); PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_ROOT, DLT_IEEE802_11_RADIO, PacketAnalyzer::ANALYZER_IEEE802_11_RADIO); PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_ROOT, DLT_LINUX_SLL, PacketAnalyzer::ANALYZER_LINUXSLL); + PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_ROOT, DLT_LINUX_SLL2, PacketAnalyzer::ANALYZER_LINUXSLL2); PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_ROOT, DLT_NFLOG, PacketAnalyzer::ANALYZER_NFLOG); } diff --git a/src/iosource/Packet.h b/src/iosource/Packet.h index b0db0a2b12..cedc235493 100644 --- a/src/iosource/Packet.h +++ b/src/iosource/Packet.h @@ -136,8 +136,8 @@ public: /** * 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. + * LinuxSLL/LinuxSLL2 packet analyzers don'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}; diff --git a/src/packet_analysis/protocol/CMakeLists.txt b/src/packet_analysis/protocol/CMakeLists.txt index e325816351..63f8c03928 100644 --- a/src/packet_analysis/protocol/CMakeLists.txt +++ b/src/packet_analysis/protocol/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(fddi) add_subdirectory(nflog) add_subdirectory(mpls) add_subdirectory(linux_sll) +add_subdirectory(linux_sll2) add_subdirectory(arp) add_subdirectory(ip) diff --git a/src/packet_analysis/protocol/linux_sll2/CMakeLists.txt b/src/packet_analysis/protocol/linux_sll2/CMakeLists.txt new file mode 100644 index 0000000000..75bc2cb0b6 --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll2/CMakeLists.txt @@ -0,0 +1,8 @@ + +include(ZeekPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +zeek_plugin_begin(PacketAnalyzer LinuxSLL2) +zeek_plugin_cc(LinuxSLL2.cc Plugin.cc) +zeek_plugin_end() diff --git a/src/packet_analysis/protocol/linux_sll2/LinuxSLL2.cc b/src/packet_analysis/protocol/linux_sll2/LinuxSLL2.cc new file mode 100644 index 0000000000..49ea1f2492 --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll2/LinuxSLL2.cc @@ -0,0 +1,30 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/packet_analysis/protocol/linux_sll2/LinuxSLL2.h" + +using namespace zeek::packet_analysis::LinuxSLL2; + +LinuxSLL2Analyzer::LinuxSLL2Analyzer() : zeek::packet_analysis::Analyzer("LinuxSLL2") { } + +bool LinuxSLL2Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) + { + auto len_sll2_hdr = sizeof(SLL2Header); + if ( len_sll2_hdr >= len ) + { + Weird("truncated_Linux_SLL2_header", packet); + return false; + } + + // Note: We assume to see an Ethertype and don't consider different ARPHRD_types + // (see https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL2.html) + auto hdr = (const SLL2Header*)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_sll2_hdr, data + len_sll2_hdr, packet, protocol); + } diff --git a/src/packet_analysis/protocol/linux_sll2/LinuxSLL2.h b/src/packet_analysis/protocol/linux_sll2/LinuxSLL2.h new file mode 100644 index 0000000000..a1b20fdd9a --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll2/LinuxSLL2.h @@ -0,0 +1,38 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include "zeek/packet_analysis/Analyzer.h" +#include "zeek/packet_analysis/Component.h" + +namespace zeek::packet_analysis::LinuxSLL2 + { + +class LinuxSLL2Analyzer : public Analyzer + { +public: + LinuxSLL2Analyzer(); + ~LinuxSLL2Analyzer() 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_SLL2.html + struct SLL2Header + { + uint16_t protocol_type; + uint16_t reserved; + uint32_t interface_index; + uint16_t arphrd_type; + uint8_t packet_type; + uint8_t addr_len; + uint64_t addr; + } __attribute__((__packed__)); + }; + + } diff --git a/src/packet_analysis/protocol/linux_sll2/Plugin.cc b/src/packet_analysis/protocol/linux_sll2/Plugin.cc new file mode 100644 index 0000000000..f70f2fe139 --- /dev/null +++ b/src/packet_analysis/protocol/linux_sll2/Plugin.cc @@ -0,0 +1,27 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/plugin/Plugin.h" + +#include "zeek/packet_analysis/Component.h" +#include "zeek/packet_analysis/protocol/linux_sll2/LinuxSLL2.h" + +namespace zeek::plugin::Zeek_LinuxSLL2 + { + +class Plugin : public zeek::plugin::Plugin + { +public: + zeek::plugin::Configuration Configure() + { + AddComponent(new zeek::packet_analysis::Component( + "LinuxSLL2", zeek::packet_analysis::LinuxSLL2::LinuxSLL2Analyzer::Instantiate)); + + zeek::plugin::Configuration config; + config.name = "Zeek::LinuxSLL2"; + config.description = "Linux cooked capture version 2 (SLL2) packet analyzer"; + return config; + } + + } plugin; + + } diff --git a/testing/btest/Baseline/core.linuxsll2/.stdout b/testing/btest/Baseline/core.linuxsll2/.stdout new file mode 100644 index 0000000000..e1f6cbe44f --- /dev/null +++ b/testing/btest/Baseline/core.linuxsll2/.stdout @@ -0,0 +1,6 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[orig_h=192.0.2.1, orig_p=8/icmp, resp_h=192.0.2.1, resp_p=0/icmp], [v6=F, itype=8, icode=0, len=56, ttl=64], 8, 1 +[orig_h=192.0.2.1, orig_p=8/icmp, resp_h=192.0.2.1, resp_p=0/icmp], [v6=F, itype=0, icode=0, len=56, ttl=64], 8, 1 +[orig_h=fe80::8c36:6ff:fe44:acaf, orig_p=128/icmp, resp_h=fe80::8c36:6ff:fe44:acaf, resp_p=129/icmp], [v6=T, itype=128, icode=0, len=56, ttl=64], 9, 1 +[orig_h=fe80::8c36:6ff:fe44:acaf, orig_p=128/icmp, resp_h=fe80::8c36:6ff:fe44:acaf, resp_p=129/icmp], [v6=T, itype=129, icode=0, len=56, ttl=64], 9, 1 +8e:36:06:44:ac:af, 00:00:00:00:00:00, 192.0.2.1, 8e:36:06:44:ac:af, 192.0.2.2, 00:00:00:00:00:00 diff --git a/testing/btest/Traces/linux_dlt_sll2.pcap b/testing/btest/Traces/linux_dlt_sll2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ec9bc31abcd55c0c59b6a8e714686492c178e49c GIT binary patch literal 672 zcmca|c+)~A1{MYcU||qpWMFu?_h*u`KQBWDPy&QGAPN|nSs2)0YF!x^Le}> zOC4ZfVgz9hhO{j}#f%{RAa#%Yc)`jA1cih}M8(7<*BLk&7(r%&RIUb^3j)N30Z5-v6alyJ9NbNe zTN)XbQ{cY@fB?v1 QLf7A53YNmApBbBe06TPor~m)} literal 0 HcmV?d00001 diff --git a/testing/btest/core/linuxsll2.zeek b/testing/btest/core/linuxsll2.zeek new file mode 100644 index 0000000000..a436eedc64 --- /dev/null +++ b/testing/btest/core/linuxsll2.zeek @@ -0,0 +1,17 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/linux_dlt_sll2.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 icmp_echo_request(c: connection , info: icmp_info , id: count , seq: count , payload: string ) + { + print c$id, info, id, seq; + } + +event icmp_echo_reply(c: connection , info: icmp_info , id: count , seq: count , payload: string ) + { + print c$id, info, id, seq; + }