From: Victor Julien Date: Sat, 29 Sep 2018 07:44:06 +0000 (+0200) Subject: detect/ttl: major clean up of ttl code X-Git-Tag: suricata-4.1.0-rc2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=275cf9b0299a347c90c0b58603ee2535a15deade;p=thirdparty%2Fsuricata.git detect/ttl: major clean up of ttl code Redo unittests using FAIL/PASS macros Switch parsing to pcre_copy_substring. Misc cleanups. --- diff --git a/src/detect-ttl.c b/src/detect-ttl.c index 6a30679183..bf0fac7f2d 100644 --- a/src/detect-ttl.c +++ b/src/detect-ttl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation +/* Copyright (C) 2007-2018 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 @@ -19,13 +19,13 @@ * \file * * \author Gurvinder Singh + * \author Victor Julien * - * Implements the ttl keyword + * Implements the ttl keyword including prefilter support. */ #include "suricata-common.h" #include "stream-tcp.h" -#include "util-unittest.h" #include "detect.h" #include "detect-parse.h" @@ -35,20 +35,21 @@ #include "util-debug.h" /** - * \brief Regex for parsing our flow options + * \brief Regex for parsing our ttl options */ #define PARSE_REGEX "^\\s*([0-9]*)?\\s*([<>=-]+)?\\s*([0-9]+)?\\s*$" static pcre *parse_regex; static pcre_extra *parse_regex_study; -/*prototypes*/ +/* prototypes */ static int DetectTtlMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *); static int DetectTtlSetup (DetectEngineCtx *, Signature *, const char *); void DetectTtlFree (void *); +#ifdef UNITTESTS void DetectTtlRegisterTests (void); - +#endif static int PrefilterSetupTtl(DetectEngineCtx *de_ctx, SigGroupHead *sgh); static _Bool PrefilterTtlIsPrefilterable(const Signature *s); @@ -64,8 +65,9 @@ void DetectTtlRegister(void) sigmatch_table[DETECT_TTL].Match = DetectTtlMatch; sigmatch_table[DETECT_TTL].Setup = DetectTtlSetup; sigmatch_table[DETECT_TTL].Free = DetectTtlFree; +#ifdef UNITTESTS sigmatch_table[DETECT_TTL].RegisterTests = DetectTtlRegisterTests; - +#endif sigmatch_table[DETECT_TTL].SupportsPrefilter = PrefilterTtlIsPrefilterable; sigmatch_table[DETECT_TTL].SetupPrefilter = PrefilterSetupTtl; @@ -86,11 +88,11 @@ static inline int TtlMatch(const uint8_t pttl, const uint8_t mode, return 1; return 0; - } /** - * \brief This function is used to match TTL rule option on a packet with those passed via ttl: + * \brief This function is used to match TTL rule option on a packet with + * those passed via ttl * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread @@ -103,7 +105,6 @@ static inline int TtlMatch(const uint8_t pttl, const uint8_t mode, static int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx) { - if (PKT_IS_PSEUDOPKT(p)) return 0; @@ -132,134 +133,122 @@ static int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet static DetectTtlData *DetectTtlParse (const char *ttlstr) { - DetectTtlData *ttld = NULL; - char *arg1 = NULL; - char *arg2 = NULL; - char *arg3 = NULL; #define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; + char arg1[6] = ""; + char arg2[6] = ""; + char arg3[6] = ""; - ret = pcre_exec(parse_regex, parse_regex_study, ttlstr, strlen(ttlstr), 0, 0, ov, MAX_SUBSTRINGS); + int ret = pcre_exec(parse_regex, parse_regex_study, ttlstr, strlen(ttlstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret < 2 || ret > 4) { SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 "", ret); - goto error; + return NULL; } - const char *str_ptr; - res = pcre_get_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); + int res = pcre_copy_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 1, arg1, sizeof(arg1)); if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; + SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); + return NULL; } - arg1 = (char *) str_ptr; - SCLogDebug("Arg1 \"%s\"", arg1); + SCLogDebug("arg1 \"%s\"", arg1); if (ret >= 3) { - res = pcre_get_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); + res = pcre_copy_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 2, arg2, sizeof(arg2)); if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; + SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); + return NULL; } - arg2 = (char *) str_ptr; - SCLogDebug("Arg2 \"%s\"", arg2); + SCLogDebug("arg2 \"%s\"", arg2); if (ret >= 4) { - res = pcre_get_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); + res = pcre_copy_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 3, arg3, sizeof(arg3)); if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; + SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); + return NULL; } - arg3 = (char *) str_ptr; - SCLogDebug("Arg3 \"%s\"", arg3); + SCLogDebug("arg3 \"%s\"", arg3); } } - ttld = SCMalloc(sizeof (DetectTtlData)); - if (unlikely(ttld == NULL)) - goto error; - ttld->ttl1 = 0; - ttld->ttl2 = 0; + int ttl1 = 0; + int ttl2 = 0; + int mode = 0; - if (arg2 != NULL) { - /*set the values*/ - switch(arg2[0]) { + if (strlen(arg2) > 0) { + switch (arg2[0]) { case '<': - if (arg3 == NULL) - goto error; + if (strlen(arg3) == 0) + return NULL; - ttld->mode = DETECT_TTL_LT; - ttld->ttl1 = (uint8_t) atoi(arg3); + mode = DETECT_TTL_LT; + ttl1 = atoi(arg3); - SCLogDebug("ttl is %"PRIu8"",ttld->ttl1); + SCLogDebug("ttl is %"PRIu8"",ttl1); if (strlen(arg1) > 0) - goto error; + return NULL; break; case '>': - if (arg3 == NULL) - goto error; + if (strlen(arg3) == 0) + return NULL; - ttld->mode = DETECT_TTL_GT; - ttld->ttl1 = (uint8_t) atoi(arg3); + mode = DETECT_TTL_GT; + ttl1 = atoi(arg3); - SCLogDebug("ttl is %"PRIu8"",ttld->ttl1); + SCLogDebug("ttl is %"PRIu8"",ttl1); if (strlen(arg1) > 0) - goto error; + return NULL; break; case '-': - if (arg1 == NULL || strlen(arg1)== 0) - goto error; - if (arg3 == NULL || strlen(arg3)== 0) - goto error; - - ttld->mode = DETECT_TTL_RA; - ttld->ttl1 = (uint8_t) atoi(arg1); - - ttld->ttl2 = (uint8_t) atoi(arg3); - SCLogDebug("ttl is %"PRIu8" to %"PRIu8"",ttld->ttl1, ttld->ttl2); - if (ttld->ttl1 >= ttld->ttl2) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid ttl range. "); - goto error; + if (strlen(arg1) == 0 || strlen(arg3) == 0) + return NULL; + + mode = DETECT_TTL_RA; + ttl1 = atoi(arg1); + ttl2 = atoi(arg3); + + SCLogDebug("ttl is %"PRIu8" to %"PRIu8"",ttl1, ttl2); + if (ttl1 >= ttl2) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid ttl range"); + return NULL; } break; default: - ttld->mode = DETECT_TTL_EQ; + mode = DETECT_TTL_EQ; - if ((arg2 != NULL && strlen(arg2) > 0) || - (arg3 != NULL && strlen(arg3) > 0) || - (arg1 == NULL ||strlen(arg1) == 0)) - goto error; + if ((strlen(arg2) > 0) || + (strlen(arg3) > 0) || + (strlen(arg1) == 0)) + return NULL; - ttld->ttl1 = (uint8_t) atoi(arg1); + ttl1 = atoi(arg1); break; } } else { - ttld->mode = DETECT_TTL_EQ; + mode = DETECT_TTL_EQ; - if ((arg3 != NULL && strlen(arg3) > 0) || - (arg1 == NULL ||strlen(arg1) == 0)) - goto error; + if ((strlen(arg3) > 0) || + (strlen(arg1) == 0)) + return NULL; - ttld->ttl1 = (uint8_t) atoi(arg1); + ttl1 = atoi(arg1); } - SCFree(arg1); - SCFree(arg2); - SCFree(arg3); - return ttld; + if (ttl1 < 0 || ttl1 > UCHAR_MAX || + ttl2 < 0 || ttl2 > UCHAR_MAX) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid ttl value(s)"); + return NULL; + } + + DetectTtlData *ttld = SCMalloc(sizeof(DetectTtlData)); + if (unlikely(ttld == NULL)) + return NULL; + ttld->ttl1 = (uint8_t)ttl1; + ttld->ttl2 = (uint8_t)ttl2; + ttld->mode = mode; -error: - if (ttld) - SCFree(ttld); - if (arg1) - SCFree(arg1); - if (arg2) - SCFree(arg2); - if (arg3) - SCFree(arg3); - return NULL; + return ttld; } /** @@ -274,29 +263,22 @@ error: */ static int DetectTtlSetup (DetectEngineCtx *de_ctx, Signature *s, const char *ttlstr) { - DetectTtlData *ttld = NULL; - SigMatch *sm = NULL; - - ttld = DetectTtlParse(ttlstr); + DetectTtlData *ttld = DetectTtlParse(ttlstr); if (ttld == NULL) - goto error; + return -1; - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; + SigMatch *sm = SigMatchAlloc(); + if (sm == NULL) { + DetectTtlFree(ttld); + return -1; + } sm->type = DETECT_TTL; sm->ctx = (SigMatchCtx *)ttld; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); s->flags |= SIG_FLAG_REQUIRE_PACKET; - return 0; - -error: - if (ttld != NULL) DetectTtlFree(ttld); - if (sm != NULL) SCFree(sm); - return -1; } /** @@ -381,324 +363,5 @@ static _Bool PrefilterTtlIsPrefilterable(const Signature *s) } #ifdef UNITTESTS -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \brief this function is used to initialize the detection engine context and - * setup the signature with passed values. - * - */ - -static int DetectTtlInitTest(DetectEngineCtx **de_ctx, Signature **sig, DetectTtlData **ttld, const char *str) -{ - char fullstr[1024]; - int result = 0; - - *de_ctx = NULL; - *sig = NULL; - - if (snprintf(fullstr, 1024, "alert ip any any -> any any (msg:\"Ttl test\"; ttl:%s; sid:1;)", str) >= 1024) { - goto end; - } - - *de_ctx = DetectEngineCtxInit(); - if (*de_ctx == NULL) { - goto end; - } - - (*de_ctx)->flags |= DE_QUIET; - - (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr); - if ((*de_ctx)->sig_list == NULL) { - goto end; - } - - *sig = (*de_ctx)->sig_list; - - *ttld = DetectTtlParse(str); - - result = 1; - -end: - return result; -} - -/** - * \test DetectTtlParseTest01 is a test for setting up an valid ttl value. - */ - -static int DetectTtlParseTest01 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse("10"); - if (ttld != NULL) { - if (ttld->ttl1 == 10 && ttld->mode == DETECT_TTL_EQ) - res = 1; - - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest02 is a test for setting up an valid ttl value with - * "<" operator. - */ - -static int DetectTtlParseTest02 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - ttld = DetectTtlParse("<10"); - if (ttld != NULL) { - if (ttld->ttl1 == 10 && ttld->mode == DETECT_TTL_LT) - res = 1; - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest03 is a test for setting up an valid ttl values with - * "-" operator. - */ - -static int DetectTtlParseTest03 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - ttld = DetectTtlParse("1-2"); - if (ttld != NULL) { - if (ttld->ttl1 == 1 && ttld->ttl2 == 2 && ttld->mode == DETECT_TTL_RA) - res = 1; - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest04 is a test for setting up an valid ttl value with - * ">" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest04 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" > 10 "); - if (ttld != NULL) { - if (ttld->ttl1 == 10 && ttld->mode == DETECT_TTL_GT) - res = 1; - - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest05 is a test for setting up an valid ttl values with - * "-" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest05 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" 1 - 2 "); - if (ttld != NULL) { - if (ttld->ttl1 == 1 && ttld->ttl2 == 2 && ttld->mode == DETECT_TTL_RA) - res = 1; - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest06 is a test for setting up an valid ttl values with - * invalid "=" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest06 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" 1 = 2 "); - if (ttld == NULL) - res = 1; - if (ttld) SCFree(ttld); - - return res; -} - -/** - * \test DetectTtlParseTest07 is a test for setting up an valid ttl values with - * invalid "<>" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest07 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" 1<>2 "); - if (ttld == NULL) - res = 1; - - if (ttld) SCFree(ttld); - - return res; -} - -/** - * \test DetectTtlSetpTest01 is a test for setting up an valid ttl values with - * valid "-" operator and include spaces arround the given values. In the - * test the values are setup with initializing the detection engine context - * setting up the signature itself. - */ - -static int DetectTtlSetpTest01(void) -{ - - DetectTtlData *ttld = NULL; - uint8_t res = 0; - Signature *sig = NULL; - DetectEngineCtx *de_ctx = NULL; - - res = DetectTtlInitTest(&de_ctx, &sig, &ttld, "1 - 2 "); - if (res == 0) { - goto end; - } - - if(ttld == NULL) - goto cleanup; - - if (ttld != NULL) { - if (ttld->ttl1 == 1 && ttld->ttl2 == 2 && ttld->mode == DETECT_TTL_RA) - res = 1; - } - -cleanup: - if (ttld) SCFree(ttld); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); -end: - return res; -} - -/** - * \test DetectTtlTestSig01 is a test for checking the working of ttl keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - */ - -static int DetectTtlTestSig1(void) -{ - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - IPV4Hdr ip4h; - - memset(&th_v, 0, sizeof(th_v)); - memset(&ip4h, 0, sizeof(ip4h)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - ip4h.ip_ttl = 15; - p->ip4h = &ip4h; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"with in ttl limit\"; ttl: >16; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Less than 17\"; ttl: <17; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Greater than 5\"; ttl:15; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Equals tcp\"; ttl: 1-30; sid:4;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - printf("sid 2 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3) == 0) { - printf("sid 3 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - printf("sid 4 did not alert, but should have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectTtl - */ -void DetectTtlRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectTtlParseTest01", DetectTtlParseTest01); - UtRegisterTest("DetectTtlParseTest02", DetectTtlParseTest02); - UtRegisterTest("DetectTtlParseTest03", DetectTtlParseTest03); - UtRegisterTest("DetectTtlParseTest04", DetectTtlParseTest04); - UtRegisterTest("DetectTtlParseTest05", DetectTtlParseTest05); - UtRegisterTest("DetectTtlParseTest06", DetectTtlParseTest06); - UtRegisterTest("DetectTtlParseTest07", DetectTtlParseTest07); - UtRegisterTest("DetectTtlSetpTest01", DetectTtlSetpTest01); - UtRegisterTest("DetectTtlTestSig1", DetectTtlTestSig1); -#endif /* UNITTESTS */ -} +#include "tests/detect-ttl.c" +#endif diff --git a/src/tests/detect-ttl.c b/src/tests/detect-ttl.c new file mode 100644 index 0000000000..a89d98a51f --- /dev/null +++ b/src/tests/detect-ttl.c @@ -0,0 +1,220 @@ + +/* Copyright (C) 2007-2018 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 "../detect-engine.h" +#include "../util-unittest.h" + +/** + * \test DetectTtlParseTest01 is a test for setting up an valid ttl value. + */ + +static int DetectTtlParseTest01 (void) +{ + DetectTtlData *ttld = DetectTtlParse("10"); + FAIL_IF_NULL(ttld); + FAIL_IF_NOT(ttld->ttl1 == 10); + FAIL_IF_NOT(ttld->mode == DETECT_TTL_EQ); + DetectTtlFree(ttld); + PASS; +} + +/** + * \test DetectTtlParseTest02 is a test for setting up an valid ttl value with + * "<" operator. + */ + +static int DetectTtlParseTest02 (void) +{ + DetectTtlData *ttld = DetectTtlParse("<10"); + FAIL_IF_NULL(ttld); + FAIL_IF_NOT(ttld->ttl1 == 10); + FAIL_IF_NOT(ttld->mode == DETECT_TTL_LT); + DetectTtlFree(ttld); + PASS; +} + +/** + * \test DetectTtlParseTest03 is a test for setting up an valid ttl values with + * "-" operator. + */ + +static int DetectTtlParseTest03 (void) +{ + DetectTtlData *ttld = DetectTtlParse("1-2"); + FAIL_IF_NULL(ttld); + FAIL_IF_NOT(ttld->ttl1 == 1); + FAIL_IF_NOT(ttld->ttl2 == 2); + FAIL_IF_NOT(ttld->mode == DETECT_TTL_RA); + DetectTtlFree(ttld); + PASS; +} + +/** + * \test DetectTtlParseTest04 is a test for setting up an valid ttl value with + * ">" operator and include spaces arround the given values. + */ + +static int DetectTtlParseTest04 (void) +{ + DetectTtlData *ttld = DetectTtlParse(" > 10 "); + FAIL_IF_NULL(ttld); + FAIL_IF_NOT(ttld->ttl1 == 10); + FAIL_IF_NOT(ttld->mode == DETECT_TTL_GT); + DetectTtlFree(ttld); + PASS; +} + +/** + * \test DetectTtlParseTest05 is a test for setting up an valid ttl values with + * "-" operator and include spaces arround the given values. + */ + +static int DetectTtlParseTest05 (void) +{ + DetectTtlData *ttld = DetectTtlParse(" 1 - 2 "); + FAIL_IF_NULL(ttld); + FAIL_IF_NOT(ttld->ttl1 == 1); + FAIL_IF_NOT(ttld->ttl2 == 2); + FAIL_IF_NOT(ttld->mode == DETECT_TTL_RA); + DetectTtlFree(ttld); + PASS; +} + +/** + * \test DetectTtlParseTest06 is a test for setting up an valid ttl values with + * invalid "=" operator and include spaces arround the given values. + */ + +static int DetectTtlParseTest06 (void) +{ + DetectTtlData *ttld = DetectTtlParse(" 1 = 2 "); + FAIL_IF_NOT_NULL(ttld); + PASS; +} + +/** + * \test DetectTtlParseTest07 is a test for setting up an valid ttl values with + * invalid "<>" operator and include spaces arround the given values. + */ + +static int DetectTtlParseTest07 (void) +{ + DetectTtlData *ttld = DetectTtlParse(" 1<>2 "); + FAIL_IF_NOT_NULL(ttld); + PASS; +} + +/** + * \test DetectTtlSetupTest01 is a test for setting up an valid ttl values with + * valid "-" operator and include spaces arround the given values. In the + * test the values are setup with initializing the detection engine context + * setting up the signature itself. + */ + +static int DetectTtlSetupTest01(void) +{ + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + de_ctx->flags |= DE_QUIET; + + Signature *s = DetectEngineAppendSig(de_ctx, + "alert ip any any -> any any (msg:\"with in ttl limit\"; ttl:1 - 2; sid:1;)"); + FAIL_IF_NULL(s); + SigGroupBuild(de_ctx); + FAIL_IF_NULL(s->sm_arrays[DETECT_SM_LIST_MATCH]); + FAIL_IF_NULL(s->sm_arrays[DETECT_SM_LIST_MATCH]->ctx); + DetectTtlData *ttld = (DetectTtlData *)s->sm_arrays[DETECT_SM_LIST_MATCH]->ctx; + + FAIL_IF_NOT(ttld->ttl1 == 1); + FAIL_IF_NOT(ttld->ttl2 == 2); + FAIL_IF_NOT(ttld->mode == DETECT_TTL_RA); + DetectEngineCtxFree(de_ctx); + PASS; +} + +/** + * \test DetectTtlTestSig01 is a test for checking the working of ttl keyword + * by setting up the signature and later testing its working by matching + * the received packet against the sig. + */ + +static int DetectTtlTestSig1(void) +{ + Packet *p = PacketGetFromAlloc(); + FAIL_IF_NULL(p); + Signature *s = NULL; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx; + IPV4Hdr ip4h; + + memset(&th_v, 0, sizeof(th_v)); + memset(&ip4h, 0, sizeof(ip4h)); + + p->src.family = AF_INET; + p->dst.family = AF_INET; + p->proto = IPPROTO_TCP; + ip4h.ip_ttl = 15; + p->ip4h = &ip4h; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + de_ctx->flags |= DE_QUIET; + + s = DetectEngineAppendSig(de_ctx,"alert ip any any -> any any (msg:\"with in ttl limit\"; ttl: >16; sid:1;)"); + FAIL_IF_NULL(s); + + s = DetectEngineAppendSig(de_ctx,"alert ip any any -> any any (msg:\"Less than 17\"; ttl: <17; sid:2;)"); + FAIL_IF_NULL(s); + + s = DetectEngineAppendSig(de_ctx,"alert ip any any -> any any (msg:\"Greater than 5\"; ttl:15; sid:3;)"); + FAIL_IF_NULL(s); + + s = DetectEngineAppendSig(de_ctx,"alert ip any any -> any any (msg:\"Equals tcp\"; ttl: 1-30; sid:4;)"); + FAIL_IF_NULL(s); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + FAIL_IF(PacketAlertCheck(p, 1)); + FAIL_IF_NOT(PacketAlertCheck(p, 2)); + FAIL_IF_NOT(PacketAlertCheck(p, 3)); + FAIL_IF_NOT(PacketAlertCheck(p, 4)); + + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + DetectEngineCtxFree(de_ctx); + + SCFree(p); + PASS; +} + +/** + * \brief this function registers unit tests for DetectTtl + */ +void DetectTtlRegisterTests(void) +{ + UtRegisterTest("DetectTtlParseTest01", DetectTtlParseTest01); + UtRegisterTest("DetectTtlParseTest02", DetectTtlParseTest02); + UtRegisterTest("DetectTtlParseTest03", DetectTtlParseTest03); + UtRegisterTest("DetectTtlParseTest04", DetectTtlParseTest04); + UtRegisterTest("DetectTtlParseTest05", DetectTtlParseTest05); + UtRegisterTest("DetectTtlParseTest06", DetectTtlParseTest06); + UtRegisterTest("DetectTtlParseTest07", DetectTtlParseTest07); + UtRegisterTest("DetectTtlSetupTest01", DetectTtlSetupTest01); + UtRegisterTest("DetectTtlTestSig1", DetectTtlTestSig1); +}