]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Forgot to add LLC codec file
authorJosh <jrosenba@cisco.com>
Tue, 2 Sep 2014 14:18:37 +0000 (10:18 -0400)
committerJosh <jrosenba@cisco.com>
Tue, 2 Sep 2014 14:18:37 +0000 (10:18 -0400)
src/codecs/misc/cd_llc.cc [new file with mode: 0644]

diff --git a/src/codecs/misc/cd_llc.cc b/src/codecs/misc/cd_llc.cc
new file mode 100644 (file)
index 0000000..5249650
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
+**
+** 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.
+*/
+// cd_llc.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "framework/codec.h"
+#include "codecs/decode_module.h"
+#include "protocols/packet.h"
+#include "framework/module.h"
+#include "codecs/codec_events.h"
+#include "codecs/decode_module.h"
+#include "log/text_log.h"
+#include "protocols/packet_manager.h"
+
+namespace
+{
+
+// yes, macros are necessary. The API and class constructor require different strings.
+//
+// this macros is defined in the module to ensure identical names. However,
+// if you don't want a module, define the name here.
+#define LLC_NAME "llc"
+
+
+
+class LlcCodec : public Codec
+{
+public:
+    LlcCodec() : Codec(LLC_NAME){};
+    ~LlcCodec() {};
+
+
+    virtual bool decode(const uint8_t *raw_pkt, const uint32_t &raw_len,
+        Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
+
+    virtual void log(TextLog*, const uint8_t* /*raw_pkt*/, const Packet* const);
+    virtual void get_protocol_ids(std::vector<uint16_t>&);
+};
+
+
+struct EthLlc
+{
+    uint8_t dsap;
+    uint8_t ssap;
+    uint8_t ctrl;
+};
+
+struct EthLlcOther
+{
+    uint8_t org_code[3];
+    uint16_t proto_id;
+};
+
+const uint8_t UNNUMBERED_INFORMATION = 3;
+#define ETH_DSAP_SNA                  0x08    /* SNA */
+#define ETH_SSAP_SNA                  0x00    /* SNA */
+#define ETH_DSAP_STP                  0x42    /* Spanning Tree Protocol */
+#define ETH_SSAP_STP                  0x42    /* Spanning Tree Protocol */
+#define ETH_DSAP_IP                   0xaa    /* IP */
+#define ETH_SSAP_IP                   0xaa    /* IP */
+
+#define ETH_ORG_CODE_ETHR              0x000000    /* Encapsulated Ethernet */
+#define ETH_ORG_CODE_CDP               0x00000c    /* Cisco Discovery Proto */
+
+} // namespace
+
+
+void LlcCodec::get_protocol_ids(std::vector<uint16_t>& v)
+{
+    v.push_back(ETHERNET_LLC);
+}
+
+bool LlcCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
+        Packet* p, uint16_t& lyr_len, uint16_t& next_prot_id)
+{
+    if(raw_len < sizeof(EthLlc))
+    {
+        // FIXIT-L - J - Need a better alert
+        codec_events::decoder_event(p, DECODE_BAD_VLAN_ETHLLC);
+        return false;
+    }
+
+     const EthLlc *ehllc = reinterpret_cast<const EthLlc *>(raw_pkt);
+
+
+
+    if(ehllc->dsap == ETH_DSAP_IP &&
+        ehllc->ssap == ETH_SSAP_IP &&
+        ehllc->ctrl == UNNUMBERED_INFORMATION)
+    {
+        if (raw_len <  sizeof(EthLlc) + sizeof(EthLlcOther))
+        {
+            codec_events::decoder_event(p, DECODE_BAD_VLAN_ETHLLC);
+            return false;
+        }
+
+        const EthLlcOther *ehllcother = reinterpret_cast<const EthLlcOther *>(raw_pkt + sizeof(EthLlc));
+
+        if (ehllcother->org_code[0] == 0 &&
+            ehllcother->org_code[1] == 0 &&
+            ehllcother->org_code[2] == 0)
+        {
+            lyr_len = sizeof(EthLlc) + sizeof(EthLlcOther);
+            next_prot_id = ntohs(ehllcother->proto_id);
+        }
+    }
+
+
+    return true;
+}
+
+void LlcCodec::log(TextLog* text_log, const uint8_t* raw_pkt,
+    const Packet* const)
+{
+    const EthLlc *ehllc = reinterpret_cast<const EthLlc *>(raw_pkt);
+
+    TextLog_Print(text_log, "LLC  DSAP:0x%X SSAP:0x%X CTRL:0x%X",
+        ehllc->dsap, ehllc->ssap, ehllc->ctrl);
+
+    // Assuming that if these three conditions are met, this is SNAP.
+    if(ehllc->dsap == ETH_DSAP_IP &&
+        ehllc->ssap == ETH_SSAP_IP &&
+        ehllc->ctrl == UNNUMBERED_INFORMATION)
+    {
+
+        const EthLlcOther *other = reinterpret_cast<const EthLlcOther *>(raw_pkt + sizeof(EthLlc));
+        const uint16_t proto = ntohs(other->proto_id);
+
+        TextLog_Print(text_log, " ORG:0x%02X%02X%02X PROTO:0x%s(%04X)",
+            other->org_code[0], other->org_code[1], other->org_code[2],
+            PacketManager::get_proto_name(proto), proto);
+    }
+}
+
+
+//-------------------------------------------------------------------------
+// api
+//-------------------------------------------------------------------------
+
+static Codec* ctor(Module*)
+{ return new LlcCodec(); }
+
+static void dtor(Codec *cd)
+{ delete cd; }
+
+
+static const CodecApi llc_api =
+{
+    {
+        PT_CODEC,
+        LLC_NAME,
+        CDAPI_PLUGIN_V0,
+        0,
+        nullptr,
+        nullptr
+    },
+    nullptr,
+    nullptr,
+    nullptr,
+    nullptr,
+    ctor,
+    dtor,
+};
+
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &llc_api.base,
+    nullptr
+};
+#else
+const BaseApi* cd_llc = &llc_api.base;
+#endif