decode/hdlc: initial support

pull/4802/head
Victor Julien 6 years ago
parent 136d351e40
commit 328a94206e

@ -143,5 +143,8 @@ alert pkthdr any any -> any any (msg:"SURICATA ERSPAN too many vlan layers"; dec
# 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

@ -63,6 +63,7 @@ datasets-string.c datasets-string.h \
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 \

@ -0,0 +1,111 @@
/* 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 */
}
/**
* @}
*/

@ -0,0 +1,37 @@
/* 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__ */

@ -184,6 +184,9 @@ const struct DecodeEvents_ DEvents[] = {
/* 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, },

@ -191,8 +191,11 @@ enum {
/* 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,

@ -483,6 +483,7 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
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);

@ -74,6 +74,7 @@ enum PktSrcEnum {
#include "decode-erspan.h"
#include "decode-ethernet.h"
#include "decode-chdlc.h"
#include "decode-gre.h"
#include "decode-ppp.h"
#include "decode-pppoe.h"
@ -633,6 +634,7 @@ typedef struct DecodeThreadVars_
uint16_t counter_invalid;
uint16_t counter_eth;
uint16_t counter_chdlc;
uint16_t counter_ipv4;
uint16_t counter_ipv6;
uint16_t counter_tcp;
@ -935,6 +937,7 @@ int DecodeVXLAN(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uin
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
@ -1039,6 +1042,10 @@ void DecodeUnregisterCounters(void);
#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__
@ -1064,6 +1071,7 @@ void DecodeUnregisterCounters(void);
#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
@ -1171,6 +1179,9 @@ static inline void DecodeLinkLayer(ThreadVars *tv, DecodeThreadVars *dtv,
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);

@ -146,6 +146,7 @@ static void RegisterUnittests(void)
IPPairBitRegisterTests();
StatsRegisterTests();
DecodeEthernetRegisterTests();
DecodeCHDLCRegisterTests();
DecodePPPRegisterTests();
DecodeVLANRegisterTests();
DecodeVXLANRegisterTests();

@ -253,6 +253,9 @@ TmEcode ValidateLinkType(int datalink, DecoderFunc *DecoderFn)
case LINKTYPE_NULL:
*DecoderFn = DecodeNull;
break;
case LINKTYPE_CISCO_HDLC:
*DecoderFn = DecodeCHDLC;
break;
default:
SCLogError(SC_ERR_UNIMPLEMENTED,

Loading…
Cancel
Save