]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
vlan: add configurable TPIDs
authorruss <rucombs@cisco.com>
Fri, 15 Jul 2022 18:32:18 +0000 (14:32 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Sat, 13 Aug 2022 18:39:07 +0000 (18:39 +0000)
vlan.extra_tpid_ether_types defaults to '0x9100 0x9200'.
Thanks to ozkankirik for reporting the issue.

src/codecs/link/cd_vlan.cc
src/protocols/protocol_ids.h

index ec02b5250e14c338868cb990396fb762051c154b..0162396481fb7ea11d5c6c141ec09536a29b49e6 100644 (file)
 #include "config.h"
 #endif
 
+#include <iomanip>
+#include <sstream>
+#include <unordered_set>
+#include <vector>
+
 #include <daq.h>
 
 #include "codecs/codec_module.h"
@@ -41,25 +46,53 @@ static const RuleMap vlan_rules[] =
     { 0, nullptr }
 };
 
+static const char* default_tpids = "0x9100 0x9200";
+
+static const Parameter vlan_params[] =
+{
+    { "extra_tpid_ether_types", Parameter::PT_INT_LIST, "65535", default_tpids,
+      "set non-standard QinQ ether types" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
 class VlanModule : public BaseCodecModule
 {
 public:
-    VlanModule() : BaseCodecModule(CD_VLAN_NAME, CD_VLAN_HELP) { }
+    VlanModule() : BaseCodecModule(CD_VLAN_NAME, CD_VLAN_HELP, vlan_params) { }
+
+    bool set(const char*, Value&, SnortConfig*) override;
 
     const RuleMap* get_rules() const override
     { return vlan_rules; }
+
+    const char* get_tpids() const
+    { return tpids.c_str(); }
+
+private:
+    std::string tpids;
 };
 
+bool VlanModule::set(const char*, Value& v, SnortConfig*)
+{
+    assert(v.is("extra_tpid_ether_types"));
+    tpids = v.get_string();
+    return true;
+}
+
 class VlanCodec : public Codec
 {
 public:
-    VlanCodec() : Codec(CD_VLAN_NAME) { }
+    VlanCodec(const char* s) : Codec(CD_VLAN_NAME)
+    { tpids = s; }
 
     void get_protocol_ids(std::vector<ProtocolId>& v) override;
     bool decode(const RawData&, CodecData&, DecodeData&) override;
     void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
-    bool encode(const uint8_t* const raw_in, const uint16_t raw_len, EncState&, Buffer&,
-        Flow*) override;
+    bool encode(const uint8_t* const raw_in, const uint16_t raw_len, EncState&, Buffer&, Flow*) override;
+
+private:
+    std::string tpids;
 };
 
 constexpr unsigned int ETHERNET_MAX_LEN_ENCAP = 1518;    /* 802.3 (+LLC) or ether II ? */
@@ -67,10 +100,19 @@ constexpr unsigned int ETHERNET_MAX_LEN_ENCAP = 1518;    /* 802.3 (+LLC) or ethe
 
 void VlanCodec::get_protocol_ids(std::vector<ProtocolId>& v)
 {
-    v.emplace_back(ProtocolId::ETHERTYPE_8021Q);
-    v.emplace_back(ProtocolId::ETHERTYPE_8021AD);
-    v.emplace_back(ProtocolId::ETHERTYPE_QINQ_NS1);
-    v.emplace_back(ProtocolId::ETHERTYPE_QINQ_NS2);
+    std::unordered_set<ProtocolId> id_set;
+    id_set.insert(ProtocolId::ETHERTYPE_8021Q);
+    id_set.insert(ProtocolId::ETHERTYPE_8021AD);
+
+    std::stringstream ss(tpids);
+    ss >> std::setbase(0);
+    int val;
+
+    while ( ss >> val )
+        id_set.insert((ProtocolId)val);
+
+    for ( auto id : id_set )
+        v.emplace_back(id);
 }
 
 bool VlanCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
@@ -152,8 +194,11 @@ static Module* mod_ctor()
 static void mod_dtor(Module* m)
 { delete m; }
 
-static Codec* ctor(Module*)
-{ return new VlanCodec(); }
+static Codec* ctor(Module* m)
+{
+    VlanModule* mod = (VlanModule*)m;
+    return new VlanCodec(mod ? mod->get_tpids() : default_tpids);
+}
 
 static void dtor(Codec* cd)
 { delete cd; }
index 12462e731ae92dcf068bcdeab61cd20c38a19096..b9822098133acd308251d1360e9c494c9117c8d9 100644 (file)
@@ -159,8 +159,6 @@ enum class ProtocolId : std::uint16_t
     ETHERTYPE_ERSPAN_TYPE2 = 0x88BE,
     ETHERTYPE_FPATH = 0x8903,
     ETHERTYPE_CISCO_META = 0x8909,
-    ETHERTYPE_QINQ_NS1 = 0x9100,
-    ETHERTYPE_QINQ_NS2 = 0x9200,
 };
 
 static const auto num_protocol_ids =