From: russ Date: Fri, 15 Jul 2022 18:32:18 +0000 (-0400) Subject: vlan: add configurable TPIDs X-Git-Tag: 3.1.40.0~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc77923a7fab0d0b726a038a13c7e61ff0bfa1f8;p=thirdparty%2Fsnort3.git vlan: add configurable TPIDs vlan.extra_tpid_ether_types defaults to '0x9100 0x9200'. Thanks to ozkankirik for reporting the issue. --- diff --git a/src/codecs/link/cd_vlan.cc b/src/codecs/link/cd_vlan.cc index ec02b5250..016239648 100644 --- a/src/codecs/link/cd_vlan.cc +++ b/src/codecs/link/cd_vlan.cc @@ -21,6 +21,11 @@ #include "config.h" #endif +#include +#include +#include +#include + #include #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& 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& 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 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; } diff --git a/src/protocols/protocol_ids.h b/src/protocols/protocol_ids.h index 12462e731..b98220981 100644 --- a/src/protocols/protocol_ids.h +++ b/src/protocols/protocol_ids.h @@ -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 =