suricata
detect-tcp-session.c
Go to the documentation of this file.
1 /* Copyright (C) 2026 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 /** \file \brief tcp.session: keyword (Redmine #7704). */
19 
20 #include "suricata-common.h"
21 
22 #include "detect.h"
23 #include "detect-engine.h"
24 #include "detect-parse.h"
25 
26 #include "flow.h"
27 #include "stream-tcp.h"
28 #include "stream-tcp-private.h"
29 
30 #include "util-debug.h"
31 
32 #include "detect-tcp-session.h"
33 
34 /** Upper bound on the total length of the keyword argument. */
35 #define DETECT_TCP_SESSION_ARG_MAX_LEN 32
36 
37 /* prototypes */
38 static int DetectTcpSessionMatch(
39  DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
40 static int DetectTcpSessionSetup(DetectEngineCtx *, Signature *, const char *);
41 static void DetectTcpSessionFree(DetectEngineCtx *, void *);
42 #ifdef UNITTESTS
43 static void DetectTcpSessionRegisterTests(void);
44 #endif
45 
46 /** Map a single phase token to its phase flag. */
47 static uint8_t DetectTcpSessionPhaseFlagFromToken(const char *token)
48 {
49  if (strcmp(token, "setup") == 0) {
51  }
52  if (strcmp(token, "established") == 0) {
54  }
55  if (strcmp(token, "closing") == 0) {
57  }
58  return 0;
59 }
60 
61 /** Parse a tcp.session: keyword argument into a DetectTcpSessionData. */
62 static DetectTcpSessionData *DetectTcpSessionParse(const char *arg)
63 {
64  if (arg == NULL || strlen(arg) == 0) {
65  SCLogError("tcp.session keyword requires a value: comma-separated "
66  "subset of {setup, established, closing}");
67  return NULL;
68  }
69 
70  if (strlen(arg) > DETECT_TCP_SESSION_ARG_MAX_LEN) {
71  SCLogError("tcp.session argument too long (%zu > %d): accepted "
72  "tokens are {setup, established, closing}",
73  strlen(arg), DETECT_TCP_SESSION_ARG_MAX_LEN);
74  return NULL;
75  }
76 
77  /* Reject leading, trailing, or consecutive commas — strtok_r would
78  * silently skip them, but we treat these as syntax errors. */
79  if (arg[0] == ',' || arg[strlen(arg) - 1] == ',') {
80  SCLogError("tcp.session: leading or trailing comma in argument "
81  "\"%s\"; accepted tokens are {setup, established, closing}",
82  arg);
83  return NULL;
84  }
85  if (strstr(arg, ",,") != NULL) {
86  SCLogError("tcp.session: consecutive commas in argument \"%s\"; "
87  "accepted tokens are {setup, established, closing}",
88  arg);
89  return NULL;
90  }
91 
92  uint8_t phase_flags = 0;
93 
94  /* Work on a mutable copy for strtok_r. */
95  char *argdup = SCStrdup(arg);
96  if (argdup == NULL) {
97  return NULL;
98  }
99 
100  char *saveptr = NULL;
101  char *token = strtok_r(argdup, ",", &saveptr);
102 
103  while (token != NULL) {
104  if (strlen(token) == 0) {
105  SCLogError("tcp.session: empty token in argument \"%s\"; "
106  "accepted tokens are {setup, established, closing}",
107  arg);
108  SCFree(argdup);
109  return NULL;
110  }
111 
112  const uint8_t flag = DetectTcpSessionPhaseFlagFromToken(token);
113  if (flag == 0) {
114  SCLogError("tcp.session: unknown token \"%s\" in argument "
115  "\"%s\"; accepted tokens are {setup, established, "
116  "closing}",
117  token, arg);
118  SCFree(argdup);
119  return NULL;
120  }
121 
122  if (phase_flags & flag) {
123  SCLogError("tcp.session: duplicate token \"%s\" in argument "
124  "\"%s\"",
125  token, arg);
126  SCFree(argdup);
127  return NULL;
128  }
129 
130  phase_flags |= flag;
131  token = strtok_r(NULL, ",", &saveptr);
132  }
133 
134  SCFree(argdup);
135 
136  if (phase_flags == 0) {
137  SCLogError("tcp.session keyword requires a value: comma-separated "
138  "subset of {setup, established, closing}");
139  return NULL;
140  }
141 
142  DetectTcpSessionData *data = SCMalloc(sizeof(*data));
143  if (unlikely(data == NULL)) {
144  return NULL;
145  }
146  data->phase_flags = phase_flags;
147  return data;
148 }
149 
150 /** Per-packet match: returns 1 iff the packet's TCP session phase intersects phase_flags. */
151 static int DetectTcpSessionMatch(
152  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
153 {
154  const DetectTcpSessionData *d = (const DetectTcpSessionData *)ctx;
155  const Flow *f = p->flow;
156 
157  if (f == NULL || f->proto != IPPROTO_TCP) {
158  return 0;
159  }
160 
161  uint8_t pkt_phase = 0;
162 
163  /* Setup vs established split via FLOW_PKT_ESTABLISHED. */
166  } else {
167  pkt_phase |= DETECT_TCP_SESSION_PHASE_SETUP;
168  }
169 
170  /* Closing phase: consult TcpSession::state directly. */
171  const TcpSession *ssn = (const TcpSession *)f->protoctx;
172  if (ssn != NULL) {
173  switch (ssn->state) {
174  case TCP_FIN_WAIT1:
175  case TCP_FIN_WAIT2:
176  case TCP_TIME_WAIT:
177  case TCP_LAST_ACK:
178  case TCP_CLOSE_WAIT:
179  case TCP_CLOSING:
181  break;
182  default:
183  break;
184  }
185  }
186 
187  return (pkt_phase & d->phase_flags) ? 1 : 0;
188 }
189 
190 /** Setup function: parse argument and append the SigMatch. */
191 static int DetectTcpSessionSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
192 {
193  if (!(DetectProtoContainsProto(&s->init_data->proto, IPPROTO_TCP))) {
194  SCLogError("tcp.session requires a TCP rule");
195  return -1;
196  }
197 
198  DetectTcpSessionData *data = DetectTcpSessionParse(arg);
199  if (data == NULL) {
200  return -1;
201  }
202 
205  DetectTcpSessionFree(de_ctx, data);
206  return -1;
207  }
208 
210  return 0;
211 }
212 
213 /** Free a DetectTcpSessionData allocation. */
214 static void DetectTcpSessionFree(DetectEngineCtx *de_ctx, void *ptr)
215 {
216  if (ptr != NULL) {
217  SCFree(ptr);
218  }
219 }
220 
221 /** Registration function for the tcp.session: keyword. */
223 {
224  sigmatch_table[DETECT_TCP_SESSION].name = "tcp.session";
226  "match TCP session lifecycle phase set (setup, established, closing)";
227  sigmatch_table[DETECT_TCP_SESSION].url = "/rules/flow-keywords.html#tcp-session";
228  sigmatch_table[DETECT_TCP_SESSION].Match = DetectTcpSessionMatch;
229  sigmatch_table[DETECT_TCP_SESSION].Setup = DetectTcpSessionSetup;
230  sigmatch_table[DETECT_TCP_SESSION].Free = DetectTcpSessionFree;
232 #ifdef UNITTESTS
233  sigmatch_table[DETECT_TCP_SESSION].RegisterTests = DetectTcpSessionRegisterTests;
234 #endif
235 }
236 
237 #ifdef UNITTESTS
238 #include "util-unittest-helper.h"
239 #include "detect-engine.h"
240 #include "detect-flow.h"
241 
243 
244 /** Test01: single-token parsing. */
245 static int DetectTcpSessionTest01(void)
246 {
247  DetectTcpSessionData *d = DetectTcpSessionParse("setup");
248  FAIL_IF_NULL(d);
250  DetectTcpSessionFree(NULL, d);
251 
252  d = DetectTcpSessionParse("established");
253  FAIL_IF_NULL(d);
255  DetectTcpSessionFree(NULL, d);
256 
257  d = DetectTcpSessionParse("closing");
258  FAIL_IF_NULL(d);
260  DetectTcpSessionFree(NULL, d);
261 
262  PASS;
263 }
264 
265 /** Test02: multi-token parsing and order independence. */
266 static int DetectTcpSessionTest02(void)
267 {
268  DetectTcpSessionData *d = DetectTcpSessionParse("setup,established");
269  FAIL_IF_NULL(d);
272  DetectTcpSessionFree(NULL, d);
273 
274  d = DetectTcpSessionParse("established,setup");
275  FAIL_IF_NULL(d);
278  DetectTcpSessionFree(NULL, d);
279 
280  d = DetectTcpSessionParse("setup,established,closing");
281  FAIL_IF_NULL(d);
285  DetectTcpSessionFree(NULL, d);
286 
287  PASS;
288 }
289 
290 /** Test03: closing token and closing combinations. */
291 static int DetectTcpSessionTest03(void)
292 {
293  DetectTcpSessionData *d = DetectTcpSessionParse("closing");
294  FAIL_IF_NULL(d);
296  DetectTcpSessionFree(NULL, d);
297 
298  d = DetectTcpSessionParse("established,closing");
299  FAIL_IF_NULL(d);
302  DetectTcpSessionFree(NULL, d);
303 
304  PASS;
305 }
306 
307 /** Test04: empty/missing value is rejected. */
308 static int DetectTcpSessionTest04(void)
309 {
310  FAIL_IF_NOT_NULL(DetectTcpSessionParse(NULL));
311  FAIL_IF_NOT_NULL(DetectTcpSessionParse(""));
312  FAIL_IF_NOT_NULL(DetectTcpSessionParse(","));
313  FAIL_IF_NOT_NULL(DetectTcpSessionParse(",setup"));
314  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setup,"));
315  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setup,,established"));
316  PASS;
317 }
318 
319 /** Test05: unknown/whitespace/over-length tokens are rejected. */
320 static int DetectTcpSessionTest05(void)
321 {
322  FAIL_IF_NOT_NULL(DetectTcpSessionParse("bogus"));
323  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setup,bogus"));
324  FAIL_IF_NOT_NULL(DetectTcpSessionParse("SETUP"));
325  FAIL_IF_NOT_NULL(DetectTcpSessionParse(" setup"));
326  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setup "));
327  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setu p"));
328  char longarg[128];
329  memset(longarg, 'a', sizeof(longarg) - 1);
330  longarg[sizeof(longarg) - 1] = '\0';
331  FAIL_IF_NOT_NULL(DetectTcpSessionParse(longarg));
332  PASS;
333 }
334 
335 /** Test06: duplicate tokens are rejected. */
336 static int DetectTcpSessionTest06(void)
337 {
338  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setup,setup"));
339  FAIL_IF_NOT_NULL(DetectTcpSessionParse("established,established"));
340  FAIL_IF_NOT_NULL(DetectTcpSessionParse("setup,established,setup"));
341  PASS;
342 }
343 
344 /** Build a minimal TCP packet+flow harness for match tests. */
345 static Packet *DetectTcpSessionTestBuildPacket(
346  Flow *f, TcpSession *ssn, TCPHdr *tcph, uint8_t state, bool established)
347 {
349  if (p == NULL)
350  return NULL;
351 
352  memset(f, 0, sizeof(*f));
353  memset(ssn, 0, sizeof(*ssn));
354  memset(tcph, 0, sizeof(*tcph));
355 
356  f->proto = IPPROTO_TCP;
357  ssn->state = state;
358  f->protoctx = ssn;
359 
360  p->flow = f;
361  PacketSetTCP(p, (uint8_t *)tcph);
363  if (established) {
365  }
366  return p;
367 }
368 
369 /** Test07: established flow matches tcp.session:established. */
370 static int DetectTcpSessionTest07(void)
371 {
372  Flow f;
373  TcpSession ssn;
374  TCPHdr tcph;
375  ThreadVars tv;
377  Signature s;
378  memset(&tv, 0, sizeof(tv));
379  memset(&dtx, 0, sizeof(dtx));
380  memset(&s, 0, sizeof(s));
381 
382  Packet *p = DetectTcpSessionTestBuildPacket(&f, &ssn, &tcph, TCP_ESTABLISHED, true);
383  FAIL_IF_NULL(p);
384 
385  DetectTcpSessionData *d = DetectTcpSessionParse("established");
386  FAIL_IF_NULL(d);
387 
388  FAIL_IF_NOT(DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)d) == 1);
389 
390  DetectTcpSessionFree(NULL, d);
391  PacketFree(p);
392  PASS;
393 }
394 
395 /** Test08: SYN_SENT flow matches tcp.session:setup but not established. */
396 static int DetectTcpSessionTest08(void)
397 {
398  Flow f;
399  TcpSession ssn;
400  TCPHdr tcph;
401  ThreadVars tv;
403  Signature s;
404  memset(&tv, 0, sizeof(tv));
405  memset(&dtx, 0, sizeof(dtx));
406  memset(&s, 0, sizeof(s));
407 
408  Packet *p = DetectTcpSessionTestBuildPacket(&f, &ssn, &tcph, TCP_SYN_SENT, false);
409  FAIL_IF_NULL(p);
410 
411  DetectTcpSessionData *setup = DetectTcpSessionParse("setup");
412  FAIL_IF_NULL(setup);
413  FAIL_IF_NOT(DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)setup) == 1);
414  DetectTcpSessionFree(NULL, setup);
415 
416  DetectTcpSessionData *est = DetectTcpSessionParse("established");
417  FAIL_IF_NULL(est);
418  FAIL_IF_NOT(DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)est) == 0);
419  DetectTcpSessionFree(NULL, est);
420 
421  PacketFree(p);
422  PASS;
423 }
424 
425 /** Test09: midstream pickup in TCP_ESTABLISHED matches established, not setup. */
426 static int DetectTcpSessionTest09(void)
427 {
428  Flow f;
429  TcpSession ssn;
430  TCPHdr tcph;
431  ThreadVars tv;
433  Signature s;
434  memset(&tv, 0, sizeof(tv));
435  memset(&dtx, 0, sizeof(dtx));
436  memset(&s, 0, sizeof(s));
437 
438  Packet *p = DetectTcpSessionTestBuildPacket(&f, &ssn, &tcph, TCP_ESTABLISHED, true);
439  FAIL_IF_NULL(p);
441 
442  DetectTcpSessionData *est = DetectTcpSessionParse("established");
443  FAIL_IF_NULL(est);
444  FAIL_IF_NOT(DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)est) == 1);
445  DetectTcpSessionFree(NULL, est);
446 
447  DetectTcpSessionData *setup = DetectTcpSessionParse("setup");
448  FAIL_IF_NULL(setup);
449  FAIL_IF_NOT(DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)setup) == 0);
450  DetectTcpSessionFree(NULL, setup);
451 
452  PacketFree(p);
453  PASS;
454 }
455 
456 /** Test10: equivalence with flow:established / flow:not_established. */
457 static int DetectTcpSessionTest10(void)
458 {
459  ThreadVars tv;
461  Signature s;
462  memset(&tv, 0, sizeof(tv));
463  memset(&dtx, 0, sizeof(dtx));
464  memset(&s, 0, sizeof(s));
465 
466  DetectTcpSessionData *ts_setup = DetectTcpSessionParse("setup");
467  FAIL_IF_NULL(ts_setup);
468  DetectTcpSessionData *ts_est = DetectTcpSessionParse("established");
469  FAIL_IF_NULL(ts_est);
470 
471  DetectFlowData fd_not_est = { .flags = DETECT_FLOW_FLAG_NOT_ESTABLISHED, .match_cnt = 1 };
472  DetectFlowData fd_est = { .flags = DETECT_FLOW_FLAG_ESTABLISHED, .match_cnt = 1 };
473 
474  const uint8_t states[] = { TCP_NONE, TCP_SYN_SENT, TCP_SYN_RECV, TCP_ESTABLISHED };
475  const bool est_flags[] = { false, true };
476 
477  for (size_t si = 0; si < sizeof(states) / sizeof(states[0]); si++) {
478  for (size_t ei = 0; ei < sizeof(est_flags) / sizeof(est_flags[0]); ei++) {
479  Flow f;
480  TcpSession ssn;
481  TCPHdr tcph;
482  Packet *p = DetectTcpSessionTestBuildPacket(&f, &ssn, &tcph, states[si], est_flags[ei]);
483  FAIL_IF_NULL(p);
484 
485  int ts_setup_r = DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)ts_setup);
486  int flow_not_est_r = DetectFlowMatch(&dtx, p, &s, (const SigMatchCtx *)&fd_not_est);
487  FAIL_IF_NOT(ts_setup_r == flow_not_est_r);
488 
489  int ts_est_r = DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)ts_est);
490  int flow_est_r = DetectFlowMatch(&dtx, p, &s, (const SigMatchCtx *)&fd_est);
491  FAIL_IF_NOT(ts_est_r == flow_est_r);
492 
493  PacketFree(p);
494  }
495  }
496 
497  DetectTcpSessionFree(NULL, ts_setup);
498  DetectTcpSessionFree(NULL, ts_est);
499  PASS;
500 }
501 
502 static int DetectTcpSessionMatchExhaustive(void);
503 
504 static void DetectTcpSessionRegisterTests(void)
505 {
506  UtRegisterTest("DetectTcpSessionTest01", DetectTcpSessionTest01);
507  UtRegisterTest("DetectTcpSessionTest02", DetectTcpSessionTest02);
508  UtRegisterTest("DetectTcpSessionTest03", DetectTcpSessionTest03);
509  UtRegisterTest("DetectTcpSessionTest04", DetectTcpSessionTest04);
510  UtRegisterTest("DetectTcpSessionTest05", DetectTcpSessionTest05);
511  UtRegisterTest("DetectTcpSessionTest06", DetectTcpSessionTest06);
512  UtRegisterTest("DetectTcpSessionTest07", DetectTcpSessionTest07);
513  UtRegisterTest("DetectTcpSessionTest08", DetectTcpSessionTest08);
514  UtRegisterTest("DetectTcpSessionTest09", DetectTcpSessionTest09);
515  UtRegisterTest("DetectTcpSessionTest10", DetectTcpSessionTest10);
516  UtRegisterTest("DetectTcpSessionMatchExhaustive", DetectTcpSessionMatchExhaustive);
517 }
518 #endif /* UNITTESTS */
519 
520 #ifdef UNITTESTS
521 
522 /** Oracle: compute expected per-packet phase mask from state and flow flag. */
523 static uint8_t DetectTcpSessionExpectedPhaseMask(enum TcpState state, bool flow_pkt_est)
524 {
525  uint8_t mask = 0;
526 
527  if (flow_pkt_est) {
529  } else {
531  }
532 
533  switch (state) {
534  case TCP_FIN_WAIT1:
535  case TCP_FIN_WAIT2:
536  case TCP_TIME_WAIT:
537  case TCP_LAST_ACK:
538  case TCP_CLOSE_WAIT:
539  case TCP_CLOSING:
541  break;
542  default:
543  break;
544  }
545 
546  return mask;
547 }
548 
549 /** Exhaustive match test over all (state × flag × phase_flags) combinations. */
550 static int DetectTcpSessionMatchExhaustive(void)
551 {
552  /* Iterate all TcpState values (0..TCP_CLOSED). Value 1 is unused
553  * (TCP_LISTEN is commented out) but the match function handles it
554  * via the default case, so including it is harmless. */
555 
556  for (uint8_t st = 0; st <= TCP_CLOSED; st++) {
557  for (int est = 0; est <= 1; est++) {
558  const bool flow_pkt_est = (est == 1);
559 
560  /* All 7 non-empty subsets of the 3-bit phase space. */
561  for (uint8_t pf = 1; pf <= 0x7; pf++) {
562  ThreadVars tv;
564  Signature s;
565  TcpSession ssn;
566  Flow f;
568  FAIL_IF_NULL(p);
569  memset(&tv, 0, sizeof(tv));
570  memset(&dtx, 0, sizeof(dtx));
571  memset(&s, 0, sizeof(s));
572  memset(&ssn, 0, sizeof(ssn));
573  memset(&f, 0, sizeof(f));
574  f.proto = IPPROTO_TCP;
575  ssn.state = st;
576  f.protoctx = &ssn;
577  p->flow = &f;
578  p->flags |= PKT_HAS_FLOW;
579  if (flow_pkt_est)
581 
582  DetectTcpSessionData d = { .phase_flags = pf };
583  const uint8_t expected_mask =
584  DetectTcpSessionExpectedPhaseMask((enum TcpState)st, flow_pkt_est);
585  const int expected = (expected_mask & pf) ? 1 : 0;
586  const int actual = DetectTcpSessionMatch(&dtx, p, &s, (const SigMatchCtx *)&d);
587  PacketFree(p);
588  FAIL_IF_NOT(actual == expected);
589  }
590  }
591  }
592 
593  PASS;
594 }
595 
596 #endif /* UNITTESTS */
TCP_SYN_RECV
@ TCP_SYN_RECV
Definition: stream-tcp-private.h:154
SigTableElmt_::url
const char * url
Definition: detect.h:1545
DetectFlowMatch
int DetectFlowMatch(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
This function is used to match flow flags set on a packet with those passed via flow:
Definition: detect-flow.c:133
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1544
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:78
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1311
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1529
TCP_SYN_SENT
@ TCP_SYN_SENT
Definition: stream-tcp-private.h:153
DetectFlowData_
Definition: detect-flow.h:37
SigTableElmt_::name
const char * name
Definition: detect.h:1542
stream-tcp.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1533
TCP_FIN_WAIT2
@ TCP_FIN_WAIT2
Definition: stream-tcp-private.h:157
Flow_::proto
uint8_t proto
Definition: flow.h:381
Packet_::flags
uint32_t flags
Definition: decode.h:562
ssn
TcpSession ssn
Definition: fuzz_dataset.c:31
Flow_
Flow data structure.
Definition: flow.h:359
detect-tcp-session.h
tcp.session: keyword (Redmine #7704).
ctx
struct Thresholds ctx
DetectFlowData_::flags
uint16_t flags
Definition: detect-flow.h:38
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:995
TCP_FIN_WAIT1
@ TCP_FIN_WAIT1
Definition: stream-tcp-private.h:156
TCP_LAST_ACK
@ TCP_LAST_ACK
Definition: stream-tcp-private.h:159
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:236
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:155
STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED
#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED
Definition: stream-tcp-private.h:172
p
Packet * p
Definition: fuzz_dataset.c:30
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:547
Flow_::protoctx
void * protoctx
Definition: flow.h:438
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1524
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TcpState
TcpState
Definition: stream-tcp-private.h:150
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:170
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:294
TCP_NONE
@ TCP_NONE
Definition: stream-tcp-private.h:151
TCP_CLOSE_WAIT
@ TCP_CLOSE_WAIT
Definition: stream-tcp-private.h:160
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
DetectEngineThreadCtx_
Definition: detect.h:1316
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:424
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DETECT_TCP_SESSION
@ DETECT_TCP_SESSION
Definition: detect-engine-register.h:64
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:221
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
SignatureInitData_::proto
DetectProto proto
Definition: detect.h:655
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:118
DETECT_TCP_SESSION_PHASE_SETUP
#define DETECT_TCP_SESSION_PHASE_SETUP
Definition: detect-tcp-session.h:29
Signature_::flags
uint32_t flags
Definition: detect.h:693
Packet_
Definition: decode.h:516
DetectTcpSessionData_::phase_flags
uint8_t phase_flags
Definition: detect-tcp-session.h:34
stream-tcp-private.h
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:775
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1504
DetectTcpSessionData_
Definition: detect-tcp-session.h:33
DETECT_TCP_SESSION_PHASE_ESTABLISHED
#define DETECT_TCP_SESSION_PHASE_ESTABLISHED
Definition: detect-tcp-session.h:30
DetectTcpSessionRegister
void DetectTcpSessionRegister(void)
Definition: detect-tcp-session.c:222
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:355
TCP_CLOSED
@ TCP_CLOSED
Definition: stream-tcp-private.h:162
Packet_::flow
struct Flow_ * flow
Definition: decode.h:564
DETECT_TCP_SESSION_PHASE_CLOSING
#define DETECT_TCP_SESSION_PHASE_CLOSING
Definition: detect-tcp-session.h:31
suricata-common.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
TCP_CLOSING
@ TCP_CLOSING
Definition: stream-tcp-private.h:161
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:260
DETECT_FLOW_FLAG_NOT_ESTABLISHED
#define DETECT_FLOW_FLAG_NOT_ESTABLISHED
Definition: detect-flow.h:30
detect-flow.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DETECT_FLOW_FLAG_ESTABLISHED
#define DETECT_FLOW_FLAG_ESTABLISHED
Definition: detect-flow.h:29
detect-parse.h
Signature_
Signature container.
Definition: detect.h:692
TCP_TIME_WAIT
@ TCP_TIME_WAIT
Definition: stream-tcp-private.h:158
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:238
SIGMATCH_SUPPORT_FIREWALL
#define SIGMATCH_SUPPORT_FIREWALL
Definition: detect-engine-register.h:336
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
DETECT_TCP_SESSION_ARG_MAX_LEN
#define DETECT_TCP_SESSION_ARG_MAX_LEN
Definition: detect-tcp-session.c:35
TCPHdr_
Definition: decode-tcp.h:149
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1531
f
Flow f
Definition: fuzz_dataset.c:32
DetectProtoContainsProto
int DetectProtoContainsProto(const DetectProto *dp, int proto)
see if a DetectProto contains a certain proto
Definition: detect-engine-proto.c:114
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:257