]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode: add ERSPANv1 decoder
authorVictor Julien <victor@inliniac.net>
Wed, 20 May 2015 21:01:22 +0000 (23:01 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 10 Jun 2015 10:35:46 +0000 (12:35 +0200)
Only allow v1 to be parsed as thats what is tested.

Take vlan_id from the ERSPAN layer.

rules/decoder-events.rules
src/Makefile.am
src/decode-erspan.c [new file with mode: 0644]
src/decode-erspan.h [new file with mode: 0644]
src/decode-ethernet.h
src/decode-events.h
src/decode-gre.c
src/decode.c
src/decode.h
src/detect-engine-event.h

index dc74a8160bf1f808a7845af99ff5cc7de41e9941..314c0f9268e7daa5b34c964533105e14c17af9b9 100644 (file)
@@ -128,5 +128,11 @@ alert pkthdr any any -> any any (msg:"SURICATA NULL pkt too small"; decode-event
 # packet has type not supported by Suricata's decoders
 alert pkthdr any any -> any any (msg:"SURICATA NULL unsupported type"; decode-event:ltnull.unsupported_type; sid: 2200104; rev:1;)
 
-# next sid is 2200105
+# ERSPAN
+alert pkthdr any any -> any any (msg:"SURICATA ERSPAN pkt too small"; decode-event:erspan.header_too_small; sid: 2200105; rev:1;)
+# packet has type not supported by Suricata's decoders
+alert pkthdr any any -> any any (msg:"SURICATA ERSPAN unsupported version"; decode-event:erspan.unsupported_version; sid: 2200106; rev:1;)
+alert pkthdr any any -> any any (msg:"SURICATA ERSPAN too many vlan layers"; decode-event:erspan.too_many_vlan_layers; sid: 2200107; rev:1;)
+
+# next sid is 2200108
 
index d682b62cc4f455adc820a5776e0893ae801cb977..819338427761261eb23ddfeac37a945856ce43f9 100644 (file)
@@ -41,6 +41,7 @@ conf-yaml-loader.c conf-yaml-loader.h \
 counters.c counters.h \
 data-queue.c data-queue.h \
 decode.c decode.h \
+decode-erspan.c decode-erspan.h \
 decode-ethernet.c decode-ethernet.h \
 decode-events.c decode-events.h \
 decode-gre.c decode-gre.h \
diff --git a/src/decode-erspan.c b/src/decode-erspan.c
new file mode 100644 (file)
index 0000000..9325f6b
--- /dev/null
@@ -0,0 +1,78 @@
+/* Copyright (C) 2015 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \ingroup decode
+ *
+ * @{
+ */
+
+
+/**
+ * \file
+ *
+ * \author Victor Julien <victor@inliniac.net>
+ *
+ * Decodes ERSPAN
+ */
+
+#include "suricata-common.h"
+#include "suricata.h"
+#include "decode.h"
+#include "decode-events.h"
+#include "decode-erspan.h"
+
+#include "util-unittest.h"
+#include "util-debug.h"
+
+/**
+ * \brief Function to decode ERSPAN packets
+ */
+
+int DecodeERSPAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+{
+    if (len < sizeof(ErspanHdr)) {
+        ENGINE_SET_EVENT(p,ERSPAN_HEADER_TOO_SMALL);
+        return TM_ECODE_FAILED;
+    }
+
+    const ErspanHdr *ehdr = (const ErspanHdr *)pkt;
+    uint16_t version = ntohs(ehdr->ver_vlan) >> 12;
+    uint16_t vlan_id = ntohs(ehdr->ver_vlan) & 0x0fff;
+
+    SCLogDebug("ERSPAN: version %u vlan %u", version, vlan_id);
+
+    /* only v1 is tested at this time */
+    if (version != 1) {
+        ENGINE_SET_EVENT(p,ERSPAN_UNSUPPORTED_VERSION);
+        return TM_ECODE_FAILED;
+    }
+
+    if (vlan_id > 0) {
+        if (p->vlan_idx >= 2) {
+            ENGINE_SET_EVENT(p,ERSPAN_TOO_MANY_VLAN_LAYERS);
+            return TM_ECODE_FAILED;
+        }
+        p->vlan_id[p->vlan_idx++] = vlan_id;
+    }
+
+    return DecodeEthernet(tv, dtv, p, pkt + sizeof(ErspanHdr), len - sizeof(ErspanHdr), pq);
+}
+
+/**
+ * @}
+ */
diff --git a/src/decode-erspan.h b/src/decode-erspan.h
new file mode 100644 (file)
index 0000000..2f81d1e
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (C) 2007-2010 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Victor Julien <victor@inliniac.net>
+ *
+ */
+
+#ifndef __DECODE_ERSPAN_H__
+#define __DECODE_ERSPAN_H__
+
+#include "decode.h"
+#include "threadvars.h"
+
+typedef struct ErspanHdr_ {
+    uint16_t ver_vlan;
+    uint16_t flags_spanid;
+    uint32_t padding;
+} __attribute__((__packed__)) ErspanHdr;
+
+#endif /* __DECODE_ERSPAN_H__ */
index 2a6f86e936a4ea1298fd31320d324d1fc26aca85..f8ede8803ffc68e18d16fea87f79d2abf7e50653 100644 (file)
@@ -40,6 +40,7 @@
 #define ETHERNET_TYPE_8021Q           0x8100
 #define ETHERNET_TYPE_LOOP            0x9000
 #define ETHERNET_TYPE_8021QINQ        0x9100
+#define ETHERNET_TYPE_ERSPAN          0x88BE
 
 typedef struct EthernetHdr_ {
     uint8_t eth_dst[6];
index 7ad23d9f7259b8ec4b3020901bff7dbc2983841d..c16d0d92d6a17f2461343501c1d2bffc996fc13d 100644 (file)
@@ -240,6 +240,11 @@ enum {
     MPLS_BAD_LABEL_RESERVED,
     MPLS_UNKNOWN_PAYLOAD_TYPE,
 
+    /* ERSPAN events */
+    ERSPAN_HEADER_TOO_SMALL,
+    ERSPAN_UNSUPPORTED_VERSION,
+    ERSPAN_TOO_MANY_VLAN_LAYERS,
+
     /* should always be last! */
     DECODE_EVENT_MAX,
 };
index f827cabe8815877705f2a6b57c18b486f3a51f0b..6ad9e39758d80b6305ca19aeb13f64de9b605ead 100644 (file)
@@ -249,6 +249,19 @@ int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
                 break;
             }
 
+        case ETHERNET_TYPE_ERSPAN:
+        {
+            if (pq != NULL) {
+                Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
+                        len - header_len, DECODE_TUNNEL_ERSPAN, pq);
+                if (tp != NULL) {
+                    PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
+                    PacketEnqueue(pq,tp);
+                }
+            }
+            break;
+        }
+
         default:
             return TM_ECODE_OK;
     }
