# Cisco Fabric Path/DCE
alert pkthdr any any -> any any (msg:"SURICATA DCE packet too small"; decode-event:dce.pkt_too_small; classtype:protocol-command-decode; sid:2200110; rev:2;)
-# next sid is 2200114
+# Cisco HDLC
+alert pkthdr any any -> any any (msg:"SURICATA CHDLC packet too small"; decode-event:chdlc.pkt_too_small; classtype:protocol-command-decode; sid:2200115; rev:1;)
+
+# next sid is 2200116
datasets-sha256.c datasets-sha256.h \
datasets-md5.c datasets-md5.h \
decode.c decode.h \
+decode-chdlc.c decode-chdlc.h \
decode-erspan.c decode-erspan.h \
decode-ethernet.c decode-ethernet.h \
decode-events.c decode-events.h \
--- /dev/null
+/* Copyright (C) 2020 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>
+ *
+ * Decode Cisco HDLC
+ */
+
+#include "suricata-common.h"
+#include "decode.h"
+#include "decode-chdlc.h"
+#include "decode-events.h"
+
+#include "util-unittest.h"
+#include "util-debug.h"
+
+int DecodeCHDLC(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
+ const uint8_t *pkt, uint32_t len)
+{
+ StatsIncr(tv, dtv->counter_chdlc);
+
+ if (unlikely(len < CHDLC_HEADER_LEN)) {
+ ENGINE_SET_INVALID_EVENT(p, CHDLC_PKT_TOO_SMALL);
+ return TM_ECODE_FAILED;
+ }
+
+ if (unlikely(len > CHDLC_HEADER_LEN + USHRT_MAX)) {
+ return TM_ECODE_FAILED;
+ }
+
+ CHDLCHdr *hdr = (CHDLCHdr *)pkt;
+ if (unlikely(hdr == NULL))
+ return TM_ECODE_FAILED;
+
+ SCLogDebug("p %p pkt %p ether type %04x", p, pkt, SCNtohs(hdr->protocol));
+
+ DecodeNetworkLayer(tv, dtv, SCNtohs(hdr->protocol), p,
+ pkt + CHDLC_HEADER_LEN, len - CHDLC_HEADER_LEN);
+
+ return TM_ECODE_OK;
+}
+
+#ifdef UNITTESTS
+static int DecodeCHDLCTest01 (void)
+{
+ uint8_t raw[] = { 0x0f,0x00,0x08,0x00, // HDLC
+ 0x45,0x00,0x00,0x30,0x15,0x5a,0x40,0x00,0x80,0x06,
+ 0x6c,0xd0,0xc0,0xa8,0x02,0x07,0x41,0x37,0x74,0xb7,
+ 0x13,0x4a,0x00,0x50,0x9c,0x34,0x09,0x6c,0x00,0x00,
+ 0x00,0x00,0x70,0x02,0x40,0x00,0x11,0x47,0x00,0x00,
+ 0x02,0x04,0x05,0xb4,0x01,0x01,0x04,0x02 };
+
+ Packet *p = SCMalloc(SIZE_OF_PACKET);
+ if (unlikely(p == NULL))
+ return 0;
+ ThreadVars tv;
+ DecodeThreadVars dtv;
+
+ memset(&dtv, 0, sizeof(DecodeThreadVars));
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(p, 0, SIZE_OF_PACKET);
+
+ DecodeCHDLC(&tv, &dtv, p, raw, sizeof(raw));
+
+ FAIL_IF_NOT(PKT_IS_IPV4(p));
+ FAIL_IF_NOT(PKT_IS_TCP(p));
+ FAIL_IF_NOT(p->dp == 80);
+
+ SCFree(p);
+ PASS;
+}
+#endif /* UNITTESTS */
+
+
+/**
+ * \brief Registers Ethernet unit tests
+ * \todo More Ethernet tests
+ */
+void DecodeCHDLCRegisterTests(void)
+{
+#ifdef UNITTESTS
+ UtRegisterTest("DecodeCHDLCTest01", DecodeCHDLCTest01);
+#endif /* UNITTESTS */
+}
+/**
+ * @}
+ */
--- /dev/null
+/* Copyright (C) 2020 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_CHDLC_H__
+#define __DECODE_CHDLC_H__
+
+#define CHDLC_HEADER_LEN 4
+
+typedef struct CHDLCHdr_ {
+ uint8_t address;
+ uint8_t control;
+ uint16_t protocol;
+} CHDLCHdr;
+
+void DecodeCHDLCRegisterTests(void);
+
+#endif /* __DECODE_CHDLC_H__ */
/* Cisco Fabric Path/DCE events. */
{ "decoder.dce.pkt_too_small", DCE_PKT_TOO_SMALL, },
+ /* Cisco HDLC events. */
+ { "decoder.chdlc.pkt_too_small", CHDLC_PKT_TOO_SMALL, },
+
/* STREAM EVENTS */
{ "stream.3whs_ack_in_wrong_dir", STREAM_3WHS_ACK_IN_WRONG_DIR, },
{ "stream.3whs_async_wrong_seq", STREAM_3WHS_ASYNC_WRONG_SEQ, },
/* Cisco Fabric Path/DCE events. */
DCE_PKT_TOO_SMALL,
+ /* Cisco HDLC events. */
+ CHDLC_PKT_TOO_SMALL,
+
/* END OF DECODE EVENTS ON SINGLE PACKET */
- DECODE_EVENT_PACKET_MAX = DCE_PKT_TOO_SMALL,
+ DECODE_EVENT_PACKET_MAX = CHDLC_PKT_TOO_SMALL,
/* STREAM EVENTS */
STREAM_3WHS_ACK_IN_WRONG_DIR,
dtv->counter_ipv4 = StatsRegisterCounter("decoder.ipv4", tv);
dtv->counter_ipv6 = StatsRegisterCounter("decoder.ipv6", tv);
dtv->counter_eth = StatsRegisterCounter("decoder.ethernet", tv);
+ dtv->counter_chdlc = StatsRegisterCounter("decoder.chdlc", tv);
dtv->counter_raw = StatsRegisterCounter("decoder.raw", tv);
dtv->counter_null = StatsRegisterCounter("decoder.null", tv);
dtv->counter_sll = StatsRegisterCounter("decoder.sll", tv);
#include "decode-erspan.h"
#include "decode-ethernet.h"
+#include "decode-chdlc.h"
#include "decode-gre.h"
#include "decode-ppp.h"
#include "decode-pppoe.h"
uint16_t counter_invalid;
uint16_t counter_eth;
+ uint16_t counter_chdlc;
uint16_t counter_ipv4;
uint16_t counter_ipv6;
uint16_t counter_tcp;
int DecodeMPLS(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
int DecodeERSPAN(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
int DecodeERSPANTypeI(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
+int DecodeCHDLC(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
int DecodeTEMPLATE(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
#ifdef UNITTESTS
#define DLT_EN10MB 1
#endif
+#ifndef DLT_C_HDLC
+#define DLT_C_HDLC 104
+#endif
+
/* taken from pcap's bpf.h */
#ifndef DLT_RAW
#ifdef __OpenBSD__
#define LINKTYPE_RAW2 101
#define LINKTYPE_IPV4 228
#define LINKTYPE_GRE_OVER_IP 778
+#define LINKTYPE_CISCO_HDLC DLT_C_HDLC
#define PPP_OVER_GRE 11
#define VLAN_OVER_GRE 13
case LINKTYPE_NULL:
DecodeNull(tv, dtv, p, data, len);
break;
+ case LINKTYPE_CISCO_HDLC:
+ DecodeCHDLC(tv, dtv, p, data, len);
+ break;
default:
SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "datalink type "
"%"PRId32" not yet supported", datalink);
IPPairBitRegisterTests();
StatsRegisterTests();
DecodeEthernetRegisterTests();
+ DecodeCHDLCRegisterTests();
DecodePPPRegisterTests();
DecodeVLANRegisterTests();
DecodeVXLANRegisterTests();
case LINKTYPE_NULL:
*DecoderFn = DecodeNull;
break;
+ case LINKTYPE_CISCO_HDLC:
+ *DecoderFn = DecodeCHDLC;
+ break;
default:
SCLogError(SC_ERR_UNIMPLEMENTED,