36 #define DETECT_TCP_SESSION_ARG_MAX_LEN 32
39 static int DetectTcpSessionMatch(
44 static void DetectTcpSessionRegisterTests(
void);
48 static uint8_t DetectTcpSessionPhaseFlagFromToken(
const char *token)
50 if (strcmp(token,
"setup") == 0) {
53 if (strcmp(token,
"established") == 0) {
56 if (strcmp(token,
"closing") == 0) {
65 if (arg == NULL || strlen(arg) == 0) {
66 SCLogError(
"tcp.session keyword requires a value: comma-separated "
67 "subset of {setup, established, closing}");
72 SCLogError(
"tcp.session argument too long (%zu > %d): accepted "
73 "tokens are {setup, established, closing}",
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}",
86 if (strstr(arg,
",,") != NULL) {
87 SCLogError(
"tcp.session: consecutive commas in argument \"%s\"; "
88 "accepted tokens are {setup, established, closing}",
93 uint8_t phase_flags = 0;
101 char *saveptr = NULL;
102 char *token = strtok_r(argdup,
",", &saveptr);
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}",
113 const uint8_t flag = DetectTcpSessionPhaseFlagFromToken(token);
115 SCLogError(
"tcp.session: unknown token \"%s\" in argument "
116 "\"%s\"; accepted tokens are {setup, established, "
123 if (phase_flags & flag) {
124 SCLogError(
"tcp.session: duplicate token \"%s\" in argument "
132 token = strtok_r(NULL,
",", &saveptr);
137 if (phase_flags == 0) {
138 SCLogError(
"tcp.session keyword requires a value: comma-separated "
139 "subset of {setup, established, closing}");
152 static int DetectTcpSessionMatch(
158 if (f == NULL || f->
proto != IPPROTO_TCP) {
162 uint8_t pkt_phase = 0;
174 switch (ssn->
state) {
195 SCLogError(
"tcp.session requires a TCP rule");
206 DetectTcpSessionFree(
de_ctx, data);
227 "match TCP session lifecycle phase set (setup, established, closing)";
247 static int DetectTcpSessionTest01(
void)
252 DetectTcpSessionFree(NULL, d);
254 d = DetectTcpSessionParse(
"established");
257 DetectTcpSessionFree(NULL, d);
259 d = DetectTcpSessionParse(
"closing");
262 DetectTcpSessionFree(NULL, d);
268 static int DetectTcpSessionTest02(
void)
274 DetectTcpSessionFree(NULL, d);
276 d = DetectTcpSessionParse(
"established,setup");
280 DetectTcpSessionFree(NULL, d);
282 d = DetectTcpSessionParse(
"setup,established,closing");
287 DetectTcpSessionFree(NULL, d);
293 static int DetectTcpSessionTest03(
void)
298 DetectTcpSessionFree(NULL, d);
300 d = DetectTcpSessionParse(
"established,closing");
304 DetectTcpSessionFree(NULL, d);
310 static int DetectTcpSessionTest04(
void)
322 static int DetectTcpSessionTest05(
void)
331 memset(longarg,
'a',
sizeof(longarg) - 1);
332 longarg[
sizeof(longarg) - 1] =
'\0';
338 static int DetectTcpSessionTest06(
void)
347 static Packet *DetectTcpSessionTestBuildPacket(
354 memset(f, 0,
sizeof(*f));
355 memset(ssn, 0,
sizeof(*ssn));
356 memset(tcph, 0,
sizeof(*tcph));
358 f->
proto = IPPROTO_TCP;
363 PacketSetTCP(
p, (uint8_t *)tcph);
372 static int DetectTcpSessionTest07(
void)
380 memset(&
tv, 0,
sizeof(
tv));
381 memset(&dtx, 0,
sizeof(dtx));
382 memset(&s, 0,
sizeof(s));
392 DetectTcpSessionFree(NULL, d);
398 static int DetectTcpSessionTest08(
void)
406 memset(&
tv, 0,
sizeof(
tv));
407 memset(&dtx, 0,
sizeof(dtx));
408 memset(&s, 0,
sizeof(s));
416 DetectTcpSessionFree(NULL, setup);
421 DetectTcpSessionFree(NULL, est);
428 static int DetectTcpSessionTest09(
void)
436 memset(&
tv, 0,
sizeof(
tv));
437 memset(&dtx, 0,
sizeof(dtx));
438 memset(&s, 0,
sizeof(s));
447 DetectTcpSessionFree(NULL, est);
452 DetectTcpSessionFree(NULL, setup);
459 static int DetectTcpSessionTest10(
void)
464 memset(&
tv, 0,
sizeof(
tv));
465 memset(&dtx, 0,
sizeof(dtx));
466 memset(&s, 0,
sizeof(s));
477 const bool est_flags[] = {
false,
true };
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++) {
484 Packet *
p = DetectTcpSessionTestBuildPacket(&f, &ssn, &tcph, states[si], est_flags[ei]);
487 int ts_setup_r = DetectTcpSessionMatch(&dtx,
p, &s, (
const SigMatchCtx *)ts_setup);
491 int ts_est_r = DetectTcpSessionMatch(&dtx,
p, &s, (
const SigMatchCtx *)ts_est);
499 DetectTcpSessionFree(NULL, ts_setup);
500 DetectTcpSessionFree(NULL, ts_est);
504 static int DetectTcpSessionMatchExhaustive(
void);
506 static void DetectTcpSessionRegisterTests(
void)
518 UtRegisterTest(
"DetectTcpSessionMatchExhaustive", DetectTcpSessionMatchExhaustive);
525 static uint8_t DetectTcpSessionExpectedPhaseMask(
enum TcpState state,
bool flow_pkt_est)
552 static int DetectTcpSessionMatchExhaustive(
void)
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);
563 for (uint8_t pf = 1; pf <= 0x7; pf++) {
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;
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);