suricata
detect-app-layer-protocol.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2025 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22 */
23
24#include "suricata-common.h"
25#include "detect-engine.h"
26#include "detect-engine-build.h"
29#include "detect-parse.h"
31#include "app-layer.h"
32#include "app-layer-parser.h"
33#include "util-debug.h"
34#include "util-unittest.h"
36
37#ifdef UNITTESTS
38static void DetectAppLayerProtocolRegisterTests(void);
39#endif
40
41enum {
48};
49
55
56static int DetectAppLayerProtocolPacketMatch(
57 DetectEngineThreadCtx *det_ctx,
58 Packet *p, const Signature *s, const SigMatchCtx *ctx)
59{
60 SCEnter();
61
62 bool r = false;
64
65 /* if the sig is PD-only we only match when PD packet flags are set */
66 if (s->type == SIG_TYPE_PDONLY &&
68 SCLogDebug("packet %"PRIu64": flags not set", p->pcap_cnt);
69 SCReturnInt(0);
70 }
71
72 const Flow *f = p->flow;
73 if (f == NULL) {
74 SCLogDebug("packet %"PRIu64": no flow", p->pcap_cnt);
75 SCReturnInt(0);
76 }
77
78 switch (data->mode) {
80 if (data->negated) {
83 SCReturnInt(0);
84 r = AppProtoEquals(data->alproto, f->alproto_ts);
85 } else {
87 SCReturnInt(0);
88 r = AppProtoEquals(data->alproto, f->alproto_tc);
89 }
90 } else {
92 r = AppProtoEquals(data->alproto, f->alproto_ts);
93 } else {
94 r = AppProtoEquals(data->alproto, f->alproto_tc);
95 }
96 }
97 break;
99 if (data->negated) {
101 SCReturnInt(0);
102 r = AppProtoEquals(data->alproto, f->alproto_orig);
103 } else {
104 r = AppProtoEquals(data->alproto, f->alproto_orig);
105 }
106 break;
108 if (data->negated) {
109 if (f->alproto == ALPROTO_UNKNOWN)
110 SCReturnInt(0);
111 r = AppProtoEquals(data->alproto, f->alproto);
112 } else {
113 r = AppProtoEquals(data->alproto, f->alproto);
114 }
115 break;
117 if (data->negated) {
118 if (f->alproto_ts == ALPROTO_UNKNOWN)
119 SCReturnInt(0);
120 r = AppProtoEquals(data->alproto, f->alproto_ts);
121 } else {
122 r = AppProtoEquals(data->alproto, f->alproto_ts);
123 }
124 break;
126 if (data->negated) {
127 if (f->alproto_tc == ALPROTO_UNKNOWN)
128 SCReturnInt(0);
129 r = AppProtoEquals(data->alproto, f->alproto_tc);
130 } else {
131 r = AppProtoEquals(data->alproto, f->alproto_tc);
132 }
133 break;
135 if (data->negated) {
137 SCReturnInt(0);
138 r = AppProtoEquals(data->alproto, f->alproto_tc) ||
139 AppProtoEquals(data->alproto, f->alproto_ts);
140 } else {
141 r = AppProtoEquals(data->alproto, f->alproto_tc) ||
142 AppProtoEquals(data->alproto, f->alproto_ts);
143 }
144 break;
145 }
146 r = r ^ data->negated;
147 if (r) {
148 SCReturnInt(1);
149 }
150 SCReturnInt(0);
151}
152
153#define MAX_ALPROTO_NAME 50
154static DetectAppLayerProtocolData *DetectAppLayerProtocolParse(const char *arg, bool negate)
155{
157 AppProto alproto = ALPROTO_UNKNOWN;
158
159 char alproto_copy[MAX_ALPROTO_NAME];
160 char *sep = strchr(arg, ',');
161 char *alproto_name;
162 if (sep && sep - arg < MAX_ALPROTO_NAME) {
163 strlcpy(alproto_copy, arg, sep - arg + 1);
164 alproto_name = alproto_copy;
165 } else {
166 alproto_name = (char *)arg;
167 }
168 if (strcmp(alproto_name, "failed") == 0) {
169 alproto = ALPROTO_FAILED;
170 } else if (strcmp(alproto_name, "unknown") == 0) {
171 if (negate) {
172 SCLogError("app-layer-protocol "
173 "keyword can't use negation with protocol 'unknown'");
174 return NULL;
175 }
176 alproto = ALPROTO_UNKNOWN;
177 } else {
178 alproto = AppLayerGetProtoByName(alproto_name);
179 if (alproto == ALPROTO_UNKNOWN) {
180 SCLogError("app-layer-protocol "
181 "keyword supplied with unknown protocol \"%s\"",
182 alproto_name);
183 return NULL;
184 }
185 }
186 uint8_t mode = DETECT_ALPROTO_DIRECTION;
187 if (sep) {
188 if (strcmp(sep + 1, "final") == 0) {
190 } else if (strcmp(sep + 1, "original") == 0) {
191 mode = DETECT_ALPROTO_ORIG;
192 } else if (strcmp(sep + 1, "either") == 0) {
194 } else if (strcmp(sep + 1, "to_server") == 0) {
196 } else if (strcmp(sep + 1, "to_client") == 0) {
198 } else if (strcmp(sep + 1, "direction") == 0) {
200 } else {
201 SCLogError("app-layer-protocol "
202 "keyword supplied with unknown mode \"%s\"",
203 sep + 1);
204 return NULL;
205 }
206 }
207
208 data = SCMalloc(sizeof(DetectAppLayerProtocolData));
209 if (unlikely(data == NULL))
210 return NULL;
211 data->alproto = alproto;
212 data->negated = negate;
213 data->mode = mode;
214
215 return data;
216}
217
218static bool HasConflicts(const DetectAppLayerProtocolData *us,
219 const DetectAppLayerProtocolData *them)
220{
221 /* mixing negated and non negated is illegal */
222 if ((them->negated ^ us->negated) && them->mode == us->mode)
223 return true;
224 /* multiple non-negated is illegal */
225 if (!us->negated && them->mode == us->mode)
226 return true;
227 /* duplicate option */
228 if (us->alproto == them->alproto && them->mode == us->mode)
229 return true;
230
231 /* all good */
232 return false;
233}
234
235static int DetectAppLayerProtocolSetup(DetectEngineCtx *de_ctx,
236 Signature *s, const char *arg)
237{
238 DetectAppLayerProtocolData *data = NULL;
239
240 if (s->alproto != ALPROTO_UNKNOWN) {
241 SCLogError("Either we already "
242 "have the rule match on an app layer protocol set through "
243 "other keywords that match on this protocol, or have "
244 "already seen a non-negated app-layer-protocol.");
245 goto error;
246 }
247
248 data = DetectAppLayerProtocolParse(arg, s->init_data->negated);
249 if (data == NULL)
250 goto error;
251
253 for ( ; tsm != NULL; tsm = tsm->next) {
254 if (tsm->type == DETECT_APP_LAYER_PROTOCOL) {
256
257 if (HasConflicts(data, them)) {
258 SCLogError("can't mix "
259 "positive app-layer-protocol match with negated "
260 "match or match for 'failed'.");
261 goto error;
262 }
263 }
264 }
265
267 DETECT_SM_LIST_MATCH) == NULL) {
268 goto error;
269 }
270 return 0;
271
272error:
273 if (data != NULL)
274 SCFree(data);
275 return -1;
276}
277
278static void DetectAppLayerProtocolFree(DetectEngineCtx *de_ctx, void *ptr)
279{
280 SCFree(ptr);
281}
282
283/** \internal
284 * \brief prefilter function for protocol detect matching
285 */
286static void
287PrefilterPacketAppProtoMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
288{
289 const PrefilterPacketHeaderCtx *ctx = pectx;
290
291 if (!PrefilterPacketHeaderExtraMatch(ctx, p)) {
292 SCLogDebug("packet %"PRIu64": extra match failed", p->pcap_cnt);
293 SCReturn;
294 }
295
296 if (p->flow == NULL) {
297 SCLogDebug("packet %"PRIu64": no flow, no alproto", p->pcap_cnt);
298 SCReturn;
299 }
300
302 SCLogDebug("packet %"PRIu64": flags not set", p->pcap_cnt);
303 SCReturn;
304 }
305
306 Flow *f = p->flow;
307 AppProto alproto = ALPROTO_UNKNOWN;
308 bool negated = (bool)ctx->v1.u8[2];
309 switch (ctx->v1.u8[3]) {
311 if (p->flowflags & FLOW_PKT_TOSERVER) {
312 alproto = f->alproto_ts;
313 } else {
314 alproto = f->alproto_tc;
315 }
316 break;
318 alproto = f->alproto_orig;
319 break;
321 alproto = f->alproto;
322 break;
324 alproto = f->alproto_ts;
325 break;
327 alproto = f->alproto_tc;
328 break;
330 // check if either protocol toclient or toserver matches
331 // the one in the signature ctx
332 if (negated) {
333 if (f->alproto_tc != ALPROTO_UNKNOWN &&
334 !AppProtoEquals(ctx->v1.u16[0], f->alproto_tc)) {
335 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
336 } else if (f->alproto_ts != ALPROTO_UNKNOWN &&
337 !AppProtoEquals(ctx->v1.u16[0], f->alproto_ts)) {
338 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
339 }
340 } else {
341 if (AppProtoEquals(ctx->v1.u16[0], f->alproto_tc) ||
342 AppProtoEquals(ctx->v1.u16[0], f->alproto_ts)) {
343 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
344 }
345 }
346 // We return right away to avoid calling PrefilterAddSids again
347 return;
348 }
349
350 if (negated) {
351 if (alproto != ALPROTO_UNKNOWN) {
352 if (!AppProtoEquals(ctx->v1.u16[0], alproto)) {
353 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
354 }
355 }
356 } else {
357 if (AppProtoEquals(ctx->v1.u16[0], alproto)) {
358 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
359 }
360 }
361}
362
363static void
364PrefilterPacketAppProtoSet(PrefilterPacketHeaderValue *v, void *smctx)
365{
366 const DetectAppLayerProtocolData *a = smctx;
367 v->u16[0] = a->alproto;
368 v->u8[2] = (uint8_t)a->negated;
369 v->u8[3] = a->mode;
370}
371
372static bool
373PrefilterPacketAppProtoCompare(PrefilterPacketHeaderValue v, void *smctx)
374{
375 const DetectAppLayerProtocolData *a = smctx;
376 if (v.u16[0] == a->alproto && v.u8[2] == (uint8_t)a->negated && v.u8[3] == a->mode)
377 return true;
378 return false;
379}
380
381static int PrefilterSetupAppProto(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
382{
384 PrefilterPacketAppProtoSet, PrefilterPacketAppProtoCompare,
385 PrefilterPacketAppProtoMatch);
386}
387
388static bool PrefilterAppProtoIsPrefilterable(const Signature *s)
389{
390 if (s->type == SIG_TYPE_PDONLY) {
391 SCLogDebug("prefilter on PD %u", s->id);
392 return true;
393 }
394 return false;
395}
396
398{
399 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].name = "app-layer-protocol";
400 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].desc = "match on the detected app-layer protocol";
401 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].url = "/rules/app-layer.html#app-layer-protocol";
402 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].Match = DetectAppLayerProtocolPacketMatch;
403 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].Setup = DetectAppLayerProtocolSetup;
404 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].Free = DetectAppLayerProtocolFree;
405#ifdef UNITTESTS
406 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].RegisterTests = DetectAppLayerProtocolRegisterTests;
407#endif
410
412 sigmatch_table[DETECT_APP_LAYER_PROTOCOL].SupportsPrefilter = PrefilterAppProtoIsPrefilterable;
413}
414
415/**********************************Unittests***********************************/
416
417#ifdef UNITTESTS
418
419static int DetectAppLayerProtocolTest01(void)
420{
421 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", false);
422 FAIL_IF_NULL(data);
423 FAIL_IF(data->alproto != ALPROTO_HTTP);
424 FAIL_IF(data->negated != 0);
425 DetectAppLayerProtocolFree(NULL, data);
426 PASS;
427}
428
429static int DetectAppLayerProtocolTest02(void)
430{
431 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", true);
432 FAIL_IF_NULL(data);
433 FAIL_IF(data->alproto != ALPROTO_HTTP);
434 FAIL_IF(data->negated == 0);
435 DetectAppLayerProtocolFree(NULL, data);
436 PASS;
437}
438
439static int DetectAppLayerProtocolTest03(void)
440{
441 Signature *s = NULL;
442 DetectAppLayerProtocolData *data = NULL;
446
447 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
448 "(app-layer-protocol:http; sid:1;)");
449 FAIL_IF_NULL(s);
450
452
455
457 FAIL_IF(data->alproto != ALPROTO_HTTP);
458 FAIL_IF(data->negated);
460 PASS;
461}
462
463static int DetectAppLayerProtocolTest04(void)
464{
465 Signature *s = NULL;
466 DetectAppLayerProtocolData *data = NULL;
470
471 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
472 "(app-layer-protocol:!http; sid:1;)");
473 FAIL_IF_NULL(s);
476
479
481 FAIL_IF_NULL(data);
482 FAIL_IF(data->alproto != ALPROTO_HTTP);
483 FAIL_IF(data->negated == 0);
484
486 PASS;
487}
488
489static int DetectAppLayerProtocolTest05(void)
490{
491 Signature *s = NULL;
492 DetectAppLayerProtocolData *data = NULL;
496
497 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
498 "(app-layer-protocol:!http; app-layer-protocol:!smtp; sid:1;)");
499 FAIL_IF_NULL(s);
502
505
507 FAIL_IF_NULL(data);
508 FAIL_IF(data->alproto != ALPROTO_HTTP);
509 FAIL_IF(data->negated == 0);
510
512 FAIL_IF_NULL(data);
513 FAIL_IF(data->alproto != ALPROTO_SMTP);
514 FAIL_IF(data->negated == 0);
515
517 PASS;
518}
519
520static int DetectAppLayerProtocolTest06(void)
521{
522 Signature *s = NULL;
526
527 s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
528 "(app-layer-protocol:smtp; sid:1;)");
531 PASS;
532}
533
534static int DetectAppLayerProtocolTest07(void)
535{
536 Signature *s = NULL;
540
541 s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
542 "(app-layer-protocol:!smtp; sid:1;)");
545 PASS;
546}
547
548static int DetectAppLayerProtocolTest08(void)
549{
550 Signature *s = NULL;
554
555 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
556 "(app-layer-protocol:!smtp; app-layer-protocol:http; sid:1;)");
559 PASS;
560}
561
562static int DetectAppLayerProtocolTest09(void)
563{
564 Signature *s = NULL;
568
569 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
570 "(app-layer-protocol:http; app-layer-protocol:!smtp; sid:1;)");
573 PASS;
574}
575
576static int DetectAppLayerProtocolTest10(void)
577{
578 Signature *s = NULL;
582
583 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
584 "(app-layer-protocol:smtp; app-layer-protocol:!http; sid:1;)");
587 PASS;
588}
589
590static int DetectAppLayerProtocolTest11(void)
591{
592 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", false);
593 FAIL_IF_NULL(data);
595 FAIL_IF(data->negated != 0);
596 DetectAppLayerProtocolFree(NULL, data);
597 PASS;
598}
599
600static int DetectAppLayerProtocolTest12(void)
601{
602 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", true);
603 FAIL_IF_NULL(data);
605 FAIL_IF(data->negated == 0);
606 DetectAppLayerProtocolFree(NULL, data);
607 PASS;
608}
609
610static int DetectAppLayerProtocolTest13(void)
611{
612 Signature *s = NULL;
613 DetectAppLayerProtocolData *data = NULL;
617
618 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
619 "(app-layer-protocol:failed; sid:1;)");
620 FAIL_IF_NULL(s);
621
623
626
628 FAIL_IF(data->alproto != ALPROTO_FAILED);
629 FAIL_IF(data->negated);
631 PASS;
632}
633
634static int DetectAppLayerProtocolTest14(void)
635{
636 DetectAppLayerProtocolData *data = NULL;
640
641 Signature *s1 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
642 "(app-layer-protocol:http; flowbits:set,blah; sid:1;)");
643 FAIL_IF_NULL(s1);
648 FAIL_IF(data->alproto != ALPROTO_HTTP);
649 FAIL_IF(data->negated);
650
651 Signature *s2 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
652 "(app-layer-protocol:http; flow:to_client; sid:2;)");
653 FAIL_IF_NULL(s2);
658 FAIL_IF(data->alproto != ALPROTO_HTTP);
659 FAIL_IF(data->negated);
660
661 /* flow:established and other options not supported for PD-only */
662 Signature *s3 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
663 "(app-layer-protocol:http; flow:to_client,established; sid:3;)");
664 FAIL_IF_NULL(s3);
669 FAIL_IF(data->alproto != ALPROTO_HTTP);
670 FAIL_IF(data->negated);
671
673 FAIL_IF_NOT(s1->type == SIG_TYPE_PDONLY);
674 FAIL_IF_NOT(s2->type == SIG_TYPE_PDONLY);
675 FAIL_IF(s3->type == SIG_TYPE_PDONLY); // failure now
676
678 PASS;
679}
680
681
682static void DetectAppLayerProtocolRegisterTests(void)
683{
684 UtRegisterTest("DetectAppLayerProtocolTest01",
685 DetectAppLayerProtocolTest01);
686 UtRegisterTest("DetectAppLayerProtocolTest02",
687 DetectAppLayerProtocolTest02);
688 UtRegisterTest("DetectAppLayerProtocolTest03",
689 DetectAppLayerProtocolTest03);
690 UtRegisterTest("DetectAppLayerProtocolTest04",
691 DetectAppLayerProtocolTest04);
692 UtRegisterTest("DetectAppLayerProtocolTest05",
693 DetectAppLayerProtocolTest05);
694 UtRegisterTest("DetectAppLayerProtocolTest06",
695 DetectAppLayerProtocolTest06);
696 UtRegisterTest("DetectAppLayerProtocolTest07",
697 DetectAppLayerProtocolTest07);
698 UtRegisterTest("DetectAppLayerProtocolTest08",
699 DetectAppLayerProtocolTest08);
700 UtRegisterTest("DetectAppLayerProtocolTest09",
701 DetectAppLayerProtocolTest09);
702 UtRegisterTest("DetectAppLayerProtocolTest10",
703 DetectAppLayerProtocolTest10);
704 UtRegisterTest("DetectAppLayerProtocolTest11",
705 DetectAppLayerProtocolTest11);
706 UtRegisterTest("DetectAppLayerProtocolTest12",
707 DetectAppLayerProtocolTest12);
708 UtRegisterTest("DetectAppLayerProtocolTest13",
709 DetectAppLayerProtocolTest13);
710 UtRegisterTest("DetectAppLayerProtocolTest14",
711 DetectAppLayerProtocolTest14);
712}
713#endif /* UNITTESTS */
uint16_t AppProto
@ ALPROTO_FAILED
@ ALPROTO_SMTP
@ ALPROTO_HTTP
@ ALPROTO_UNKNOWN
AppProto AppLayerGetProtoByName(const char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition app-layer.c:1002
#define PKT_PROTO_DETECT_TS_DONE
Definition decode.h:1299
#define PKT_PROTO_DETECT_TC_DONE
Definition decode.h:1300
#define MAX_ALPROTO_NAME
struct DetectAppLayerProtocolData_ DetectAppLayerProtocolData
void DetectAppLayerProtocolRegister(void)
@ DETECT_ALPROTO_TOCLIENT
@ DETECT_ALPROTO_EITHER
@ DETECT_ALPROTO_TOSERVER
@ DETECT_ALPROTO_DIRECTION
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
@ DETECT_APP_LAYER_PROTOCOL
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define SIG_MASK_REQUIRE_FLOW
Definition detect.h:312
#define DE_QUIET
Definition detect.h:330
#define SIGMATCH_SUPPORT_FIREWALL
Definition detect.h:1682
@ SIG_TYPE_PDONLY
Definition detect.h:70
#define SIGMATCH_QUOTES_OPTIONAL
Definition detect.h:1664
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
#define SIG_FLAG_APPLAYER
Definition detect.h:249
#define SIGMATCH_HANDLE_NEGATION
Definition detect.h:1672
#define FLOW_PKT_TOSERVER
Definition flow.h:233
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
struct Thresholds ctx
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
PrefilterRuleStore pmq
Definition detect.h:1349
Flow data structure.
Definition flow.h:356
AppProto alproto_ts
Definition flow.h:451
AppProto alproto_tc
Definition flow.h:452
AppProto alproto
application level protocol
Definition flow.h:450
AppProto alproto_orig
Definition flow.h:456
uint8_t flowflags
Definition decode.h:532
uint64_t pcap_cnt
Definition decode.h:626
struct Flow_ * flow
Definition decode.h:546
uint32_t flags
Definition decode.h:544
Container for matching data for a signature group.
Definition detect.h:1629
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
a single match condition for a signature
Definition detect.h:356
uint16_t type
Definition detect.h:357
struct SigMatch_ * next
Definition detect.h:360
SigMatchCtx * ctx
Definition detect.h:359
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition detect.h:1444
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * name
Definition detect.h:1459
bool(* SupportsPrefilter)(const Signature *s)
Definition detect.h:1443
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition detect.h:642
Signature container.
Definition detect.h:668
enum SignatureType type
Definition detect.h:671
uint32_t flags
Definition detect.h:669
SignatureInitData * init_data
Definition detect.h:747
AppProto alproto
Definition detect.h:673
uint32_t id
Definition detect.h:713
size_t strlcpy(char *dst, const char *src, size_t siz)
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCReturn
Definition util-debug.h:279
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)