#include "config.h"
#endif
+#include <iomanip>
+#include <sstream>
+#include <unordered_set>
+#include <vector>
+
#include <daq.h>
#include "codecs/codec_module.h"
{ 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 ? */
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&)
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; }