#define PROTO_BIT__ANY_SSN (PROTO_BIT__ANY_IP | PROTO_BIT__PDU | PROTO_BIT__FILE | PROTO_BIT__USER)
#define PROTO_BIT__ANY_TYPE (PROTO_BIT__ANY_SSN | PROTO_BIT__ARP)
-enum DecodeFlags : std::uint16_t
+enum DecodeFlags : std::uint32_t
{
- DECODE_ERR_CKSUM_IP = 0x0001, // error flags
- DECODE_ERR_CKSUM_TCP = 0x0002,
- DECODE_ERR_CKSUM_UDP = 0x0004,
- DECODE_ERR_CKSUM_ICMP = 0x0008,
- DECODE_ERR_BAD_TTL = 0x0010,
+ DECODE_ERR_CKSUM_IP = 0x00000001, // error flags
+ DECODE_ERR_CKSUM_TCP = 0x00000002,
+ DECODE_ERR_CKSUM_UDP = 0x00000004,
+ DECODE_ERR_CKSUM_ICMP = 0x00000008,
+ DECODE_ERR_BAD_TTL = 0x00000010,
DECODE_ERR_CKSUM_ALL = ( DECODE_ERR_CKSUM_IP | DECODE_ERR_CKSUM_TCP |
DECODE_ERR_CKSUM_UDP | DECODE_ERR_CKSUM_ICMP ),
- DECODE_ERR_FLAGS = ( DECODE_ERR_CKSUM_ALL | DECODE_ERR_BAD_TTL ),
- DECODE_PKT_TRUST = 0x0020, // trust this packet
- DECODE_FRAG = 0x0040, // ip - fragmented packet
- DECODE_MF = 0x0080, // ip - more fragments
- DECODE_DF = 0x0100, // ip - don't fragment
+ DECODE_PKT_TRUST = 0x00000020, // trust this packet
+ DECODE_FRAG = 0x00000040, // ip - fragmented packet
+ DECODE_MF = 0x00000080, // ip - more fragments
+ DECODE_DF = 0x00000100, // ip - don't fragment
// using decode flags in lieu of creating user layer for now
- DECODE_C2S = 0x0200, // user - client to server
- DECODE_SOF = 0x0400, // user - start of flow
- DECODE_EOF = 0x0800, // user - end of flow
- DECODE_GTP = 0x1000,
-
- DECODE_TCP_MSS = 0x2000,
- DECODE_TCP_TS = 0x4000,
- DECODE_TCP_WS = 0x8000,
+ DECODE_C2S = 0x00000200, // user - client to server
+ DECODE_SOF = 0x00000400, // user - start of flow
+ DECODE_EOF = 0x00000800, // user - end of flow
+ DECODE_GTP = 0x00001000,
+
+ DECODE_TCP_MSS = 0x00002000,
+ DECODE_TCP_TS = 0x00004000,
+ DECODE_TCP_WS = 0x00008000,
+
+ DECODE_ERR_LEN = 0X00010000, // received incorrect len from DAQ
+
+ DECODE_ERR_FLAGS = ( DECODE_ERR_CKSUM_ALL | DECODE_ERR_BAD_TTL | DECODE_ERR_LEN ),
};
struct DecodeData
uint16_t sp = 0; /* source port (TCP/UDP) */
uint16_t dp = 0; /* dest port (TCP/UDP) */
- uint16_t decode_flags = 0;
+ uint32_t decode_flags = 0;
PktType type = PktType::NONE;
snort::ip::IpApi ip_api;
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2024-2024 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// decode_err_len_test.cc author Maya Dagon <mdagon@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "detection/detection_engine.h"
+#include "detection/ips_context.h"
+#include "flow/expect_cache.h"
+#include "log/text_log.h"
+#include "main/snort_config.h"
+#include "managers/codec_manager.h"
+#include "packet_io/sfdaq.h"
+#include "packet_tracer/packet_tracer.h"
+#include "profiler/profiler_defs.h"
+#include "stream/stream.h"
+#include "trace/trace_api.h"
+
+#include "protocols/packet.h"
+#include "protocols/packet_manager.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+using namespace snort;
+
+
+//------------------------------
+// Stubs
+//------------------------------
+bool snort::TextLog_Print(TextLog* const, const char*, ...) { return true; }
+bool snort::TextLog_Write(TextLog* const, const char*, int) { return true; }
+bool snort::TextLog_Putc(TextLog* const, char) { return true; }
+void snort::trace_vprintf(const char*, TraceLevel, const char*, const Packet*, const char*, va_list) { }
+void TraceApi::filter(const Packet&) {}
+uint8_t TraceApi::get_constraints_generation() { return 0; }
+
+void ExpectFlow::reset_expect_flows() {}
+bool SnortConfig::tunnel_bypass_enabled(uint16_t) const { return false; }
+const vlan::VlanTagHdr* layer::get_vlan_layer(const Packet*) { return nullptr; }
+const geneve::GeneveLyr* layer::get_geneve_layer(const Packet*, bool) { return nullptr; }
+void ip::IpApi::reset() {}
+void PacketTracer::log_msg_only(const char*, ...) {}
+void PacketTracer::log(const char*, ...) {}
+int DetectionEngine::queue_event(unsigned, unsigned) { return 0; }
+Packet* DetectionEngine::get_encode_packet() { return nullptr; }
+void show_percent_stats(PegCount*, const char*[], unsigned, const char*) {}
+void layer::set_packet_pointer(const Packet* const) {}
+bool layer::set_inner_ip_api(const Packet* const, ip::IpApi&, int8_t&) { return true; }
+int layer::get_inner_ip_lyr_index(const Packet* const) { return 0; }
+int layer::get_inner_ip6_frag_index(const Packet* const) { return 0; }
+uint8_t Stream::get_flow_ttl(Flow*, char, bool) { return 0; }
+bool SFDAQ::forwarding_packet(const DAQ_PktHdr_t*) { return false; }
+void sum_stats(PegCount*, PegCount*, unsigned, bool) {}
+IpsContext::IpsContext(unsigned):
+ packet(nullptr), encode_packet(nullptr), pkth (nullptr), buf(nullptr),
+ stash(nullptr), otnx(nullptr), equeue(nullptr), context_num(0),
+ active_rules(IpsContext::NONE), state(IpsContext::IDLE), check_tags(false), clear_inspectors(false),
+ data(0), depends_on(nullptr), next_to_process(nullptr) { searches.context = nullptr; }
+IpsContext::~IpsContext() {}
+Buffer::Buffer(uint8_t*, uint32_t) :
+ base(nullptr), end(0), max_len(0), off(0) {}
+EncState::EncState(const ip::IpApi& api, EncodeFlags f, IpProtocol pr, uint8_t t, uint16_t data_size) :
+ ip_api(api), flags(f), dsize(data_size), next_ethertype(ProtocolId::ETHERTYPE_NOT_SET),
+ next_proto(pr), ttl(t) {}
+
+THREAD_LOCAL bool TimeProfilerStats::enabled = false;
+THREAD_LOCAL const Trace* decode_trace = nullptr;
+std::array<uint8_t, num_protocol_ids> CodecManager::s_proto_map {
+ { 0 }
+};
+
+THREAD_LOCAL ProtocolId CodecManager::grinder_id = ProtocolId::ETHERTYPE_NOT_SET;
+THREAD_LOCAL uint8_t CodecManager::grinder = 0;
+
+//-----------------------------
+// Mocks
+//-----------------------------
+class MockCodec : public Codec
+{
+public:
+ MockCodec() : Codec("mock_codec") { }
+
+ bool decode(const RawData& raw, CodecData& codec_data, DecodeData&) override
+ {
+ codec_data.lyr_len = raw.len +1;
+ codec_data.next_prot_id = ProtocolId::FINISHED_DECODE;
+ return true;
+ }
+};
+
+MockCodec mock_cd;
+std::array<Codec*, UINT8_MAX> CodecManager::s_protocols { { &mock_cd } };
+THREAD_LOCAL uint8_t CodecManager::max_layers = 1;
+
+//-----------------------------
+// Test
+//-----------------------------
+
+TEST_GROUP(decode_err_len_tests)
+{
+};
+
+TEST(decode_err_len_tests, layer_len_more_than_raw)
+{
+ Packet p(false);
+ p.context = new IpsContext();
+ _daq_msg msg;
+ memset(&msg, 0, sizeof(_daq_msg));
+ p.daq_msg = &msg;
+ PacketManager::decode(&p, nullptr, nullptr, 10, false);
+ CHECK_TRUE((p.ptrs.decode_flags & DECODE_ERR_LEN) != 0);
+ delete p.context;
+}
+
+int main(int argc, char** argv)
+{
+ return CommandLineTestRunner::RunAllTests(argc, argv);
+}