]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Set decoder events for labels that shouldn't be seen on the wire.
authorJason Ish <jason.ish@emulex.com>
Wed, 13 Aug 2014 22:53:19 +0000 (16:53 -0600)
committerJason Ish <jason.ish@emulex.com>
Mon, 20 Oct 2014 21:15:05 +0000 (15:15 -0600)
Add unit tests to test for mpls decoder events.

rules/decoder-events.rules
src/decode-events.h
src/decode-mpls.c
src/decode-mpls.h
src/detect-engine-event.h
src/runmode-unittests.c

index 5d77928283112ae7476e82fd2c0589905dedcdb8..6fbcdb74af866aa38844313350b9dd10436ef66c 100644 (file)
@@ -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
 
index 3080764621ef7a7aad65d13d06cdf3add0e52c73..d9a1d5a680e1dc83815c0045012ed962ff52dcdd 100644 (file)
@@ -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,
 };
index e8edb25fad511a79d30af6e590db7f1c01560dce..7ffc5d1d878fea093669183e0b0c6be478df7507 100644 (file)
 
 #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 */
+}
index 0f2ad323c243f43e1477bf22d901144e74ee0d5b..c701d3df210236b8478dda616ed74d752eeb51cb 100644 (file)
@@ -29,4 +29,6 @@
 #define ETHERNET_TYPE_MPLS_UNICAST   0x8847
 #define ETHERNET_TYPE_MPLS_MULTICAST 0x8848
 
+void DecodeMPLSRegisterTests(void);
+
 #endif /* !__DECODE_MPLS_H__ */
index fb6089b92ac13a629a943344b604e89d41b638bc..2fecc8769b49d9b819b281032ef82087790614fa 100644 (file)
@@ -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 */
index ef808f24e1d0553b07a8b326d0486d5edd5e1744..479e1323d4792360b41a87c30679bbd26fcdb1c3 100644 (file)
@@ -206,6 +206,7 @@ void RunUnittests(int list_unittests, char *regex_arg)
     DecodeUDPV4RegisterTests();
     DecodeGRERegisterTests();
     DecodeAsn1RegisterTests();
+    DecodeMPLSRegisterTests();
     AppLayerProtoDetectUnittestsRegister();
     ConfRegisterTests();
     ConfYamlRegisterTests();