From: Jason Ish Date: Wed, 13 Aug 2014 22:53:19 +0000 (-0600) Subject: Set decoder events for labels that shouldn't be seen on the wire. X-Git-Tag: suricata-2.1beta2~70 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=348b0e0e9f1036dc3c488c18192a40905056edf8;p=thirdparty%2Fsuricata.git Set decoder events for labels that shouldn't be seen on the wire. Add unit tests to test for mpls decoder events. --- diff --git a/rules/decoder-events.rules b/rules/decoder-events.rules index 5d77928283..6fbcdb74af 100644 --- a/rules/decoder-events.rules +++ b/rules/decoder-events.rules @@ -116,5 +116,10 @@ alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 invalid protocol"; d alert pkthdr any any -> any any (msg:"SURICATA IPv6-in-IPv6 packet too short"; decode-event:ipv6.ipv6_in_ipv6_too_small; sid:2200084; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA IPv6-in-IPv6 invalid protocol"; decode-event:ipv6.ipv6_in_ipv6_wrong_version; sid:2200085; rev:1;) -# next sid is 2200098 +# MPLS rules +alert pkthdr any any -> any any (msg:"SURICATA MPLS bad router alert label"; mpls.bad_label_router_alert; sid: 2200098; rev:1;) +alert pkthdr any any -> any any (msg:"SURICATA MPLS bad implicit null label"; mpls.bad_label_implicit_null; sid: 2200099; rev:1;) +alert pkthdr any any -> any any (msg:"SURICATA MPLS reserved label"; mpls.bad_label_reserved; sid: 2200100; rev:1;) + +# next sid is 2200101 diff --git a/src/decode-events.h b/src/decode-events.h index 3080764621..d9a1d5a680 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -228,6 +228,11 @@ enum { IPV6_IN_IPV6_PKT_TOO_SMALL, IPV6_IN_IPV6_WRONG_IP_VER, + /* MPLS decode events. */ + MPLS_BAD_LABEL_ROUTER_ALERT, + MPLS_BAD_LABEL_IMPLICIT_NULL, + MPLS_BAD_LABEL_RESERVED, + /* should always be last! */ DECODE_EVENT_MAX, }; diff --git a/src/decode-mpls.c b/src/decode-mpls.c index e8edb25fad..7ffc5d1d87 100644 --- a/src/decode-mpls.c +++ b/src/decode-mpls.c @@ -25,12 +25,17 @@ #include "suricata-common.h" #include "decode.h" +#include "util-unittest.h" #define MPLS_HEADER_LEN 4 #define MPLS_PW_LEN 4 #define MPLS_MAX_RESERVED_LABEL 15 + #define MPLS_LABEL_IPV4 0 +#define MPLS_LABEL_ROUTER_ALERT 1 #define MPLS_LABEL_IPV6 2 +#define MPLS_LABEL_NULL 3 + #define MPLS_LABEL(shim) ntohl(shim) >> 12 #define MPLS_BOTTOM(shim) ((ntohl(shim) >> 8) & 0x1) @@ -44,6 +49,7 @@ int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, { uint32_t shim; int label; + int event = 0; SCPerfCounterIncr(dtv->counter_mpls, tv->sc_perf_pca); @@ -60,11 +66,24 @@ int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, if (label == MPLS_LABEL_IPV4) { return DecodeIPV4(tv, dtv, p, pkt, len, pq); } + else if (label == MPLS_LABEL_ROUTER_ALERT) { + /* Not valid at the bottom of the stack. */ + event = MPLS_BAD_LABEL_ROUTER_ALERT; + } else if (label == MPLS_LABEL_IPV6) { return DecodeIPV6(tv, dtv, p, pkt, len, pq); } + else if (label == MPLS_LABEL_NULL) { + /* Shouldn't appear on the wire. */ + event = MPLS_BAD_LABEL_IMPLICIT_NULL; + } else if (label < MPLS_MAX_RESERVED_LABEL) { - return TM_ECODE_FAILED; + event = MPLS_BAD_LABEL_RESERVED; + } + + if (event) { + ENGINE_SET_EVENT(p, event); + return TM_ECODE_OK; } /* Best guess at inner packet. */ @@ -88,3 +107,139 @@ int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, return TM_ECODE_OK; } + +#ifdef UNITTESTS + +static int DecodeMPLSTestBadLabelRouterAlert(void) +{ + int ret = 1; + uint8_t pkt[] = { + 0x00, 0x00, 0x11, 0xff, 0x45, 0x00, 0x00, 0x64, + 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, + 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, + 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd + }; + + 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); + + DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); + + if (!ENGINE_ISSET_EVENT(p, MPLS_BAD_LABEL_ROUTER_ALERT)) { + ret = 0; + } + + SCFree(p); + return ret; +} + +static int DecodeMPLSTestBadLabelImplicitNull(void) +{ + int ret = 1; + uint8_t pkt[] = { + 0x00, 0x00, 0x31, 0xff, 0x45, 0x00, 0x00, 0x64, + 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, + 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, + 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd + }; + + 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); + + DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); + + if (!ENGINE_ISSET_EVENT(p, MPLS_BAD_LABEL_IMPLICIT_NULL)) { + ret = 0; + } + + SCFree(p); + return ret; +} + +static int DecodeMPLSTestBadLabelReserved(void) +{ + int ret = 1; + uint8_t pkt[] = { + 0x00, 0x00, 0x51, 0xff, 0x45, 0x00, 0x00, 0x64, + 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, + 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, + 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, + 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd + }; + + 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); + + DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); + + if (!ENGINE_ISSET_EVENT(p, MPLS_BAD_LABEL_RESERVED)) { + ret = 0; + } + + SCFree(p); + return ret; +} + +#endif /* UNITTESTS */ + +void DecodeMPLSRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DecodeMPLSTestBadLabelRouterAlert", + DecodeMPLSTestBadLabelRouterAlert, 1); + UtRegisterTest("DecodeMPLSTestBadLabelImplicitNull", + DecodeMPLSTestBadLabelImplicitNull, 1); + UtRegisterTest("DecodeMPLSTestBadLabelReserved", + DecodeMPLSTestBadLabelReserved, 1); +#endif /* UNITTESTS */ +} diff --git a/src/decode-mpls.h b/src/decode-mpls.h index 0f2ad323c2..c701d3df21 100644 --- a/src/decode-mpls.h +++ b/src/decode-mpls.h @@ -29,4 +29,6 @@ #define ETHERNET_TYPE_MPLS_UNICAST 0x8847 #define ETHERNET_TYPE_MPLS_MULTICAST 0x8848 +void DecodeMPLSRegisterTests(void); + #endif /* !__DECODE_MPLS_H__ */ diff --git a/src/detect-engine-event.h b/src/detect-engine-event.h index fb6089b92a..2fecc8769b 100644 --- a/src/detect-engine-event.h +++ b/src/detect-engine-event.h @@ -232,6 +232,11 @@ struct DetectEngineEvents_ { { "ipv6.ipv6_in_ipv6_too_small", IPV6_IN_IPV6_PKT_TOO_SMALL, }, { "ipv6.ipv6_in_ipv6_wrong_version", IPV6_IN_IPV6_WRONG_IP_VER, }, + /* MPLS events */ + { "mpls.bad_label_router_alert", MPLS_BAD_LABEL_ROUTER_ALERT, }, + { "mpls.bad_label_implicit_null", MPLS_BAD_LABEL_IMPLICIT_NULL, }, + { "mpls.bad_label_reserved", MPLS_BAD_LABEL_RESERVED, }, + { NULL, 0 }, }; #endif /* DETECT_EVENTS */ diff --git a/src/runmode-unittests.c b/src/runmode-unittests.c index ef808f24e1..479e1323d4 100644 --- a/src/runmode-unittests.c +++ b/src/runmode-unittests.c @@ -206,6 +206,7 @@ void RunUnittests(int list_unittests, char *regex_arg) DecodeUDPV4RegisterTests(); DecodeGRERegisterTests(); DecodeAsn1RegisterTests(); + DecodeMPLSRegisterTests(); AppLayerProtoDetectUnittestsRegister(); ConfRegisterTests(); ConfYamlRegisterTests();