diff --git a/src/Makefile.am b/src/Makefile.am index 325d8a8d85..959d27b1a9 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1208,7 +1208,6 @@ EXTRA_DIST = \ tests/detect-icmpv6hdr.c \ tests/detect-snmp-pdu_type.c \ tests/detect-snmp-version.c \ - tests/detect-tcpmss.c \ tests/detect-template.c \ tests/detect-transform-pcrexform.c \ tests/detect-transform-xor.c \ diff --git a/src/detect-tcpmss.c b/src/detect-tcpmss.c index f544d1c8ee..1ed04d3499 100644 --- a/src/detect-tcpmss.c +++ b/src/detect-tcpmss.c @@ -27,16 +27,11 @@ #include "detect.h" #include "detect-parse.h" #include "detect-engine-prefilter-common.h" +#include "detect-engine-uint.h" #include "util-byte.h" #include "detect-tcpmss.h" -/** - * \brief Regex for parsing our options - */ -#define PARSE_REGEX "^\\s*([0-9]*)?\\s*([<>=-]+)?\\s*([0-9]+)?\\s*$" - -static DetectParseRegex parse_regex; /* prototypes */ static int DetectTcpmssMatch (DetectEngineThreadCtx *, Packet *, @@ -61,37 +56,19 @@ void DetectTcpmssRegister(void) sigmatch_table[DETECT_TCPMSS].Match = DetectTcpmssMatch; sigmatch_table[DETECT_TCPMSS].Setup = DetectTcpmssSetup; sigmatch_table[DETECT_TCPMSS].Free = DetectTcpmssFree; -#ifdef UNITTESTS - sigmatch_table[DETECT_TCPMSS].RegisterTests = DetectTcpmssRegisterTests; -#endif sigmatch_table[DETECT_TCPMSS].SupportsPrefilter = PrefilterTcpmssIsPrefilterable; sigmatch_table[DETECT_TCPMSS].SetupPrefilter = PrefilterSetupTcpmss; - DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); return; } -static inline int TcpmssMatch(const uint16_t parg, const uint8_t mode, - const uint16_t darg1, const uint16_t darg2) -{ - if (mode == DETECT_TCPMSS_EQ && parg == darg1) - return 1; - else if (mode == DETECT_TCPMSS_LT && parg < darg1) - return 1; - else if (mode == DETECT_TCPMSS_GT && parg > darg1) - return 1; - else if (mode == DETECT_TCPMSS_RA && (parg > darg1 && parg < darg2)) - return 1; - - return 0; -} - /** - * \brief This function is used to match TCPMSS rule option on a packet with those passed via tcpmss: + * \brief This function is used to match TCPMSS rule option on a packet with those passed via + * tcpmss: * * \param det_ctx pointer to the pattern matcher thread * \param p pointer to the current packet - * \param ctx pointer to the sigmatch that we will cast into DetectTcpmssData + * \param ctx pointer to the sigmatch that we will cast into DetectU16Data * * \retval 0 no match * \retval 1 match @@ -108,165 +85,8 @@ static int DetectTcpmssMatch (DetectEngineThreadCtx *det_ctx, Packet *p, uint16_t ptcpmss = TCP_GET_MSS(p); - const DetectTcpmssData *tcpmssd = (const DetectTcpmssData *)ctx; - return TcpmssMatch(ptcpmss, tcpmssd->mode, tcpmssd->arg1, tcpmssd->arg2); -} - -/** - * \brief This function is used to parse tcpmss options passed via tcpmss: keyword - * - * \param tcpmssstr Pointer to the user provided tcpmss options - * - * \retval tcpmssd pointer to DetectTcpmssData on success - * \retval NULL on failure - */ - -static DetectTcpmssData *DetectTcpmssParse (const char *tcpmssstr) -{ - DetectTcpmssData *tcpmssd = NULL; - char *arg1 = NULL; - char *arg2 = NULL; - char *arg3 = NULL; - int ret = 0, res = 0; - size_t pcre2_len; - - ret = DetectParsePcreExec(&parse_regex, tcpmssstr, 0, 0); - if (ret < 2 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 "", ret); - goto error; - } - const char *str_ptr; - - res = pcre2_substring_get_bynumber(parse_regex.match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed"); - goto error; - } - arg1 = (char *) str_ptr; - SCLogDebug("Arg1 \"%s\"", arg1); - - if (ret >= 3) { - res = pcre2_substring_get_bynumber( - parse_regex.match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed"); - goto error; - } - arg2 = (char *) str_ptr; - SCLogDebug("Arg2 \"%s\"", arg2); - - if (ret >= 4) { - res = pcre2_substring_get_bynumber( - parse_regex.match, 3, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed"); - goto error; - } - arg3 = (char *) str_ptr; - SCLogDebug("Arg3 \"%s\"", arg3); - } - } - - tcpmssd = SCMalloc(sizeof (DetectTcpmssData)); - if (unlikely(tcpmssd == NULL)) - goto error; - tcpmssd->arg1 = 0; - tcpmssd->arg2 = 0; - - if (arg2 != NULL) { - /*set the values*/ - switch(arg2[0]) { - case '<': - if (arg3 == NULL) - goto error; - - tcpmssd->mode = DETECT_TCPMSS_LT; - if (StringParseUint16(&tcpmssd->arg1, 10, 0, (const char *)arg3) < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first arg: %s", arg3); - goto error; - } - SCLogDebug("tcpmss is %"PRIu16"",tcpmssd->arg1); - if (strlen(arg1) > 0) - goto error; - - break; - case '>': - if (arg3 == NULL) - goto error; - - tcpmssd->mode = DETECT_TCPMSS_GT; - if (StringParseUint16(&tcpmssd->arg1, 10, 0, (const char *)arg3) < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first arg: %s", arg3); - goto error; - } - SCLogDebug("tcpmss is %"PRIu16"",tcpmssd->arg1); - if (strlen(arg1) > 0) - goto error; - - break; - case '-': - if (arg1 == NULL || strlen(arg1)== 0) - goto error; - if (arg3 == NULL || strlen(arg3)== 0) - goto error; - - tcpmssd->mode = DETECT_TCPMSS_RA; - if (StringParseUint16(&tcpmssd->arg1, 10, 0, (const char *)arg1) < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first arg: %s", arg1); - goto error; - } - if (StringParseUint16(&tcpmssd->arg2, 10, 0, (const char *)arg3) < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid second arg: %s", arg3); - goto error; - } - SCLogDebug("tcpmss is %"PRIu16" to %"PRIu16"",tcpmssd->arg1, tcpmssd->arg2); - if (tcpmssd->arg1 >= tcpmssd->arg2) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid tcpmss range. "); - goto error; - } - break; - default: - tcpmssd->mode = DETECT_TCPMSS_EQ; - - if ((arg2 != NULL && strlen(arg2) > 0) || - (arg3 != NULL && strlen(arg3) > 0) || - (arg1 == NULL ||strlen(arg1) == 0)) - goto error; - - if (StringParseUint16(&tcpmssd->arg1, 10, 0, (const char *)arg1) < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first arg: %s", arg1); - goto error; - } - break; - } - } else { - tcpmssd->mode = DETECT_TCPMSS_EQ; - - if ((arg3 != NULL && strlen(arg3) > 0) || - (arg1 == NULL ||strlen(arg1) == 0)) - goto error; - - if (StringParseUint16(&tcpmssd->arg1, 10, 0, (const char *)arg1) < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first arg: %s", arg1); - goto error; - } - } - - pcre2_substring_free((PCRE2_UCHAR8 *)arg1); - pcre2_substring_free((PCRE2_UCHAR8 *)arg2); - pcre2_substring_free((PCRE2_UCHAR8 *)arg3); - return tcpmssd; - -error: - if (tcpmssd) - SCFree(tcpmssd); - if (arg1) - pcre2_substring_free((PCRE2_UCHAR8 *)arg1); - if (arg2) - pcre2_substring_free((PCRE2_UCHAR8 *)arg2); - if (arg3) - pcre2_substring_free((PCRE2_UCHAR8 *)arg3); - return NULL; + const DetectU16Data *tcpmssd = (const DetectU16Data *)ctx; + return DetectU16Match(ptcpmss, tcpmssd); } /** @@ -281,7 +101,7 @@ error: */ static int DetectTcpmssSetup (DetectEngineCtx *de_ctx, Signature *s, const char *tcpmssstr) { - DetectTcpmssData *tcpmssd = DetectTcpmssParse(tcpmssstr); + DetectU16Data *tcpmssd = DetectU16Parse(tcpmssstr); if (tcpmssd == NULL) return -1; @@ -301,14 +121,13 @@ static int DetectTcpmssSetup (DetectEngineCtx *de_ctx, Signature *s, const char } /** - * \brief this function will free memory associated with DetectTcpmssData + * \brief this function will free memory associated with DetectU16Data * - * \param ptr pointer to DetectTcpmssData + * \param ptr pointer to DetectU16Data */ void DetectTcpmssFree(DetectEngineCtx *de_ctx, void *ptr) { - DetectTcpmssData *tcpmssd = (DetectTcpmssData *)ptr; - SCFree(tcpmssd); + rs_detect_u16_free(ptr); } /* prefilter code */ @@ -330,41 +149,22 @@ PrefilterPacketTcpmssMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void if (!PrefilterPacketHeaderExtraMatch(ctx, p)) return; + DetectU16Data du16; + du16.mode = ctx->v1.u8[0]; + du16.arg1 = ctx->v1.u16[1]; + du16.arg2 = ctx->v1.u16[2]; /* if we match, add all the sigs that use this prefilter. This means * that these will be inspected further */ - if (TcpmssMatch(ptcpmss, ctx->v1.u8[0], ctx->v1.u16[1], ctx->v1.u16[2])) - { + if (DetectU16Match(ptcpmss, &du16)) { SCLogDebug("packet matches tcpmss/hl %u", ptcpmss); PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt); } } -static void -PrefilterPacketTcpmssSet(PrefilterPacketHeaderValue *v, void *smctx) -{ - const DetectTcpmssData *a = smctx; - v->u8[0] = a->mode; - v->u16[1] = a->arg1; - v->u16[2] = a->arg2; -} - -static bool -PrefilterPacketTcpmssCompare(PrefilterPacketHeaderValue v, void *smctx) -{ - const DetectTcpmssData *a = smctx; - if (v.u8[0] == a->mode && - v.u16[1] == a->arg1 && - v.u16[2] == a->arg2) - return true; - return false; -} - static int PrefilterSetupTcpmss(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { - return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_TCPMSS, - PrefilterPacketTcpmssSet, - PrefilterPacketTcpmssCompare, - PrefilterPacketTcpmssMatch); + return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_TCPMSS, PrefilterPacketU16Set, + PrefilterPacketU16Compare, PrefilterPacketTcpmssMatch); } static bool PrefilterTcpmssIsPrefilterable(const Signature *s) @@ -378,7 +178,3 @@ static bool PrefilterTcpmssIsPrefilterable(const Signature *s) } return false; } - -#ifdef UNITTESTS -#include "tests/detect-tcpmss.c" -#endif diff --git a/src/detect-tcpmss.h b/src/detect-tcpmss.h index af5f887272..d01f2819b5 100644 --- a/src/detect-tcpmss.h +++ b/src/detect-tcpmss.h @@ -24,18 +24,6 @@ #ifndef _DETECT_TCPMSS_H #define _DETECT_TCPMSS_H -#define DETECT_TCPMSS_LT 0 /**< "less than" operator */ -#define DETECT_TCPMSS_EQ 1 /**< "equals" operator (default) */ -#define DETECT_TCPMSS_GT 2 /**< "greater than" operator */ -#define DETECT_TCPMSS_RA 3 /**< "range" operator */ - -typedef struct DetectTcpmssData_ { - uint16_t arg1; /**< first arg value in the signature*/ - uint16_t arg2; /**< second arg value in the signature, in case of range - operator*/ - uint8_t mode; /**< operator used in the signature */ -} DetectTcpmssData; - void DetectTcpmssRegister(void); #endif /* _DETECT_TCPMSS_H */ diff --git a/src/tests/detect-tcpmss.c b/src/tests/detect-tcpmss.c deleted file mode 100644 index 08ae61b732..0000000000 --- a/src/tests/detect-tcpmss.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2007-2019 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "../suricata-common.h" - -#include "../detect.h" -#include "../detect-parse.h" -#include "../detect-engine-prefilter-common.h" - -#include "../detect-tcpmss.h" - -#include "../util-unittest.h" - -/** - * \test setting up a valid tcpmss value. - */ - -static int DetectTcpmssParseTest01 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse("10"); - - FAIL_IF_NULL(tcpmssd); - FAIL_IF_NOT(tcpmssd->arg1 == 10); - FAIL_IF_NOT(tcpmssd->mode == DETECT_TCPMSS_EQ); - - DetectTcpmssFree(NULL, tcpmssd); - - PASS; -} - -/** - * \test setting up a valid tcpmss value with "<" operator. - */ - -static int DetectTcpmssParseTest02 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse("<10"); - - FAIL_IF_NULL(tcpmssd); - FAIL_IF_NOT(tcpmssd->arg1 == 10); - FAIL_IF_NOT(tcpmssd->mode == DETECT_TCPMSS_LT); - - DetectTcpmssFree(NULL, tcpmssd); - - PASS; -} - -/** - * \test setting up an valid tcpmss values with "-" operator. - */ - -static int DetectTcpmssParseTest03 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse("1-2"); - - FAIL_IF_NULL(tcpmssd); - FAIL_IF_NOT(tcpmssd->arg1 == 1); - FAIL_IF_NOT(tcpmssd->mode == DETECT_TCPMSS_RA); - - DetectTcpmssFree(NULL, tcpmssd); - - PASS; -} - -/** - * \test setting up an valid tcpmss value with - * ">" operator and include spaces arround the given values. - */ - -static int DetectTcpmssParseTest04 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse(" > 10 "); - - FAIL_IF_NULL(tcpmssd); - FAIL_IF_NOT(tcpmssd->arg1 == 10); - FAIL_IF_NOT(tcpmssd->mode == DETECT_TCPMSS_GT); - - DetectTcpmssFree(NULL, tcpmssd); - - PASS; -} - -/** - * \test setting up an valid tcpmss values with - * "-" operator and include spaces arround the given values. - */ - -static int DetectTcpmssParseTest05 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse(" 1 - 2 "); - - FAIL_IF_NULL(tcpmssd); - FAIL_IF_NOT(tcpmssd->arg1 == 1); - FAIL_IF_NOT(tcpmssd->arg2 == 2); - FAIL_IF_NOT(tcpmssd->mode == DETECT_TCPMSS_RA); - - DetectTcpmssFree(NULL, tcpmssd); - - PASS; -} - -/** - * \test setting up an valid tcpmss values with - * invalid "=" operator and include spaces arround the given values. - */ - -static int DetectTcpmssParseTest06 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse(" 1 = 2 "); - FAIL_IF_NOT_NULL(tcpmssd); - PASS; -} - -/** - * \test setting up valid tcpmss values with - * invalid "<>" operator and include spaces arround the given values. - */ - -static int DetectTcpmssParseTest07 (void) -{ - DetectTcpmssData *tcpmssd = DetectTcpmssParse(" 1<>2 "); - FAIL_IF_NOT_NULL(tcpmssd); - PASS; -} - -/** - * \brief this function registers unit tests for DetectTcpmss - */ -void DetectTcpmssRegisterTests(void) -{ - UtRegisterTest("DetectTcpmssParseTest01", DetectTcpmssParseTest01); - UtRegisterTest("DetectTcpmssParseTest02", DetectTcpmssParseTest02); - UtRegisterTest("DetectTcpmssParseTest03", DetectTcpmssParseTest03); - UtRegisterTest("DetectTcpmssParseTest04", DetectTcpmssParseTest04); - UtRegisterTest("DetectTcpmssParseTest05", DetectTcpmssParseTest05); - UtRegisterTest("DetectTcpmssParseTest06", DetectTcpmssParseTest06); - UtRegisterTest("DetectTcpmssParseTest07", DetectTcpmssParseTest07); -}