#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)
{
uint32_t shim;
int label;
+ int event = 0;
SCPerfCounterIncr(dtv->counter_mpls, tv->sc_perf_pca);
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. */
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 */
+}