index ca96ee0adf88dd1c3140091d4ffee0026b704961..49896d8efcd2e8ad64621ebdc30f78e81fb43429 100644 (file)
@@ -80,6 +80,8 @@ int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
             return DecodeVLAN(tv, dtv, p, pkt, len, pq);
         case DECODE_TUNNEL_ETHERNET:
             return DecodeEthernet(tv, dtv, p, pkt, len, pq);
+        case DECODE_TUNNEL_ERSPAN:
+            return DecodeERSPAN(tv, dtv, p, pkt, len, pq);
         default:
             SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
             break;
index 830b3b360a1c932479fbb5094d3d066602b936f5..1c02a3ede90e721b169e2fe113363fcf74c03dd8 100644 (file)
@@ -65,6 +65,7 @@ enum PktSrcEnum {
 
 #include "action-globals.h"
 
+#include "decode-erspan.h"
 #include "decode-ethernet.h"
 #include "decode-gre.h"
 #include "decode-ppp.h"
@@ -831,6 +832,7 @@ typedef struct DecodeThreadVars_
 
 enum DecodeTunnelProto {
     DECODE_TUNNEL_ETHERNET,
+    DECODE_TUNNEL_ERSPAN,
     DECODE_TUNNEL_VLAN,
     DECODE_TUNNEL_IPV4,
     DECODE_TUNNEL_IPV6,
@@ -875,6 +877,7 @@ int DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t,
 int DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
 int DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
 int DecodeMPLS(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeERSPAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
 
 void AddressDebugPrint(Address *);
 
index 5d51d6834d4b514b0f9b1ce9dd97ecbadb6e1b54..9d6424fbdb48f9a37cf4ed48d2421c5772240233 100644 (file)
@@ -243,6 +243,11 @@ struct DetectEngineEvents_ {
     { "mpls.bad_label_reserved", MPLS_BAD_LABEL_RESERVED, },
     { "mpls.unknown_payload_type", MPLS_UNKNOWN_PAYLOAD_TYPE, },
 
+    /* ERSPAN events */
+    { "erspan.header_too_small", ERSPAN_HEADER_TOO_SMALL, },
+    { "erspan.unsupported_version", ERSPAN_UNSUPPORTED_VERSION, },
+    { "erspan.too_many_vlan_layers", ERSPAN_TOO_MANY_VLAN_LAYERS, },
+
     { NULL, 0 },
 };
 #endif /* DETECT_EVENTS */