diff --git a/doc/userguide/rules/header-keywords.rst b/doc/userguide/rules/header-keywords.rst index d1d2d7b88779..f407af7f05a5 100644 --- a/doc/userguide/rules/header-keywords.rst +++ b/doc/userguide/rules/header-keywords.rst @@ -259,6 +259,13 @@ field. The tos keyword can be have a value from 0 - 255. This field of the IP header has been updated by `rfc2474 `_ to include functionality for `Differentiated services `_. +Note that the value of the field has been defined with the right-most 2 bits having +the value 0. When specifying a value for tos, ensure that the value follows this. + +E.g, instead of specifying the decimal value 34 (hex 22), right shift twice and use +decimal 136 (hex 88). + +You can specify hexadecimal values as with a leading `x`, e.g, `x88`. Format of tos:: diff --git a/doc/userguide/rules/transforms.rst b/doc/userguide/rules/transforms.rst index 593e52853c34..4b8eb1465a17 100644 --- a/doc/userguide/rules/transforms.rst +++ b/doc/userguide/rules/transforms.rst @@ -1,7 +1,8 @@ Transformations =============== -Transformation keywords turn the data at a sticky buffer into something else. +Transformation keywords turn the data at a sticky buffer into something else. Some transformations +support options for greater control over the transformation process Example:: @@ -12,7 +13,7 @@ This example will match on traffic even if there are one or more spaces between the ``navigate`` and ``(``. The transforms can be chained. They are processed in the order in which they -appear in a rule. Each transforms output acts as input for the next one. +appear in a rule. Each transform's output acts as input for the next one. Example:: @@ -106,3 +107,16 @@ Example:: .. note:: depends on libnss being compiled into Suricata +pcrexform +--------- + +Takes the buffer, applies the required regular expression, and outputs the *first captured expression*. + +.. note:: this transform requires a mandatory option string containing a regular expression. + + +This example alerts if ``http.request_line`` contains ``/dropper.php`` +Example:: + + alert http any any -> any any (msg:"HTTP with pcrexform"; http.request_line; \ + pcrexform:"[a-zA-Z]+\s+(.*)\s+HTTP"; content:"/dropper.php"; sid:1;) diff --git a/src/Makefile.am b/src/Makefile.am index be5046895175..927aa49855bb 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -291,6 +291,7 @@ detect-transform-md5.c detect-transform-md5.h \ detect-transform-sha1.c detect-transform-sha1.h \ detect-transform-sha256.c detect-transform-sha256.h \ detect-transform-dotprefix.c detect-transform-dotprefix.h \ +detect-transform-pcrexform.c detect-transform-pcrexform.h \ detect-ttl.c detect-ttl.h \ detect-uricontent.c detect-uricontent.h \ detect-urilen.c detect-urilen.h \ diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 08b6ae9b827c..4bc26f06dac4 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -1928,9 +1928,9 @@ static int HTPCallbackRequestBodyData(htp_tx_data_t *d) HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len); } else if (tx_ud->request_body_type == HTP_BODY_REQUEST_POST) { - HtpRequestBodyHandlePOST(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); + HtpRequestBodyHandlePOST(hstate, tx_ud, d->tx, (uint8_t *)d->data, len); } else if (tx_ud->request_body_type == HTP_BODY_REQUEST_PUT) { - HtpRequestBodyHandlePUT(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); + HtpRequestBodyHandlePUT(hstate, tx_ud, d->tx, (uint8_t *)d->data, len); } } else { @@ -2027,7 +2027,7 @@ static int HTPCallbackResponseBodyData(htp_tx_data_t *d) HtpBodyAppendChunk(&hstate->cfg->response, &tx_ud->response_body, d->data, len); - HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); + HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data, len); } else { if (tx_ud->tcflags & HTP_FILENAME_SET) { SCLogDebug("closing file that was being stored"); diff --git a/src/detect-asn1.c b/src/detect-asn1.c index 2b51e9f000c7..f0c2ab3dd351 100644 --- a/src/detect-asn1.c +++ b/src/detect-asn1.c @@ -148,15 +148,28 @@ static int DetectAsn1Match(DetectEngineThreadCtx *det_ctx, Packet *p, } const DetectAsn1Data *ad = (const DetectAsn1Data *)ctx; - int32_t offset; + uint16_t offset; if (ad->flags & ASN1_ABSOLUTE_OFFSET) { offset = ad->absolute_offset; } else if (ad->flags & ASN1_RELATIVE_OFFSET) { - offset = ad->relative_offset; + // relative offset in regards to the last content match + + // This range check is done when relative_offset + BUG_ON(ad->relative_offset > UINT16_MAX || ad->relative_offset < -UINT16_MAX); + + int64_t tmp_offset = det_ctx->buffer_offset + ad->relative_offset; + + // check for under/overflow before downcasting + if (tmp_offset < 0 || tmp_offset > UINT16_MAX) { + return 0; + } + + offset = (uint16_t)tmp_offset; } else { offset = 0; } - if (offset >= (int32_t)p->payload_len) { + + if (offset >= p->payload_len) { return 0; } @@ -204,7 +217,7 @@ static DetectAsn1Data *DetectAsn1Parse(const char *instr) DetectAsn1Data *fd = NULL; char *tok = NULL; uint32_t ov_len = 0; - uint32_t abs_off = 0; + uint16_t abs_off = 0; int32_t rel_off = 0; uint8_t flags = 0; char *saveptr = NULL; @@ -244,7 +257,7 @@ static DetectAsn1Data *DetectAsn1Parse(const char *instr) /* get the param */ tok = strtok_r(NULL, ASN_DELIM, &saveptr); if (tok == NULL || - StringParseUint32(&abs_off, 10, 0, tok) <= 0) + StringParseUint16(&abs_off, 10, 0, tok) <= 0) { SCLogError(SC_ERR_INVALID_VALUE, "Malformed value for " "absolute_offset: %s", tok); @@ -254,8 +267,11 @@ static DetectAsn1Data *DetectAsn1Parse(const char *instr) flags |= ASN1_RELATIVE_OFFSET; /* get the param */ tok = strtok_r(NULL, ASN_DELIM, &saveptr); + + // Range check on uint16_t max as uint16_t is the type of the buffer + // the offset is relative to if (tok == NULL || - StringParseInt32(&rel_off, 10, 0, tok) <= 0) + StringParseI32RangeCheck(&rel_off, 10, 0, tok, -UINT16_MAX, UINT16_MAX) <= 0) { SCLogError(SC_ERR_INVALID_VALUE, "Malformed value for " "relative_offset: %s", tok); @@ -1092,7 +1108,7 @@ static int DetectAsn1TestReal01(void) "content:\"Pablo\"; asn1:absolute_offset 0, " "oversize_length 130; sid:1;)"; sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "content:\"AA\"; asn1:relative_offset 2, " + "content:\"AA\"; asn1:relative_offset 0, " "oversize_length 130; sid:2;)"; sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " "content:\"lalala\"; asn1: oversize_length 2000; sid:3;)"; @@ -1171,7 +1187,7 @@ static int DetectAsn1TestReal02(void) "content:\"Pablo\"; asn1:absolute_offset 0, " "oversize_length 140; sid:1;)"; sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "content:\"AA\"; asn1:relative_offset 2, " + "content:\"AA\"; asn1:relative_offset 0, " "oversize_length 140; sid:2;)"; sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " "content:\"lalala\"; asn1: oversize_length 2000; sid:3;)"; @@ -1252,7 +1268,7 @@ static int DetectAsn1TestReal03(void) /** * \test DetectAsn1TestReal04 like the real test 02, but modified the * relative offset to check negative offset values, in this case - * start decoding from -7 bytes respect the content match "John" + * start decoding from -11 bytes respect the content match "John" */ static int DetectAsn1TestReal04(void) { @@ -1309,7 +1325,7 @@ static int DetectAsn1TestReal04(void) "content:\"Pablo\"; asn1:absolute_offset 0, " "oversize_length 140; sid:1;)"; sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "content:\"John\"; asn1:relative_offset -7, " + "content:\"John\"; asn1:relative_offset -11, " "oversize_length 140; sid:2;)"; sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " "content:\"lalala\"; asn1: oversize_length 2000; sid:3;)"; @@ -1328,6 +1344,64 @@ static int DetectAsn1TestReal04(void) return result; } +/** + * \test DetectAsn1TestReal05 like the real test 04, but modified the + * relative offset to check offset values which could read past the bounds + * of the buffer + */ +static int DetectAsn1TestReal05(void) +{ + int result = 0; + /* Check the start with AA (this is to test the relative_offset keyword) */ + uint8_t *buf = (uint8_t *) "AA\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" + "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" + "\x42\x01\x33\xA1\x0A\x43\x08""19710917" + "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" + "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" + "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" + "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" + "Jones""\xA0\x0A\x43\x08""19590717" + "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" + "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" + "\x42\x01\x33\xA1\x0A\x43\x08""19710917" + "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" + "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" + "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" + "\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05""Jones" + "\xA0\x0A\x43\x08""19590717"; + + uint16_t buflen = strlen((char *)buf) - 1; + + Packet *p[1]; + + p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); + + if (p[0] == NULL) + goto end; + + const char *sigs[3]; + sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; " + "content:\"John\"; asn1:relative_offset -100, " + "oversize_length 132; sid:1;)"; + sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " + "content:\"John\"; asn1:relative_offset -11, " + "oversize_length 132; sid:2;)"; + sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " + "content:\"John\"; asn1: relative_offset 5000, " + "oversize_length 132; sid:3;)"; + + uint32_t sid[3] = {1, 2, 3}; + + // The second signature should match + uint32_t results[1][3] = {{0, 1, 0}}; + + result = UTHGenericTest(p, 1, sigs, sid, (uint32_t *) results, 3); + + UTHFreePackets(p, 1); +end: + return result; +} + #endif /* UNITTESTS */ /** @@ -1364,6 +1438,7 @@ static void DetectAsn1RegisterTests(void) UtRegisterTest("DetectAsn1TestReal02", DetectAsn1TestReal02); UtRegisterTest("DetectAsn1TestReal03", DetectAsn1TestReal03); UtRegisterTest("DetectAsn1TestReal04", DetectAsn1TestReal04); + UtRegisterTest("DetectAsn1TestReal05", DetectAsn1TestReal05); #endif /* UNITTESTS */ } diff --git a/src/detect-asn1.h b/src/detect-asn1.h index c38d6439e729..9f350e25b131 100644 --- a/src/detect-asn1.h +++ b/src/detect-asn1.h @@ -36,7 +36,7 @@ typedef struct DetectAsn1Data_ { uint8_t flags; /* flags indicating the checks loaded */ uint32_t oversize_length; /* Length argument if needed */ - int32_t absolute_offset; /* Length argument if needed */ + uint16_t absolute_offset; /* Length argument if needed */ int32_t relative_offset; /* Length argument if needed */ } DetectAsn1Data; @@ -44,4 +44,3 @@ typedef struct DetectAsn1Data_ { void DetectAsn1Register (void); #endif /* __DETECT_ASN1_H__ */ - diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 00d043a1a706..009aeea00455 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -173,7 +173,7 @@ void DetectAppLayerMpmRegisterByParentId(DetectEngineCtx *de_ctx, for (int i = 0; i < transforms->cnt; i++) { char ttstr[64]; (void)snprintf(ttstr,sizeof(ttstr), "%s,", - sigmatch_table[transforms->transforms[i]].name); + sigmatch_table[transforms->transforms[i].transform].name); strlcat(xforms, ttstr, sizeof(xforms)); } xforms[strlen(xforms)-1] = '\0'; diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index f855353f078e..320ce6d3958f 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -207,6 +207,7 @@ #include "detect-transform-sha1.h" #include "detect-transform-sha256.h" #include "detect-transform-dotprefix.h" +#include "detect-transform-pcrexform.h" #include "util-rule-vars.h" @@ -582,6 +583,7 @@ void SigTableSetup(void) DetectTransformSha1Register(); DetectTransformSha256Register(); DetectTransformDotPrefixRegister(); + DetectTransformPcrexformRegister(); /* close keyword registration */ DetectBufferTypeCloseRegistration(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index f488ecac210f..842005814ac7 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -263,6 +263,7 @@ enum DetectKeywordId { DETECT_TRANSFORM_SHA1, DETECT_TRANSFORM_SHA256, DETECT_TRANSFORM_DOTPREFIX, + DETECT_TRANSFORM_PCREXFORM, /* make sure this stays last */ DETECT_TBLSIZE, diff --git a/src/detect-engine.c b/src/detect-engine.c index 3d38b5799c98..326060bf0caa 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -730,7 +730,10 @@ static HashListTable *g_buffer_type_hash = NULL; static int g_buffer_type_id = DETECT_SM_LIST_DYNAMIC_START; static int g_buffer_type_reg_closed = 0; -static DetectEngineTransforms no_transforms = { .transforms = { 0 }, .cnt = 0, }; +static DetectEngineTransforms no_transforms = { + .transforms[0] = {0, NULL}, + .cnt = 0, +}; int DetectBufferTypeMaxId(void) { @@ -763,6 +766,19 @@ static char DetectBufferTypeCompareFunc(void *data1, uint16_t len1, void *data2, static void DetectBufferTypeFreeFunc(void *data) { DetectBufferType *map = (DetectBufferType *)data; + + /* Release transformation option memory, if any */ + for (int i = 0; i < map->transforms.cnt; i++) { + if (map->transforms.transforms[i].options == NULL) + continue; + if (sigmatch_table[map->transforms.transforms[i].transform].Free == NULL) { + SCLogError(SC_ERR_UNIMPLEMENTED, + "%s allocates transform option memory but has no free routine", + sigmatch_table[map->transforms.transforms[i].transform].name); + continue; + } + sigmatch_table[map->transforms.transforms[i].transform].Free(NULL, map->transforms.transforms[i].options); + } if (map != NULL) { SCFree(map); } @@ -973,7 +989,7 @@ int DetectBufferSetActiveList(Signature *s, const int list) { BUG_ON(s->init_data == NULL); - if (s->init_data->list && s->init_data->transform_cnt) { + if (s->init_data->list && s->init_data->transforms.cnt) { return -1; } s->init_data->list = list; @@ -986,19 +1002,19 @@ int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s) { BUG_ON(s->init_data == NULL); - if (s->init_data->transform_cnt) { + if (s->init_data->list && s->init_data->transforms.cnt) { if (s->init_data->list == DETECT_SM_LIST_NOTSET || s->init_data->list < DETECT_SM_LIST_DYNAMIC_START) { SCLogError(SC_ERR_INVALID_SIGNATURE, "previous transforms not consumed " "(list: %u, transform_cnt %u)", s->init_data->list, - s->init_data->transform_cnt); + s->init_data->transforms.cnt); SCReturnInt(-1); } SCLogDebug("buffer %d has transform(s) registered: %d", - s->init_data->list, s->init_data->transforms[0]); + s->init_data->list, s->init_data->transforms.cnt); int new_list = DetectBufferTypeGetByIdTransforms(de_ctx, s->init_data->list, - s->init_data->transforms, s->init_data->transform_cnt); + s->init_data->transforms.transforms, s->init_data->transforms.cnt); if (new_list == -1) { SCReturnInt(-1); } @@ -1006,7 +1022,7 @@ int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s) s->init_data->list = new_list; s->init_data->list_set = false; // reset transforms now that we've set up the list - s->init_data->transform_cnt = 0; + s->init_data->transforms.cnt = 0; } SCReturnInt(0); @@ -1150,11 +1166,11 @@ void InspectionBufferApplyTransforms(InspectionBuffer *buffer, { if (transforms) { for (int i = 0; i < DETECT_TRANSFORMS_MAX; i++) { - const int id = transforms->transforms[i]; + const int id = transforms->transforms[i].transform; if (id == 0) break; BUG_ON(sigmatch_table[id].Transform == NULL); - sigmatch_table[id].Transform(buffer); + sigmatch_table[id].Transform(buffer, transforms->transforms[i].options); SCLogDebug("applied transform %s", sigmatch_table[id].name); } } @@ -1242,7 +1258,7 @@ void DetectBufferTypeCloseRegistration(void) } int DetectBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id, - int *transforms, int transform_cnt) + TransformData *transforms, int transform_cnt) { const DetectBufferType *base_map = DetectBufferTypeGetById(de_ctx, id); if (!base_map) { diff --git a/src/detect-engine.h b/src/detect-engine.h index 7bb232a2061b..6ef796134d31 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -55,7 +55,7 @@ void DetectBufferTypeRegisterValidateCallback(const char *name, bool (*ValidateCallback)(const Signature *, const char **sigerror)); int DetectBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id, - int *transforms, int transform_cnt); + TransformData *transforms, int transform_cnt); const char *DetectBufferTypeGetNameById(const DetectEngineCtx *de_ctx, const int id); bool DetectBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id); bool DetectBufferTypeSupportsPacketGetById(const DetectEngineCtx *de_ctx, const int id); diff --git a/src/detect-parse.c b/src/detect-parse.c index d6b72f757cde..c4705de37b83 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -84,7 +84,7 @@ static void SigMatchTransferSigMatchAcrossLists(SigMatch *sm, typedef struct SigDuplWrapper_ { /* the signature we want to wrap */ Signature *s; - /* the signature right before the above signatue in the det_ctx->sig_list */ + /* the signature right before the above signature in the det_ctx->sig_list */ Signature *s_prev; } SigDuplWrapper; @@ -1066,7 +1066,7 @@ static inline int SigParseToken(char **input, char *output, * Parses rule tokens that may be lists such as addresses and ports * handling the case when they may not be lists. * - * \param input ouble pointer to input buffer, will be advanced as input is + * \param input double pointer to input buffer, will be advanced as input is * parsed. * \param output buffer to copy token into. * \param output_size length of output buffer. @@ -1292,7 +1292,7 @@ Signature *SigAlloc (void) /** * \internal - * \brief Free Medadata list + * \brief Free Metadata list * * \param s Pointer to the signature */ @@ -1386,6 +1386,15 @@ void SigFree(DetectEngineCtx *de_ctx, Signature *s) IPOnlyCIDRListFree(s->CidrSrc); int i; + + if (s->init_data && s->init_data->transforms.cnt) { + for(i = 0; i < s->init_data->transforms.cnt; i++) { + if (s->init_data->transforms.transforms[i].options) { + SCFree(s->init_data->transforms.transforms[i].options); + s->init_data->transforms.transforms[i].options = NULL; + } + } + } if (s->init_data) { const int nlists = s->init_data->smlists_array_size; for (i = 0; i < nlists; i++) { @@ -1439,7 +1448,7 @@ void SigFree(DetectEngineCtx *de_ctx, Signature *s) SCFree(s); } -int DetectSignatureAddTransform(Signature *s, int transform) +int DetectSignatureAddTransform(Signature *s, int transform, void *options) { /* we only support buffers */ if (s->init_data->list == 0) { @@ -1449,10 +1458,18 @@ int DetectSignatureAddTransform(Signature *s, int transform) SCLogError(SC_ERR_INVALID_SIGNATURE, "transforms must directly follow stickybuffers"); SCReturnInt(-1); } - if (s->init_data->transform_cnt >= DETECT_TRANSFORMS_MAX) { + if (s->init_data->transforms.cnt >= DETECT_TRANSFORMS_MAX) { SCReturnInt(-1); } - s->init_data->transforms[s->init_data->transform_cnt++] = transform; + + s->init_data->transforms.transforms[s->init_data->transforms.cnt].transform = transform; + s->init_data->transforms.transforms[s->init_data->transforms.cnt].options = options; + + s->init_data->transforms.cnt++; + SCLogDebug("Added transform #%d [%s]", + s->init_data->transforms.cnt, + s->sig_str); + SCReturnInt(0); } @@ -1591,7 +1608,7 @@ static int SigMatchListLen(SigMatch *sm) } /** \brief convert SigMatch list to SigMatchData array - * \note ownership of sm->ctx is transfered to smd->ctx + * \note ownership of sm->ctx is transferred to smd->ctx */ SigMatchData* SigMatchList2DataArray(SigMatch *head) { @@ -2300,7 +2317,7 @@ static inline int DetectEngineSignatureIsDuplicate(DetectEngineCtx *de_ctx, * If the signature is bidirectional it should append two signatures * (with the addresses switched) into the list. Also handle duplicate * signatures. In case of duplicate sigs, use the ones that have the - * latest revision. We use the sid and the msg to identifiy duplicate + * latest revision. We use the sid and the msg to identify duplicate * sigs. If 2 sigs have the same sid and gid, they are duplicates. * * \param de_ctx Pointer to the Detection Engine Context. @@ -4071,7 +4088,7 @@ static int SigParseBidirWithSameSrcAndDest02(void) SigFree(de_ctx, s); - // Source is a subset of destinationn + // Source is a subset of destination s = SigInit(de_ctx, "alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:1; rev:1;)"); FAIL_IF_NULL(s); diff --git a/src/detect-parse.h b/src/detect-parse.h index 2e9d35465819..be6a6a16afce 100644 --- a/src/detect-parse.h +++ b/src/detect-parse.h @@ -83,7 +83,7 @@ SigMatch *DetectGetLastSMFromLists(const Signature *s, ...); SigMatch *DetectGetLastSMByListPtr(const Signature *s, SigMatch *sm_list, ...); SigMatch *DetectGetLastSMByListId(const Signature *s, int list_id, ...); -int DetectSignatureAddTransform(Signature *s, int transform); +int DetectSignatureAddTransform(Signature *s, int transform, void *options); int WARN_UNUSED DetectSignatureSetAppProto(Signature *s, AppProto alproto); /* parse regex setup and free util funcs */ diff --git a/src/detect-pkt-data.c b/src/detect-pkt-data.c index 72d5d5912338..792597e9d895 100644 --- a/src/detect-pkt-data.c +++ b/src/detect-pkt-data.c @@ -71,7 +71,7 @@ void DetectPktDataRegister(void) static int DetectPktDataSetup (DetectEngineCtx *de_ctx, Signature *s, const char *unused) { SCEnter(); - if (s->init_data->transform_cnt) { + if (s->init_data->transforms.cnt) { SCLogError(SC_ERR_INVALID_SIGNATURE, "previous transforms not consumed before 'pkt_data'"); SCReturnInt(-1); diff --git a/src/detect-transform-compress-whitespace.c b/src/detect-transform-compress-whitespace.c index 5b54c00b304f..4087b1211169 100644 --- a/src/detect-transform-compress-whitespace.c +++ b/src/detect-transform-compress-whitespace.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -20,7 +20,7 @@ * * \author Victor Julien * - * Implements the compress_whitespace tranform keyword + * Implements the compress_whitespace transform keyword */ #include "suricata-common.h" @@ -37,7 +37,7 @@ static int DetectTransformCompressWhitespaceSetup (DetectEngineCtx *, Signature *, const char *); static void DetectTransformCompressWhitespaceRegisterTests(void); -static void TransformCompressWhitespace(InspectionBuffer *buffer); +static void TransformCompressWhitespace(InspectionBuffer *buffer, void *options); void DetectTransformCompressWhitespaceRegister(void) { @@ -69,11 +69,11 @@ void DetectTransformCompressWhitespaceRegister(void) static int DetectTransformCompressWhitespaceSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) { SCEnter(); - int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_COMPRESS_WHITESPACE); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_COMPRESS_WHITESPACE, NULL); SCReturnInt(r); } -static void TransformCompressWhitespace(InspectionBuffer *buffer) +static void TransformCompressWhitespace(InspectionBuffer *buffer, void *options) { const uint8_t *input = buffer->inspect; const uint32_t input_len = buffer->inspect_len; @@ -133,7 +133,7 @@ static int DetectTransformCompressWhitespaceTest01(void) InspectionBufferInit(&buffer, 8); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformCompressWhitespace(&buffer); + TransformCompressWhitespace(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; @@ -152,7 +152,7 @@ static int DetectTransformCompressWhitespaceTest02(void) PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); TransformDoubleWhitespace(&buffer); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformCompressWhitespace(&buffer); + TransformCompressWhitespace(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; diff --git a/src/detect-transform-dotprefix.c b/src/detect-transform-dotprefix.c index 3c18b19a9283..b0fa5c6835c4 100644 --- a/src/detect-transform-dotprefix.c +++ b/src/detect-transform-dotprefix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Open Information Security Foundation +/* Copyright (C) 2020 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 @@ -39,7 +39,7 @@ static int DetectTransformDotPrefixSetup (DetectEngineCtx *, Signature *, const char *); static void DetectTransformDotPrefixRegisterTests(void); -static void TransformDotPrefix(InspectionBuffer *buffer); +static void TransformDotPrefix(InspectionBuffer *buffer, void *options); void DetectTransformDotPrefixRegister(void) { @@ -68,7 +68,7 @@ void DetectTransformDotPrefixRegister(void) static int DetectTransformDotPrefixSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) { SCEnter(); - int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_DOTPREFIX); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_DOTPREFIX, NULL); SCReturnInt(r); } @@ -102,7 +102,7 @@ static int DetectTransformDotPrefixSetup (DetectEngineCtx *de_ctx, Signature *s, * 4. something.google.co.uk --> match * 5. google.com --> no match */ -static void TransformDotPrefix(InspectionBuffer *buffer) +static void TransformDotPrefix(InspectionBuffer *buffer, void *options) { const size_t input_len = buffer->inspect_len; @@ -128,7 +128,7 @@ static int DetectTransformDotPrefixTest01(void) InspectionBufferInit(&buffer, input_len); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformDotPrefix(&buffer); + TransformDotPrefix(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); FAIL_IF_NOT(buffer.inspect_len == result_len); FAIL_IF_NOT(strncmp(result, (const char *)buffer.inspect, result_len) == 0); @@ -148,7 +148,7 @@ static int DetectTransformDotPrefixTest02(void) InspectionBufferInit(&buffer, input_len); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformDotPrefix(&buffer); + TransformDotPrefix(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); FAIL_IF_NOT(buffer.inspect_len == result_len); FAIL_IF_NOT(strncmp(result, (const char *)buffer.inspect, result_len) == 0); diff --git a/src/detect-transform-md5.c b/src/detect-transform-md5.c index 78d99f8615e5..a2af21efdd2a 100644 --- a/src/detect-transform-md5.c +++ b/src/detect-transform-md5.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2018 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -37,7 +37,7 @@ static int DetectTransformToMd5Setup (DetectEngineCtx *, Signature *, const char *); #ifdef HAVE_NSS static void DetectTransformToMd5RegisterTests(void); -static void TransformToMd5(InspectionBuffer *buffer); +static void TransformToMd5(InspectionBuffer *buffer, void *options); #endif void DetectTransformMd5Register(void) @@ -78,11 +78,11 @@ static int DetectTransformToMd5Setup (DetectEngineCtx *de_ctx, Signature *s, con static int DetectTransformToMd5Setup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) { SCEnter(); - int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_MD5); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_MD5, NULL); SCReturnInt(r); } -static void TransformToMd5(InspectionBuffer *buffer) +static void TransformToMd5(InspectionBuffer *buffer, void *options) { const uint8_t *input = buffer->inspect; const uint32_t input_len = buffer->inspect_len; @@ -112,7 +112,7 @@ static int DetectTransformToMd5Test01(void) InspectionBufferInit(&buffer, 8); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformToMd5(&buffer); + TransformToMd5(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; diff --git a/src/detect-transform-pcrexform.c b/src/detect-transform-pcrexform.c new file mode 100644 index 000000000000..a489232d7b83 --- /dev/null +++ b/src/detect-transform-pcrexform.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2020 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. + */ + +/** + * \file + * + * \author Jeff Lucovsky + * + * Implements the pcrexform transform keyword with option support + */ + +#include "suricata-common.h" + +#include "detect.h" +#include "detect-engine.h" +#include "detect-parse.h" +#include "detect-transform-pcrexform.h" + +typedef DetectParseRegex DetectTransformPcrexformData; + +static int DetectTransformPcrexformSetup (DetectEngineCtx *, Signature *, const char *); +static void DetectTransformPcrexformFree(DetectEngineCtx *, void *); +static void DetectTransformPcrexform(InspectionBuffer *buffer, void *options); + +void DetectTransformPcrexformRegister(void) +{ + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].name = "pcrexform"; + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].desc = + "modify buffer via PCRE before inspection"; + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].url = "/rules/transforms.html#pcre-xform"; + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].Transform = + DetectTransformPcrexform; + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].Free = + DetectTransformPcrexformFree; + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].Setup = + DetectTransformPcrexformSetup; + sigmatch_table[DETECT_TRANSFORM_PCREXFORM].flags |= SIGMATCH_QUOTES_MANDATORY; +} + +static void DetectTransformPcrexformFree(DetectEngineCtx *de_ctx, void *ptr) +{ + if (ptr != NULL) { + DetectTransformPcrexformData *pxd = (DetectTransformPcrexformData *) ptr; + SCFree(pxd); + } +} +/** + * \internal + * \brief Apply the pcrexform keyword to the last pattern match + * \param det_ctx detection engine ctx + * \param s signature + * \param regexstr options string + * \retval 0 ok + * \retval -1 failure + */ +static int DetectTransformPcrexformSetup (DetectEngineCtx *de_ctx, Signature *s, const char *regexstr) +{ + SCEnter(); + + // Create pxd from regexstr + DetectTransformPcrexformData *pxd = SCCalloc(sizeof(*pxd), 1); + if (pxd == NULL) { + SCLogDebug("pxd allocation failed"); + SCReturnInt(-1); + } + + DetectSetupParseRegexes(regexstr, pxd); + + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_PCREXFORM, pxd); + if (r != 0) { + SCFree(pxd); + } + + SCReturnInt(r); +} + +static void DetectTransformPcrexform(InspectionBuffer *buffer, void *options) +{ + const char *input = (const char *)buffer->inspect; + const uint32_t input_len = buffer->inspect_len; + DetectTransformPcrexformData *pxd = options; + + int ov[MAX_SUBSTRINGS]; + int ret = DetectParsePcreExecLen(pxd, input, input_len, 0, 0, ov, MAX_SUBSTRINGS); + + if (ret > 0) { + const char *str; + ret = pcre_get_substring((char *) buffer->inspect, ov, + MAX_SUBSTRINGS, ret - 1, &str); + + if (ret >= 0) { + InspectionBufferCopy(buffer, (uint8_t *)str, (uint32_t) ret); + pcre_free_substring(str); + } + } +} diff --git a/src/detect-transform-pcrexform.h b/src/detect-transform-pcrexform.h new file mode 100644 index 000000000000..0a807d751b8d --- /dev/null +++ b/src/detect-transform-pcrexform.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2020 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. + */ + +/** + * \file + * + * \author Jeff Lucovsky inspect; const uint32_t input_len = buffer->inspect_len; @@ -112,7 +112,7 @@ static int DetectTransformToSha1Test01(void) InspectionBufferInit(&buffer, 8); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformToSha1(&buffer); + TransformToSha1(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; diff --git a/src/detect-transform-sha256.c b/src/detect-transform-sha256.c index 9ab67556257c..b28b5492df43 100644 --- a/src/detect-transform-sha256.c +++ b/src/detect-transform-sha256.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -37,7 +37,7 @@ static int DetectTransformToSha256Setup (DetectEngineCtx *, Signature *, const char *); #ifdef HAVE_NSS static void DetectTransformToSha256RegisterTests(void); -static void TransformToSha256(InspectionBuffer *buffer); +static void TransformToSha256(InspectionBuffer *buffer, void *options); #endif void DetectTransformSha256Register(void) @@ -78,11 +78,11 @@ static int DetectTransformToSha256Setup (DetectEngineCtx *de_ctx, Signature *s, static int DetectTransformToSha256Setup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) { SCEnter(); - int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_SHA256); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_SHA256, NULL); SCReturnInt(r); } -static void TransformToSha256(InspectionBuffer *buffer) +static void TransformToSha256(InspectionBuffer *buffer, void *options) { const uint8_t *input = buffer->inspect; const uint32_t input_len = buffer->inspect_len; @@ -112,7 +112,7 @@ static int DetectTransformToSha256Test01(void) InspectionBufferInit(&buffer, 8); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformToSha256(&buffer); + TransformToSha256(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; diff --git a/src/detect-transform-strip-whitespace.c b/src/detect-transform-strip-whitespace.c index 9b444f9c2bb7..6574fdbc5f91 100644 --- a/src/detect-transform-strip-whitespace.c +++ b/src/detect-transform-strip-whitespace.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2020 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 @@ -37,7 +37,7 @@ static int DetectTransformStripWhitespaceSetup (DetectEngineCtx *, Signature *, const char *); static void DetectTransformStripWhitespaceRegisterTests(void); -static void TransformStripWhitespace(InspectionBuffer *buffer); +static void TransformStripWhitespace(InspectionBuffer *buffer, void *options); void DetectTransformStripWhitespaceRegister(void) { @@ -68,11 +68,11 @@ void DetectTransformStripWhitespaceRegister(void) static int DetectTransformStripWhitespaceSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) { SCEnter(); - int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_STRIP_WHITESPACE); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_STRIP_WHITESPACE, NULL); SCReturnInt(r); } -static void TransformStripWhitespace(InspectionBuffer *buffer) +static void TransformStripWhitespace(InspectionBuffer *buffer, void *options) { const uint8_t *input = buffer->inspect; const uint32_t input_len = buffer->inspect_len; @@ -124,7 +124,7 @@ static int DetectTransformStripWhitespaceTest01(void) InspectionBufferInit(&buffer, 8); InspectionBufferSetup(&buffer, input, input_len); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformStripWhitespace(&buffer); + TransformStripWhitespace(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; @@ -143,7 +143,7 @@ static int DetectTransformStripWhitespaceTest02(void) PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); TransformDoubleWhitespace(&buffer); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformStripWhitespace(&buffer); + TransformStripWhitespace(&buffer, NULL); PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); InspectionBufferFree(&buffer); PASS; diff --git a/src/detect.h b/src/detect.h index 8d6d66559198..dbb80918407b 100644 --- a/src/detect.h +++ b/src/detect.h @@ -366,8 +366,13 @@ typedef struct InspectionBufferMultipleForList { uint32_t init:1; /**< first time used this run. Used for clean logic */ } InspectionBufferMultipleForList; +typedef struct TransformData_ { + int transform; + void *options; +} TransformData; + typedef struct DetectEngineTransforms { - int transforms[DETECT_TRANSFORMS_MAX]; + TransformData transforms[DETECT_TRANSFORMS_MAX]; int cnt; } DetectEngineTransforms; @@ -498,8 +503,7 @@ typedef struct SignatureInitData_ { int list; bool list_set; - int transforms[DETECT_TRANSFORMS_MAX]; - int transform_cnt; + DetectEngineTransforms transforms; /** score to influence rule grouping. A higher value leads to a higher * likelihood of a rulegroup with this sig ending up as a contained @@ -1183,7 +1187,7 @@ typedef struct SigTableElmt_ { uint8_t flags, File *, const Signature *, const SigMatchCtx *); /** InspectionBuffer transformation callback */ - void (*Transform)(InspectionBuffer *); + void (*Transform)(InspectionBuffer *, void *context); /** keyword setup function pointer */ int (*Setup)(DetectEngineCtx *, Signature *, const char *); diff --git a/src/suricata.c b/src/suricata.c index 567fcd4cfee3..675747dca752 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -2064,7 +2064,11 @@ static int StartInternalRunMode(SCInstance *suri, int argc, char **argv) ListKeywords(suri->keyword_info); return TM_ECODE_DONE; case RUNMODE_LIST_APP_LAYERS: - ListAppLayerProtocols(); + if (suri->conf_filename != NULL) { + ListAppLayerProtocols(suri->conf_filename); + } else { + ListAppLayerProtocols(DEFAULT_CONF_FILE); + } return TM_ECODE_DONE; case RUNMODE_PRINT_VERSION: PrintVersion(); diff --git a/src/util-log-redis.c b/src/util-log-redis.c index b6ff2b6717c0..a145e4f564bf 100644 --- a/src/util-log-redis.c +++ b/src/util-log-redis.c @@ -67,6 +67,7 @@ static SCLogRedisContext *SCLogRedisContextAlloc(void) ctx->async = NULL; #endif ctx->batch_count = 0; + ctx->last_push = 0; ctx->tried = 0; return ctx; @@ -92,6 +93,7 @@ static SCLogRedisContext *SCLogRedisContextAsyncAlloc(void) ctx->ev_base = NULL; ctx->connected = 0; ctx->batch_count = 0; + ctx->last_push = 0; ctx->tried = 0; return ctx; @@ -201,7 +203,11 @@ static int SCConfLogReopenAsyncRedis(LogFileCtx *log_ctx) return -1; } - ctx->async = redisAsyncConnect(redis_server, redis_port); + if (strchr(redis_server, '/') == NULL) { + ctx->async = redisAsyncConnect(redis_server, redis_port); + } else { + ctx->async = redisAsyncConnectUnix(redis_server); + } if (ctx->ev_base != NULL) { event_base_free(ctx->ev_base); @@ -295,7 +301,12 @@ static int SCConfLogReopenSyncRedis(LogFileCtx *log_ctx) if (ctx->sync != NULL) { redisFree(ctx->sync); } - ctx->sync = redisConnect(redis_server, redis_port); + + if (strchr(redis_server, '/') == NULL) { + ctx->sync = redisConnect(redis_server, redis_port); + } else { + ctx->sync = redisConnectUnix(redis_server); + } if (ctx->sync == NULL) { SCLogError(SC_ERR_SOCKET, "Error connecting to redis server."); ctx->tried = time(NULL); @@ -338,11 +349,14 @@ static int SCLogRedisWriteSync(LogFileCtx *file_ctx, const char *string) file_ctx->redis_setup.command, file_ctx->redis_setup.key, string); - if (ctx->batch_count == file_ctx->redis_setup.batch_size) { + time_t now = time(NULL); + if ((ctx->batch_count == file_ctx->redis_setup.batch_size) || (ctx->last_push < now)) { redisReply *reply; int i; + int batch_size = ctx->batch_count; ctx->batch_count = 0; - for (i = 0; i <= file_ctx->redis_setup.batch_size; i++) { + ctx->last_push = now; + for (i = 0; i <= batch_size; i++) { if (redisGetReply(redis, (void **)&reply) == REDIS_OK) { freeReplyObject(reply); ret = 0; @@ -360,6 +374,12 @@ static int SCLogRedisWriteSync(LogFileCtx *file_ctx, const char *string) redis = ctx->sync; if (redis) { SCLogInfo("Reconnected to redis server"); + redisAppendCommand(redis, "%s %s %s", + file_ctx->redis_setup.command, + file_ctx->redis_setup.key, + string); + ctx->batch_count++; + return 0; } else { SCLogInfo("Unable to reconnect to redis server"); return -1; diff --git a/src/util-log-redis.h b/src/util-log-redis.h index 0153151ebaa1..ec4a4aff73c5 100644 --- a/src/util-log-redis.h +++ b/src/util-log-redis.h @@ -55,6 +55,7 @@ typedef struct SCLogRedisContext_ { #endif /* HAVE_LIBEVENT */ time_t tried; int batch_count; + time_t last_push; } SCLogRedisContext; void SCLogRedisInit(void); diff --git a/src/util-running-modes.c b/src/util-running-modes.c index 9ff1cade0d80..42c91027643e 100644 --- a/src/util-running-modes.c +++ b/src/util-running-modes.c @@ -41,9 +41,9 @@ int ListKeywords(const char *keyword_info) exit(EXIT_SUCCESS); } -int ListAppLayerProtocols() +int ListAppLayerProtocols(const char *conf_filename) { - if (ConfYamlLoadFile(DEFAULT_CONF_FILE) != -1) + if (ConfYamlLoadFile(conf_filename) != -1) SCLogLoadConfig(0, 0); MpmTableSetup(); SpmTableSetup(); diff --git a/src/util-running-modes.h b/src/util-running-modes.h index f047e02dde36..ca3bc8c28dd3 100644 --- a/src/util-running-modes.h +++ b/src/util-running-modes.h @@ -24,6 +24,6 @@ #define __UTIL_RUNNING_MODES_H__ int ListKeywords(const char *keyword_info); -int ListAppLayerProtocols(void); +int ListAppLayerProtocols(const char *conf_filename); #endif /* __UTIL_RUNNING_MODES_H__ */