61 #define DETECT_BYTEMATH_ENDIAN_DEFAULT (uint8_t) BigEndian
62 #define DETECT_BYTEMATH_BASE_DEFAULT (uint8_t) BaseDec
64 static void DetectByteMathRegisterTests(
void);
84 static inline bool DetectByteMathValidateNbytesOnly(
const DetectByteMathData *data, int32_t nbytes)
87 (((data->flags & DETECT_BYTEMATH_FLAG_STRING) && nbytes <= 10) || (nbytes <= 4));
92 uint64_t rvalue, uint64_t *value, uint8_t endian)
98 if (!DetectByteMathValidateNbytesOnly(data, nbytes)) {
110 if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
111 SCLogDebug(
"relative, working with det_ctx->buffer_offset %" PRIu32
", "
112 "data->offset %" PRIi32
"",
126 SCLogDebug(
"absolute, data->offset %" PRIi32
"", data->offset);
128 ptr = payload + data->offset;
133 if (ptr < payload || nbytes >
len) {
134 SCLogDebug(
"Data not within payload pkt=%p, ptr=%p, len=%" PRIu32
", nbytes=%d", payload,
140 if (data->flags & DETECT_BYTEMATH_FLAG_STRING) {
147 SCLogDebug(
"error extracting %d bytes of string data: %d", nbytes, extbytes);
152 ByteEndian bme = endian;
155 if (extbytes != nbytes) {
156 SCLogDebug(
"error extracting %d bytes of numeric data: %d", nbytes, extbytes);
165 switch (data->oper) {
202 if (data->flags & DETECT_BYTEMATH_FLAG_BITMASK) {
203 val &= data->bitmask_val;
204 if (val && data->bitmask_shift_count) {
205 val = val >> data->bitmask_shift_count;
224 static DetectByteMathData *DetectByteMathParse(
227 DetectByteMathData *bmd;
228 if ((bmd = SCByteMathParse(arg)) == NULL) {
233 if (bmd->nbytes_str) {
234 if (nbytes == NULL) {
236 "var name for nbytes. \"nbytes\" argument supplied to "
237 "this function must be non-NULL");
240 *nbytes =
SCStrdup(bmd->nbytes_str);
241 if (*nbytes == NULL) {
246 if (bmd->rvalue_str) {
247 if (rvalue == NULL) {
249 "var name for rvalue. \"rvalue\" argument supplied to "
250 "this function must be non-NULL");
253 *rvalue =
SCStrdup(bmd->rvalue_str);
254 if (*rvalue == NULL) {
259 if (bmd->flags & DETECT_BYTEMATH_FLAG_BITMASK) {
260 if (bmd->bitmask_val) {
261 uint32_t bmask = bmd->bitmask_val;
262 while (!(bmask & 0x1)){
264 bmd->bitmask_shift_count++;
273 DetectByteMathFree(
de_ctx, bmd);
291 DetectByteMathData *data;
296 data = DetectByteMathParse(
de_ctx, arg, &nbytes, &rvalue);
307 if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
311 "previous pattern match");
315 }
else if (data->endian == EndianDCE) {
316 if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
319 if (prev_pm == NULL) {
333 }
else if (data->flags & DETECT_BYTEMATH_FLAG_RELATIVE) {
336 if (prev_pm == NULL) {
348 if (data->endian == EndianDCE) {
352 if ((data->flags & DETECT_BYTEMATH_FLAG_STRING) || (data->base == BaseDec) ||
353 (data->base == BaseHex) || (data->base == BaseOct)) {
355 "A bytemath keyword with dce holds other invalid modifiers.");
360 if (nbytes != NULL) {
363 SCLogError(
"unknown byte_ keyword var seen in byte_math - %s", nbytes);
366 data->nbytes = index;
367 data->flags |= DETECT_BYTEMATH_FLAG_NBYTES_VAR;
372 if (rvalue != NULL) {
375 SCLogError(
"unknown byte_ keyword var seen in byte_math - %s", rvalue);
378 data->rvalue = index;
379 data->flags |= DETECT_BYTEMATH_FLAG_RVALUE_VAR;
386 if (prev_bmd_sm == NULL) {
389 data->local_id = ((DetectByteMathData *)prev_bmd_sm->
ctx)->local_id + 1;
400 if (!(data->flags & DETECT_BYTEMATH_FLAG_RELATIVE))
422 DetectByteMathFree(
de_ctx, data);
450 const DetectByteMathData *bmd = (
const DetectByteMathData *)sm->
ctx;
451 if (strcmp(bmd->result, arg) == 0) {
465 const DetectByteMathData *bmd = (
const DetectByteMathData *)sm->
ctx;
466 if (strcmp(bmd->result, arg) == 0) {
482 static int DetectByteMathParseTest01(
void)
485 DetectByteMathData *bmd = DetectByteMathParse(NULL,
486 "bytes 4, offset 2, oper +,"
487 "rvalue 10, result bar",
499 DetectByteMathFree(NULL, bmd);
504 static int DetectByteMathParseTest02(
void)
507 DetectByteMathData *bmd = DetectByteMathParse(NULL,
508 "bytes 257, offset 2, oper +, "
509 "rvalue 39, result bar",
517 static int DetectByteMathParseTest03(
void)
520 DetectByteMathData *bmd = DetectByteMathParse(NULL,
521 "bytes 11, offset 2, oper +, "
522 "rvalue 39, result bar",
529 static int DetectByteMathParseTest04(
void)
532 DetectByteMathData *bmd = DetectByteMathParse(NULL,
533 "bytes 4, offset 70000, oper +,"
534 " rvalue 39, result bar",
542 static int DetectByteMathParseTest05(
void)
545 DetectByteMathData *bmd = DetectByteMathParse(NULL,
546 "bytes 11, offset 16, oper &,"
547 "rvalue 39, result bar",
554 static int DetectByteMathParseTest06(
void)
556 uint8_t
flags = DETECT_BYTEMATH_FLAG_RELATIVE;
559 DetectByteMathData *bmd = DetectByteMathParse(NULL,
560 "bytes 4, offset 0, oper +,"
561 "rvalue 248, result var, relative",
574 DetectByteMathFree(NULL, bmd);
579 static int DetectByteMathParseTest07(
void)
583 DetectByteMathData *bmd = DetectByteMathParse(NULL,
584 "bytes 4, offset 2, oper +,"
585 "rvalue foo, result bar",
596 DetectByteMathFree(NULL, bmd);
603 static int DetectByteMathParseTest08(
void)
606 DetectByteMathData *bmd = DetectByteMathParse(NULL,
607 "bytes 4, offset 2, oper +,"
608 "rvalue foo, result bar",
615 static int DetectByteMathParseTest09(
void)
617 uint8_t
flags = DETECT_BYTEMATH_FLAG_RELATIVE;
619 DetectByteMathData *bmd = DetectByteMathParse(NULL,
620 "bytes 4, offset 2, oper +,"
621 "rvalue 39, result bar, relative",
634 DetectByteMathFree(NULL, bmd);
639 static int DetectByteMathParseTest10(
void)
641 uint8_t
flags = DETECT_BYTEMATH_FLAG_ENDIAN;
643 DetectByteMathData *bmd = DetectByteMathParse(NULL,
644 "bytes 4, offset 2, oper +,"
645 "rvalue 39, result bar, endian"
659 DetectByteMathFree(NULL, bmd);
664 static int DetectByteMathParseTest11(
void)
666 uint8_t
flags = DETECT_BYTEMATH_FLAG_ENDIAN;
668 DetectByteMathData *bmd = DetectByteMathParse(NULL,
669 "bytes 4, offset 2, oper +, "
670 "rvalue 39, result bar, dce",
683 DetectByteMathFree(NULL, bmd);
688 static int DetectByteMathParseTest12(
void)
690 uint8_t
flags = DETECT_BYTEMATH_FLAG_RELATIVE | DETECT_BYTEMATH_FLAG_STRING;
692 DetectByteMathData *bmd = DetectByteMathParse(NULL,
693 "bytes 4, offset 2, oper +,"
694 "rvalue 39, result bar, "
695 "relative, string dec",
708 DetectByteMathFree(NULL, bmd);
713 static int DetectByteMathParseTest13(
void)
715 uint8_t
flags = DETECT_BYTEMATH_FLAG_STRING |
716 DETECT_BYTEMATH_FLAG_RELATIVE |
717 DETECT_BYTEMATH_FLAG_BITMASK;
719 DetectByteMathData *bmd = DetectByteMathParse(NULL,
720 "bytes 4, offset 2, oper +, "
721 "rvalue 39, result bar, "
722 "relative, string dec, bitmask "
738 DetectByteMathFree(NULL, bmd);
744 static int DetectByteMathParseTest14(
void)
747 DetectByteMathData *bmd = DetectByteMathParse(NULL,
748 "bytes 4, offset 2, oper +,"
757 static int DetectByteMathParseTest15(
void)
761 DetectByteMathData *bmd = DetectByteMathParse(NULL,
762 "bytes 4, offset 2, oper +, "
771 static int DetectByteMathParseTest16(
void)
773 uint8_t
flags = DETECT_BYTEMATH_FLAG_STRING | DETECT_BYTEMATH_FLAG_RELATIVE |
774 DETECT_BYTEMATH_FLAG_BITMASK;
776 DetectByteMathData *bmd = DetectByteMathParse(NULL,
777 "bytes 4, offset -2, oper +, "
778 "rvalue 39, result bar, "
779 "relative, string dec, bitmask "
795 DetectByteMathFree(NULL, bmd);
800 static int DetectByteMathPacket01(
void)
802 uint8_t buf[] = { 0x38, 0x35, 0x6d, 0x00, 0x00, 0x01,
803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804 0x00, 0x00, 0x6d, 0x00, 0x01, 0x00 };
806 void *dns_state = NULL;
815 memset(&f, 0,
sizeof(
Flow));
818 "192.168.1.5",
"192.168.1.1",
824 f.
proto = IPPROTO_UDP;
846 "(byte_extract: 1, 0, extracted_val, relative;"
847 "byte_math: bytes 1, offset 1, oper +, rvalue extracted_val, result var;"
848 "byte_test: 2, =, var, 13;"
849 "msg:\"Byte extract and byte math with byte test verification\";"
855 "(byte_extract: 1, 0, extracted_val, relative;"
856 "byte_math: bytes 1, offset 1, oper +, rvalue extracted_val, result var;"
857 "byte_test: 2, !=, var, 13;"
858 "msg:\"Byte extract and byte math with byte test verification\";"
867 "(byte_extract: 1, 0, extracted_val, relative;"
868 "byte_math: bytes 1, offset 1, oper +, rvalue extracted_val, result var;"
869 "byte_test: 2, <, var, 15;"
870 "msg:\"Byte extract and byte math with byte test verification\";"
879 STREAM_TOSERVER, buf,
sizeof(buf));
903 static int DetectByteMathPacket02(
void)
905 uint8_t buf[] = { 0x38, 0x35, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
906 0x00, 0x70, 0x00, 0x01, 0x00 };
908 void *dns_state = NULL;
917 memset(&f, 0,
sizeof(
Flow));
919 p =
UTHBuildPacketReal(buf,
sizeof(buf), IPPROTO_UDP,
"192.168.1.5",
"192.168.1.1", 41424, 53);
924 f.
proto = IPPROTO_UDP;
946 "alert udp any any -> any any "
947 "(byte_extract: 1, 0, extracted_val, relative;"
948 "byte_math: bytes 1, offset -1, oper +, rvalue extracted_val, result var, relative;"
949 "byte_test: 2, =, var, 13;"
950 "msg:\"Byte extract and byte math with byte test verification\";"
956 "alert udp any any -> any any "
957 "(byte_extract: 1, 0, extracted_val, relative;"
958 "byte_math: bytes 1, offset -1, oper +, rvalue extracted_val, result var, relative;"
959 "byte_test: 2, !=, var, 13;"
960 "msg:\"Byte extract and byte math with byte test verification\";"
969 "alert udp any any -> any any "
970 "(byte_extract: 1, 0, extracted_val, relative;"
971 "byte_math: bytes 1, offset -1, oper +, rvalue extracted_val, result var, relative;"
972 "byte_test: 2, <, var, 15;"
973 "msg:\"Byte extract and byte math with byte test verification\";"
1010 static int DetectByteMathPacket03(
void)
1014 uint8_t buf[] = { 0x40, 0xff, 0x00 };
1021 "(byte_extract: 1, 0, shift;"
1022 "byte_math: bytes 1, offset 1, oper >>, rvalue shift, result "
1024 "byte_test: 1, =, var, 2;"
1034 static int DetectByteMathParseTest17(
void)
1036 DetectByteMathData *bmd = DetectByteMathParse(
1037 NULL,
"bytes 4, offset 2, oper >>, rvalue 64, result foo", NULL, NULL);
1040 bmd = DetectByteMathParse(
1041 NULL,
"bytes 4, offset 2, oper <<, rvalue 64, result foo", NULL, NULL);
1044 bmd = DetectByteMathParse(
1045 NULL,
"bytes 4, offset 2, oper >>, rvalue 63, result foo", NULL, NULL);
1047 DetectByteMathFree(NULL, bmd);
1052 static int DetectByteMathContext01(
void)
1058 DetectByteMathData *bmd = NULL;
1065 "(msg:\"Testing bytemath_body\"; "
1066 "content:\"|00 04 93 F3|\"; "
1067 "content:\"|00 00 00 07|\"; distance:4; within:4;"
1068 "byte_math:bytes 4, offset 0, oper +, rvalue "
1069 "248, result var, relative; sid:1;)");
1089 bmd = (DetectByteMathData *)sm->
ctx;
1094 FAIL_IF_NOT(bmd->flags == DETECT_BYTEMATH_FLAG_RELATIVE);
1104 static void DetectByteMathRegisterTests(
void)
1106 UtRegisterTest(
"DetectByteMathParseTest01", DetectByteMathParseTest01);
1107 UtRegisterTest(
"DetectByteMathParseTest02", DetectByteMathParseTest02);
1108 UtRegisterTest(
"DetectByteMathParseTest03", DetectByteMathParseTest03);
1109 UtRegisterTest(
"DetectByteMathParseTest04", DetectByteMathParseTest04);
1110 UtRegisterTest(
"DetectByteMathParseTest05", DetectByteMathParseTest05);
1111 UtRegisterTest(
"DetectByteMathParseTest06", DetectByteMathParseTest06);
1112 UtRegisterTest(
"DetectByteMathParseTest07", DetectByteMathParseTest07);
1113 UtRegisterTest(
"DetectByteMathParseTest08", DetectByteMathParseTest08);
1114 UtRegisterTest(
"DetectByteMathParseTest09", DetectByteMathParseTest09);
1115 UtRegisterTest(
"DetectByteMathParseTest10", DetectByteMathParseTest10);
1116 UtRegisterTest(
"DetectByteMathParseTest11", DetectByteMathParseTest11);
1117 UtRegisterTest(
"DetectByteMathParseTest12", DetectByteMathParseTest12);
1118 UtRegisterTest(
"DetectByteMathParseTest13", DetectByteMathParseTest13);
1119 UtRegisterTest(
"DetectByteMathParseTest14", DetectByteMathParseTest14);
1120 UtRegisterTest(
"DetectByteMathParseTest15", DetectByteMathParseTest15);
1121 UtRegisterTest(
"DetectByteMathParseTest16", DetectByteMathParseTest16);
1122 UtRegisterTest(
"DetectByteMathParseTest17", DetectByteMathParseTest17);
1123 UtRegisterTest(
"DetectByteMathPacket01", DetectByteMathPacket01);
1124 UtRegisterTest(
"DetectByteMathPacket02", DetectByteMathPacket02);
1125 UtRegisterTest(
"DetectByteMathPacket03", DetectByteMathPacket03);
1126 UtRegisterTest(
"DetectByteMathContext01", DetectByteMathContext01);