Only allow v1 to be parsed as thats what is tested.
Take vlan_id from the ERSPAN layer.
# 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
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 \
--- /dev/null
+/* 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);
+}
+
+/**
+ * @}
+ */
--- /dev/null
+/* 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__ */
#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];
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,
};
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;
}
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;
#include "action-globals.h"
+#include "decode-erspan.h"
#include "decode-ethernet.h"
#include "decode-gre.h"
#include "decode-ppp.h"
enum DecodeTunnelProto {
DECODE_TUNNEL_ETHERNET,
+ DECODE_TUNNEL_ERSPAN,
DECODE_TUNNEL_VLAN,
DECODE_TUNNEL_IPV4,
DECODE_TUNNEL_IPV6,
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 *);
{ "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 */