60 #define DETECT_BYTEMATH_ENDIAN_DEFAULT (uint8_t) BigEndian
61 #define DETECT_BYTEMATH_BASE_DEFAULT (uint8_t) BaseDec
63 static void DetectByteMathRegisterTests(
void);
83 static inline bool DetectByteMathValidateNbytesOnly(
const DetectByteMathData *data, int32_t nbytes)
86 (((data->flags & DETECT_BYTEMATH_FLAG_STRING) && nbytes <= 10) || (nbytes <= 4));
91 uint64_t rvalue, uint64_t *value, uint8_t endian)
97 if (!DetectByteMathValidateNbytesOnly(data, nbytes)) {
109 if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
110 SCLogDebug(
"relative, working with det_ctx->buffer_offset %" PRIu32
", "
111 "data->offset %" PRIi32
"",
125 SCLogDebug(
"absolute, data->offset %" PRIi32
"", data->offset);
127 ptr = payload + data->offset;
132 if (ptr < payload || nbytes >
len) {
133 SCLogDebug(
"Data not within payload pkt=%p, ptr=%p, len=%" PRIu32
", nbytes=%d", payload,
139 if (data->flags & DETECT_BYTEMATH_FLAG_STRING) {
146 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
151 ByteEndian bme = endian;
154 if (extbytes != nbytes) {
155 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
164 switch (data->oper) {
201 if (data->flags & DETECT_BYTEMATH_FLAG_BITMASK) {
202 val &= data->bitmask_val;
203 if (val && data->bitmask_shift_count) {
204 val = val >> data->bitmask_shift_count;
223 static DetectByteMathData *DetectByteMathParse(
226 DetectByteMathData *bmd;
227 if ((bmd = SCByteMathParse(arg)) == NULL) {
232 if (bmd->nbytes_str) {
233 if (nbytes == NULL) {
235 "var name for nbytes. \"nbytes\" argument supplied to "
236 "this function must be non-NULL");
239 *nbytes =
SCStrdup(bmd->nbytes_str);
240 if (*nbytes == NULL) {
245 if (bmd->rvalue_str) {
246 if (rvalue == NULL) {
248 "var name for rvalue. \"rvalue\" argument supplied to "
249 "this function must be non-NULL");
252 *rvalue =
SCStrdup(bmd->rvalue_str);
253 if (*rvalue == NULL) {
258 if (bmd->flags & DETECT_BYTEMATH_FLAG_BITMASK) {
259 if (bmd->bitmask_val) {
260 uint32_t bmask = bmd->bitmask_val;
261 while (!(bmask & 0x1)){
263 bmd->bitmask_shift_count++;
272 DetectByteMathFree(
de_ctx, bmd);
290 DetectByteMathData *data;
295 data = DetectByteMathParse(
de_ctx, arg, &nbytes, &rvalue);
306 if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
310 "previous pattern match");
314 }
else if (data->endian == EndianDCE) {
315 if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
318 if (prev_pm == NULL) {
332 }
else if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
335 if (prev_pm == NULL) {
347 if (data->endian == EndianDCE) {
351 if ((data->flags & DETECT_BYTEMATH_FLAG_STRING) || (data->base == BaseDec) ||
352 (data->base == BaseHex) || (data->base == BaseOct)) {
354 "A bytemath keyword with dce holds other invalid modifiers.");
359 if (nbytes != NULL) {
362 SCLogError(
"unknown byte_ keyword var seen in byte_math - %s", nbytes);
365 data->nbytes = index;
366 data->flags |= DETECT_BYTEMATH_FLAG_NBYTES_VAR;
371 if (rvalue != NULL) {
374 SCLogError(
"unknown byte_ keyword var seen in byte_math - %s", rvalue);
377 data->rvalue = index;
378 data->flags |= DETECT_BYTEMATH_FLAG_RVALUE_VAR;
385 if (prev_bmd_sm == NULL) {
388 data->local_id = ((DetectByteMathData *)prev_bmd_sm->
ctx)->local_id + 1;
399 if (!(data->flags & DETECT_BYTEMATH_FLAG_RELATIVE))
421 DetectByteMathFree(
de_ctx, data);
449 const DetectByteMathData *bmd = (
const DetectByteMathData *)sm->
ctx;
450 if (strcmp(bmd->result, arg) == 0) {
464 const DetectByteMathData *bmd = (
const DetectByteMathData *)sm->
ctx;
465 if (strcmp(bmd->result, arg) == 0) {
481 static int DetectByteMathParseTest01(
void)
484 DetectByteMathData *bmd = DetectByteMathParse(NULL,
485 "bytes 4, offset 2, oper +,"
486 "rvalue 10, result bar",
498 DetectByteMathFree(NULL, bmd);
503 static int DetectByteMathParseTest02(
void)
506 DetectByteMathData *bmd = DetectByteMathParse(NULL,
507 "bytes 257, offset 2, oper +, "
508 "rvalue 39, result bar",
516 static int DetectByteMathParseTest03(
void)
519 DetectByteMathData *bmd = DetectByteMathParse(NULL,
520 "bytes 11, offset 2, oper +, "
521 "rvalue 39, result bar",
528 static int DetectByteMathParseTest04(
void)
531 DetectByteMathData *bmd = DetectByteMathParse(NULL,
532 "bytes 4, offset 70000, oper +,"
533 " rvalue 39, result bar",
541 static int DetectByteMathParseTest05(
void)
544 DetectByteMathData *bmd = DetectByteMathParse(NULL,
545 "bytes 11, offset 16, oper &,"
546 "rvalue 39, result bar",
553 static int DetectByteMathParseTest06(
void)
555 uint8_t
flags = DETECT_BYTEMATH_FLAG_RELATIVE;
558 DetectByteMathData *bmd = DetectByteMathParse(NULL,
559 "bytes 4, offset 0, oper +,"
560 "rvalue 248, result var, relative",
573 DetectByteMathFree(NULL, bmd);
578 static int DetectByteMathParseTest07(
void)
582 DetectByteMathData *bmd = DetectByteMathParse(NULL,
583 "bytes 4, offset 2, oper +,"
584 "rvalue foo, result bar",
595 DetectByteMathFree(NULL, bmd);
602 static int DetectByteMathParseTest08(
void)
605 DetectByteMathData *bmd = DetectByteMathParse(NULL,
606 "bytes 4, offset 2, oper +,"
607 "rvalue foo, result bar",
614 static int DetectByteMathParseTest09(
void)
616 uint8_t
flags = DETECT_BYTEMATH_FLAG_RELATIVE;
618 DetectByteMathData *bmd = DetectByteMathParse(NULL,
619 "bytes 4, offset 2, oper +,"
620 "rvalue 39, result bar, relative",
633 DetectByteMathFree(NULL, bmd);
638 static int DetectByteMathParseTest10(
void)
640 uint8_t
flags = DETECT_BYTEMATH_FLAG_ENDIAN;
642 DetectByteMathData *bmd = DetectByteMathParse(NULL,
643 "bytes 4, offset 2, oper +,"
644 "rvalue 39, result bar, endian"
658 DetectByteMathFree(NULL, bmd);
663 static int DetectByteMathParseTest11(
void)
665 uint8_t
flags = DETECT_BYTEMATH_FLAG_ENDIAN;
667 DetectByteMathData *bmd = DetectByteMathParse(NULL,
668 "bytes 4, offset 2, oper +, "
669 "rvalue 39, result bar, dce",
682 DetectByteMathFree(NULL, bmd);
687 static int DetectByteMathParseTest12(
void)
689 uint8_t
flags = DETECT_BYTEMATH_FLAG_RELATIVE | DETECT_BYTEMATH_FLAG_STRING;
691 DetectByteMathData *bmd = DetectByteMathParse(NULL,
692 "bytes 4, offset 2, oper +,"
693 "rvalue 39, result bar, "
694 "relative, string dec",
707 DetectByteMathFree(NULL, bmd);
712 static int DetectByteMathParseTest13(
void)
714 uint8_t
flags = DETECT_BYTEMATH_FLAG_STRING |
715 DETECT_BYTEMATH_FLAG_RELATIVE |
716 DETECT_BYTEMATH_FLAG_BITMASK;
718 DetectByteMathData *bmd = DetectByteMathParse(NULL,
719 "bytes 4, offset 2, oper +, "
720 "rvalue 39, result bar, "
721 "relative, string dec, bitmask "
737 DetectByteMathFree(NULL, bmd);
743 static int DetectByteMathParseTest14(
void)
746 DetectByteMathData *bmd = DetectByteMathParse(NULL,
747 "bytes 4, offset 2, oper +,"
756 static int DetectByteMathParseTest15(
void)
760 DetectByteMathData *bmd = DetectByteMathParse(NULL,
761 "bytes 4, offset 2, oper +, "
770 static int DetectByteMathParseTest16(
void)
772 uint8_t
flags = DETECT_BYTEMATH_FLAG_STRING | DETECT_BYTEMATH_FLAG_RELATIVE |
773 DETECT_BYTEMATH_FLAG_BITMASK;
775 DetectByteMathData *bmd = DetectByteMathParse(NULL,
776 "bytes 4, offset -2, oper +, "
777 "rvalue 39, result bar, "
778 "relative, string dec, bitmask "
794 DetectByteMathFree(NULL, bmd);
799 static int DetectByteMathPacket01(
void)
801 uint8_t buf[] = { 0x38, 0x35, 0x6d, 0x00, 0x00, 0x01,
802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803 0x00, 0x00, 0x6d, 0x00, 0x01, 0x00 };
805 void *dns_state = NULL;
814 memset(&
f, 0,
sizeof(
Flow));
817 "192.168.1.5",
"192.168.1.1",
845 "(byte_extract: 1, 0, extracted_val, relative;"
846 "byte_math: bytes 1, offset 1, oper +, rvalue extracted_val, result var;"
847 "byte_test: 2, =, var, 13;"
848 "msg:\"Byte extract and byte math with byte test verification\";"
854 "(byte_extract: 1, 0, extracted_val, relative;"
855 "byte_math: bytes 1, offset 1, oper +, rvalue extracted_val, result var;"
856 "byte_test: 2, !=, var, 13;"
857 "msg:\"Byte extract and byte math with byte test verification\";"
866 "(byte_extract: 1, 0, extracted_val, relative;"
867 "byte_math: bytes 1, offset 1, oper +, rvalue extracted_val, result var;"
868 "byte_test: 2, <, var, 15;"
869 "msg:\"Byte extract and byte math with byte test verification\";"
878 STREAM_TOSERVER, buf,
sizeof(buf));
902 static int DetectByteMathPacket02(
void)
904 uint8_t buf[] = { 0x38, 0x35, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
905 0x00, 0x70, 0x00, 0x01, 0x00 };
907 void *dns_state = NULL;
916 memset(&
f, 0,
sizeof(
Flow));
918 p =
UTHBuildPacketReal(buf,
sizeof(buf), IPPROTO_UDP,
"192.168.1.5",
"192.168.1.1", 41424, 53);
945 "alert udp any any -> any any "
946 "(byte_extract: 1, 0, extracted_val, relative;"
947 "byte_math: bytes 1, offset -1, oper +, rvalue extracted_val, result var, relative;"
948 "byte_test: 2, =, var, 13;"
949 "msg:\"Byte extract and byte math with byte test verification\";"
955 "alert udp any any -> any any "
956 "(byte_extract: 1, 0, extracted_val, relative;"
957 "byte_math: bytes 1, offset -1, oper +, rvalue extracted_val, result var, relative;"
958 "byte_test: 2, !=, var, 13;"
959 "msg:\"Byte extract and byte math with byte test verification\";"
968 "alert udp any any -> any any "
969 "(byte_extract: 1, 0, extracted_val, relative;"
970 "byte_math: bytes 1, offset -1, oper +, rvalue extracted_val, result var, relative;"
971 "byte_test: 2, <, var, 15;"
972 "msg:\"Byte extract and byte math with byte test verification\";"
1009 static int DetectByteMathPacket03(
void)
1013 uint8_t buf[] = { 0x40, 0xff, 0x00 };
1020 "(byte_extract: 1, 0, shift;"
1021 "byte_math: bytes 1, offset 1, oper >>, rvalue shift, result "
1023 "byte_test: 1, =, var, 2;"
1033 static int DetectByteMathParseTest17(
void)
1035 DetectByteMathData *bmd = DetectByteMathParse(
1036 NULL,
"bytes 4, offset 2, oper >>, rvalue 64, result foo", NULL, NULL);
1039 bmd = DetectByteMathParse(
1040 NULL,
"bytes 4, offset 2, oper <<, rvalue 64, result foo", NULL, NULL);
1043 bmd = DetectByteMathParse(
1044 NULL,
"bytes 4, offset 2, oper >>, rvalue 63, result foo", NULL, NULL);
1046 DetectByteMathFree(NULL, bmd);
1051 static int DetectByteMathContext01(
void)
1057 DetectByteMathData *bmd = NULL;
1064 "(msg:\"Testing bytemath_body\"; "
1065 "content:\"|00 04 93 F3|\"; "
1066 "content:\"|00 00 00 07|\"; distance:4; within:4;"
1067 "byte_math:bytes 4, offset 0, oper +, rvalue "
1068 "248, result var, relative; sid:1;)");
1088 bmd = (DetectByteMathData *)sm->
ctx;
1093 FAIL_IF_NOT(bmd->flags == DETECT_BYTEMATH_FLAG_RELATIVE);
1103 static void DetectByteMathRegisterTests(
void)
1105 UtRegisterTest(
"DetectByteMathParseTest01", DetectByteMathParseTest01);
1106 UtRegisterTest(
"DetectByteMathParseTest02", DetectByteMathParseTest02);
1107 UtRegisterTest(
"DetectByteMathParseTest03", DetectByteMathParseTest03);
1108 UtRegisterTest(
"DetectByteMathParseTest04", DetectByteMathParseTest04);
1109 UtRegisterTest(
"DetectByteMathParseTest05", DetectByteMathParseTest05);
1110 UtRegisterTest(
"DetectByteMathParseTest06", DetectByteMathParseTest06);
1111 UtRegisterTest(
"DetectByteMathParseTest07", DetectByteMathParseTest07);
1112 UtRegisterTest(
"DetectByteMathParseTest08", DetectByteMathParseTest08);
1113 UtRegisterTest(
"DetectByteMathParseTest09", DetectByteMathParseTest09);
1114 UtRegisterTest(
"DetectByteMathParseTest10", DetectByteMathParseTest10);
1115 UtRegisterTest(
"DetectByteMathParseTest11", DetectByteMathParseTest11);
1116 UtRegisterTest(
"DetectByteMathParseTest12", DetectByteMathParseTest12);
1117 UtRegisterTest(
"DetectByteMathParseTest13", DetectByteMathParseTest13);
1118 UtRegisterTest(
"DetectByteMathParseTest14", DetectByteMathParseTest14);
1119 UtRegisterTest(
"DetectByteMathParseTest15", DetectByteMathParseTest15);
1120 UtRegisterTest(
"DetectByteMathParseTest16", DetectByteMathParseTest16);
1121 UtRegisterTest(
"DetectByteMathParseTest17", DetectByteMathParseTest17);
1122 UtRegisterTest(
"DetectByteMathPacket01", DetectByteMathPacket01);
1123 UtRegisterTest(
"DetectByteMathPacket02", DetectByteMathPacket02);
1124 UtRegisterTest(
"DetectByteMathPacket03", DetectByteMathPacket03);
1125 UtRegisterTest(
"DetectByteMathContext01", DetectByteMathContext01);