Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/detect-app-layer-protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ static int DetectAppLayerProtocolPacketMatch(
const DetectAppLayerProtocolData *data = (const DetectAppLayerProtocolData *)ctx;

/* if the sig is PD-only we only match when PD packet flags are set */
if ((s->flags & SIG_FLAG_PDONLY) &&
(p->flags & (PKT_PROTO_DETECT_TS_DONE|PKT_PROTO_DETECT_TC_DONE)) == 0)
{
if (s->type == SIG_TYPE_PDONLY &&
(p->flags & (PKT_PROTO_DETECT_TS_DONE | PKT_PROTO_DETECT_TC_DONE)) == 0) {
SCLogDebug("packet %"PRIu64": flags not set", p->pcap_cnt);
SCReturnInt(0);
}
Expand Down Expand Up @@ -258,7 +257,7 @@ static int PrefilterSetupAppProto(DetectEngineCtx *de_ctx, SigGroupHead *sgh)

static bool PrefilterAppProtoIsPrefilterable(const Signature *s)
{
if (s->flags & SIG_FLAG_PDONLY) {
if (s->type == SIG_TYPE_PDONLY) {
SCLogDebug("prefilter on PD %u", s->id);
return true;
}
Expand Down Expand Up @@ -548,9 +547,9 @@ static int DetectAppLayerProtocolTest14(void)
FAIL_IF(data->negated);

SigGroupBuild(de_ctx);
FAIL_IF_NOT(s1->flags & SIG_FLAG_PDONLY);
FAIL_IF_NOT(s2->flags & SIG_FLAG_PDONLY);
FAIL_IF(s3->flags & SIG_FLAG_PDONLY); // failure now
FAIL_IF_NOT(s1->type == SIG_TYPE_PDONLY);
FAIL_IF_NOT(s2->type == SIG_TYPE_PDONLY);
FAIL_IF(s3->type == SIG_TYPE_PDONLY); // failure now

DetectEngineCtxFree(de_ctx);
PASS;
Expand Down
15 changes: 12 additions & 3 deletions src/detect-engine-alert.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,19 @@ static inline void FlowApplySignatureActions(
* - match is in applayer
* - match is in stream */
if (s->action & (ACTION_DROP | ACTION_PASS)) {
if ((pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) ||
(s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_LIKE_IPONLY | SIG_FLAG_PDONLY |
SIG_FLAG_APPLAYER))) {
DEBUG_VALIDATE_BUG_ON(s->type == SIG_TYPE_NOT_SET);
DEBUG_VALIDATE_BUG_ON(s->type == SIG_TYPE_MAX);

enum SignaturePropertyFlowAction flow_action = signature_properties[s->type].flow_action;
if (flow_action == SIG_PROP_FLOW_ACTION_FLOW) {
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
} else if (flow_action == SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL) {
if (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) {
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
}
}

if (pa->flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW) {
SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
"PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
p->pcap_cnt, s->id, s->action, pa->flags);
Expand Down
77 changes: 69 additions & 8 deletions src/detect-engine-analyzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,42 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
}
jb_close(ctx.js);

switch (s->type) {
case SIG_TYPE_NOT_SET:
jb_set_string(ctx.js, "type", "unset");
break;
case SIG_TYPE_IPONLY:
jb_set_string(ctx.js, "type", "ip_only");
break;
case SIG_TYPE_LIKE_IPONLY:
jb_set_string(ctx.js, "type", "like_ip_only");
break;
case SIG_TYPE_PDONLY:
jb_set_string(ctx.js, "type", "pd_only");
break;
case SIG_TYPE_DEONLY:
jb_set_string(ctx.js, "type", "de_only");
break;
case SIG_TYPE_PKT:
jb_set_string(ctx.js, "type", "pkt");
break;
case SIG_TYPE_PKT_STREAM:
jb_set_string(ctx.js, "type", "pkt_stream");
break;
case SIG_TYPE_STREAM:
jb_set_string(ctx.js, "type", "stream");
break;
case SIG_TYPE_APPLAYER:
jb_set_string(ctx.js, "type", "app_layer");
break;
case SIG_TYPE_APP_TX:
jb_set_string(ctx.js, "type", "app_tx");
break;
case SIG_TYPE_MAX:
jb_set_string(ctx.js, "type", "error");
break;
}

jb_open_array(ctx.js, "flags");
if (s->flags & SIG_FLAG_SRC_ANY) {
jb_append_string(ctx.js, "src_any");
Expand All @@ -863,9 +899,6 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
if (s->flags & SIG_FLAG_APPLAYER) {
jb_append_string(ctx.js, "applayer");
}
if (s->flags & SIG_FLAG_IPONLY) {
jb_append_string(ctx.js, "ip_only");
}
if (s->flags & SIG_FLAG_REQUIRE_PACKET) {
jb_append_string(ctx.js, "need_packet");
}
Expand Down Expand Up @@ -899,9 +932,6 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
if (s->flags & SIG_FLAG_PREFILTER) {
jb_append_string(ctx.js, "prefilter");
}
if (s->flags & SIG_FLAG_PDONLY) {
jb_append_string(ctx.js, "proto_detect_only");
}
if (s->flags & SIG_FLAG_SRC_IS_TARGET) {
jb_append_string(ctx.js, "src_is_target");
}
Expand Down Expand Up @@ -1483,8 +1513,39 @@ void EngineAnalysisRules(const DetectEngineCtx *de_ctx,
fprintf(rule_engine_analysis_FD, "== Sid: %u ==\n", s->id);
fprintf(rule_engine_analysis_FD, "%s\n", line);

if (s->flags & SIG_FLAG_IPONLY) fprintf(rule_engine_analysis_FD, " Rule is ip only.\n");
if (s->flags & SIG_FLAG_PDONLY) fprintf(rule_engine_analysis_FD, " Rule is PD only.\n");
switch (s->type) {
case SIG_TYPE_NOT_SET:
break;
case SIG_TYPE_IPONLY:
fprintf(rule_engine_analysis_FD, " Rule is ip only.\n");
break;
case SIG_TYPE_LIKE_IPONLY:
fprintf(rule_engine_analysis_FD, " Rule is like ip only.\n");
break;
case SIG_TYPE_PDONLY:
fprintf(rule_engine_analysis_FD, " Rule is PD only.\n");
break;
case SIG_TYPE_DEONLY:
fprintf(rule_engine_analysis_FD, " Rule is DE only.\n");
break;
case SIG_TYPE_PKT:
fprintf(rule_engine_analysis_FD, " Rule is packet inspecting.\n");
break;
case SIG_TYPE_PKT_STREAM:
fprintf(rule_engine_analysis_FD, " Rule is packet and stream inspecting.\n");
break;
case SIG_TYPE_STREAM:
fprintf(rule_engine_analysis_FD, " Rule is stream inspecting.\n");
break;
case SIG_TYPE_APPLAYER:
fprintf(rule_engine_analysis_FD, " Rule is app-layer inspecting.\n");
break;
case SIG_TYPE_APP_TX:
fprintf(rule_engine_analysis_FD, " Rule is App-layer TX inspecting.\n");
break;
case SIG_TYPE_MAX:
break;
}
if (rule_ipv6_only) fprintf(rule_engine_analysis_FD, " Rule is IPv6 only.\n");
if (rule_ipv4_only) fprintf(rule_engine_analysis_FD, " Rule is IPv4 only.\n");
if (packet_buf) fprintf(rule_engine_analysis_FD, " Rule matches on packets.\n");
Expand Down
78 changes: 59 additions & 19 deletions src/detect-engine-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ static int RulesGroupByProto(DetectEngineCtx *de_ctx)
SigGroupHead *sgh_tc[256] = {NULL};

for ( ; s != NULL; s = s->next) {
if (s->flags & SIG_FLAG_IPONLY)
if (s->type == SIG_TYPE_IPONLY)
continue;

int p;
Expand Down Expand Up @@ -1168,7 +1168,7 @@ static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, uint8_t ipproto, u
DetectPort *list = NULL;
while (s) {
/* IP Only rules are handled separately */
if (s->flags & SIG_FLAG_IPONLY)
if (s->type == SIG_TYPE_IPONLY)
goto next;
if (!(s->proto.proto[ipproto / 8] & (1<<(ipproto % 8)) || (s->proto.flags & DETECT_PROTO_ANY)))
goto next;
Expand Down Expand Up @@ -1300,21 +1300,65 @@ static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, uint8_t ipproto, u

void SignatureSetType(DetectEngineCtx *de_ctx, Signature *s)
{
BUG_ON(s->type != SIG_TYPE_NOT_SET);
int iponly = 0;

/* see if the sig is dp only */
if (SignatureIsPDOnly(de_ctx, s) == 1) {
s->flags |= SIG_FLAG_PDONLY;
s->type = SIG_TYPE_PDONLY;

/* see if the sig is ip only */
/* see if the sig is ip only */
} else if ((iponly = SignatureIsIPOnly(de_ctx, s)) > 0) {
if (iponly == 1) {
s->flags |= SIG_FLAG_IPONLY;
s->type = SIG_TYPE_IPONLY;
} else if (iponly == 2) {
s->flags |= SIG_FLAG_LIKE_IPONLY;
s->type = SIG_TYPE_LIKE_IPONLY;
}
} else if (SignatureIsDEOnly(de_ctx, s) == 1) {
s->init_data->init_flags |= SIG_FLAG_INIT_DEONLY;
s->type = SIG_TYPE_DEONLY;

} else {
const bool has_match = s->init_data->smlists[DETECT_SM_LIST_MATCH] != NULL;
const bool has_pmatch = s->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL;
bool has_buffer_frame_engine = false;
bool has_buffer_packet_engine = false;
bool has_buffer_app_engine = false;

for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
const uint32_t id = s->init_data->buffers[x].id;

if (DetectEngineBufferTypeSupportsPacketGetById(de_ctx, id)) {
has_buffer_packet_engine = true;
} else if (DetectEngineBufferTypeSupportsFramesGetById(de_ctx, id)) {
has_buffer_frame_engine = true;
} else {
has_buffer_app_engine = true;
}
}

if (has_buffer_packet_engine) {
s->type = SIG_TYPE_PKT;
} else if (has_buffer_frame_engine || has_buffer_app_engine) {
s->type = SIG_TYPE_APP_TX;
} else if (has_pmatch) {
if ((s->flags & (SIG_FLAG_REQUIRE_PACKET | SIG_FLAG_REQUIRE_STREAM)) ==
SIG_FLAG_REQUIRE_PACKET) {
s->type = SIG_TYPE_PKT; // TODO review
} else if ((s->flags & (SIG_FLAG_REQUIRE_PACKET | SIG_FLAG_REQUIRE_STREAM)) ==
SIG_FLAG_REQUIRE_STREAM) {
s->type = SIG_TYPE_STREAM; // TODO review
} else {
s->type = SIG_TYPE_PKT_STREAM;
}
} else if (has_match) {
s->type = SIG_TYPE_PKT;

/* app-layer but no inspect engines */
} else if (s->flags & SIG_FLAG_APPLAYER) {
s->type = SIG_TYPE_APPLAYER;
} else {
s->type = SIG_TYPE_PKT;
}
}
}

Expand Down Expand Up @@ -1354,15 +1398,15 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx)

SCLogDebug("Signature %" PRIu32 ", internal id %" PRIu32 ", ptrs %p %p ", s->id, s->num, s, de_ctx->sig_array[s->num]);

if (s->flags & SIG_FLAG_PDONLY) {
if (s->type == SIG_TYPE_PDONLY) {
SCLogDebug("Signature %"PRIu32" is considered \"PD only\"", s->id);
} else if (s->flags & SIG_FLAG_IPONLY) {
} else if (s->type == SIG_TYPE_IPONLY) {
SCLogDebug("Signature %"PRIu32" is considered \"IP only\"", s->id);
cnt_iponly++;
} else if (SignatureIsInspectingPayload(de_ctx, s) == 1) {
SCLogDebug("Signature %"PRIu32" is considered \"Payload inspecting\"", s->id);
cnt_payload++;
} else if (s->init_data->init_flags & SIG_FLAG_INIT_DEONLY) {
} else if (s->type == SIG_TYPE_DEONLY) {
SCLogDebug("Signature %"PRIu32" is considered \"Decoder Event only\"", s->id);
cnt_deonly++;
} else if (s->flags & SIG_FLAG_APPLAYER) {
Expand Down Expand Up @@ -1684,11 +1728,9 @@ int SigAddressPrepareStage2(DetectEngineCtx *de_ctx)
/* now for every rule add the source group to our temp lists */
for (Signature *s = de_ctx->sig_list; s != NULL; s = s->next) {
SCLogDebug("s->id %"PRIu32, s->id);
if (s->flags & SIG_FLAG_IPONLY) {
if (s->type == SIG_TYPE_IPONLY) {
IPOnlyAddSignature(de_ctx, &de_ctx->io_ctx, s);
}

if (s->init_data->init_flags & SIG_FLAG_INIT_DEONLY) {
} else if (s->type == SIG_TYPE_DEONLY) {
DetectEngineAddDecoderEventSig(de_ctx, s);
}
}
Expand Down Expand Up @@ -1872,8 +1914,7 @@ static int SigMatchPrepare(DetectEngineCtx *de_ctx)
DetectEngineAppInspectionEngine2Signature(de_ctx, s);

/* built-ins */
int type;
for (type = 0; type < DETECT_SM_LIST_MAX; type++) {
for (int type = 0; type < DETECT_SM_LIST_MAX; type++) {
/* skip PMATCH if it is used in a stream 'app engine' instead */
if (type == DETECT_SM_LIST_PMATCH && (s->init_data->init_flags & SIG_FLAG_INIT_STATE_MATCH))
continue;
Expand All @@ -1888,16 +1929,15 @@ static int SigMatchPrepare(DetectEngineCtx *de_ctx)
EngineAnalysisRules2(de_ctx, s);
}
/* free lists. Ctx' are xferred to sm_arrays so won't get freed */
uint32_t i;
for (i = 0; i < DETECT_SM_LIST_MAX; i++) {
for (uint32_t i = 0; i < DETECT_SM_LIST_MAX; i++) {
SigMatch *sm = s->init_data->smlists[i];
while (sm != NULL) {
SigMatch *nsm = sm->next;
SigMatchFree(de_ctx, sm);
sm = nsm;
}
}
for (i = 0; i < (uint32_t)s->init_data->transforms.cnt; i++) {
for (uint32_t i = 0; i < (uint32_t)s->init_data->transforms.cnt; i++) {
if (s->init_data->transforms.transforms[i].options) {
int transform = s->init_data->transforms.transforms[i].transform;
sigmatch_table[transform].Free(
Expand Down
2 changes: 1 addition & 1 deletion src/detect-engine-iponly.c
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,7 @@ void IPOnlyPrepare(DetectEngineCtx *de_ctx)
void IPOnlyAddSignature(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx,
Signature *s)
{
if (!(s->flags & SIG_FLAG_IPONLY))
if (!(s->type == SIG_TYPE_IPONLY))
return;

SigIntId mapped_signum = IPOnlyTrackSigNum(io_ctx, s->num);
Expand Down
24 changes: 24 additions & 0 deletions src/detect-engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,21 @@ static DetectEngineAppInspectionEngine *g_app_inspect_engines = NULL;
static DetectEnginePktInspectionEngine *g_pkt_inspect_engines = NULL;
static DetectEngineFrameInspectionEngine *g_frame_inspect_engines = NULL;

// clang-format off
const struct SignatureProperties signature_properties[SIG_TYPE_MAX] = {
/* SIG_TYPE_NOT_SET */ { SIG_PROP_FLOW_ACTION_PACKET, },
/* SIG_TYPE_IPONLY */ { SIG_PROP_FLOW_ACTION_FLOW, },
/* SIG_TYPE_LIKE_IPONLY */ { SIG_PROP_FLOW_ACTION_FLOW, },
/* SIG_TYPE_PDONLY */ { SIG_PROP_FLOW_ACTION_FLOW, },
/* SIG_TYPE_DEONLY */ { SIG_PROP_FLOW_ACTION_PACKET, },
/* SIG_TYPE_PKT */ { SIG_PROP_FLOW_ACTION_PACKET, },
/* SIG_TYPE_PKT_STREAM */ { SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL, },
/* SIG_TYPE_STREAM */ { SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL, },
/* SIG_TYPE_APPLAYER */ { SIG_PROP_FLOW_ACTION_FLOW, },
/* SIG_TYPE_APP_TX */ { SIG_PROP_FLOW_ACTION_FLOW, },
};
// clang-format on

SCEnumCharMap det_ctx_event_table[] = {
#ifdef UNITTESTS
{ "TEST", DET_CTX_EVENT_TEST },
Expand Down Expand Up @@ -1314,6 +1329,15 @@ bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, con
return map->mpm;
}

bool DetectEngineBufferTypeSupportsFramesGetById(const DetectEngineCtx *de_ctx, const int id)
{
const DetectBufferType *map = DetectEngineBufferTypeGetById(de_ctx, id);
if (map == NULL)
return false;
SCLogDebug("map %p id %d frame? %d", map, id, map->frame);
return map->frame;
}

void DetectBufferTypeRegisterSetupCallback(const char *name,
void (*SetupCallback)(const DetectEngineCtx *, Signature *))
{
Expand Down
1 change: 1 addition & 0 deletions src/detect-engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, con
bool DetectEngineBufferTypeSupportsPacketGetById(const DetectEngineCtx *de_ctx, const int id);
bool DetectEngineBufferTypeSupportsMultiInstanceGetById(
const DetectEngineCtx *de_ctx, const int id);
bool DetectEngineBufferTypeSupportsFramesGetById(const DetectEngineCtx *de_ctx, const int id);
const char *DetectEngineBufferTypeGetDescriptionById(const DetectEngineCtx *de_ctx, const int id);
const DetectBufferType *DetectEngineBufferTypeGetById(const DetectEngineCtx *de_ctx, const int id);
int DetectEngineBufferTypeGetByIdTransforms(
Expand Down
2 changes: 1 addition & 1 deletion src/detect-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2126,7 +2126,7 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, const char *sigstr,
/* check what the type of this sig is */
SignatureSetType(de_ctx, sig);

if (sig->flags & SIG_FLAG_IPONLY) {
if (sig->type == SIG_TYPE_IPONLY) {
/* For IPOnly */
if (IPOnlySigParseAddress(de_ctx, sig, parser.src, SIG_DIREC_SRC ^ dir) < 0)
goto error;
Expand Down
1 change: 0 additions & 1 deletion src/detect-pcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,6 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, const char *r
if (DetectBufferGetActiveList(de_ctx, s) == -1)
goto error;

s->flags |= SIG_FLAG_APPLAYER;
sm_list = s->init_data->list;
} else {
switch (parsed_sm_list) {
Expand Down
5 changes: 1 addition & 4 deletions src/detect-threshold.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,10 +512,7 @@ static int DetectThresholdTestSig1(void)

SigGroupBuild(de_ctx);

if (s->flags & SIG_FLAG_IPONLY) {
printf("signature is ip-only: ");
goto end;
}
FAIL_IF(s->type == SIG_TYPE_IPONLY);

DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);

Expand Down
Loading