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