35 #define DETECT_TCP_SESSION_ARG_MAX_LEN 32
38 static int DetectTcpSessionMatch(
43 static void DetectTcpSessionRegisterTests(
void);
47 static uint8_t DetectTcpSessionPhaseFlagFromToken(
const char *token)
49 if (strcmp(token,
"setup") == 0) {
52 if (strcmp(token,
"established") == 0) {
55 if (strcmp(token,
"closing") == 0) {
64 if (arg == NULL || strlen(arg) == 0) {
65 SCLogError(
"tcp.session keyword requires a value: comma-separated "
66 "subset of {setup, established, closing}");
71 SCLogError(
"tcp.session argument too long (%zu > %d): accepted "
72 "tokens are {setup, established, closing}",
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}",
85 if (strstr(arg,
",,") != NULL) {
86 SCLogError(
"tcp.session: consecutive commas in argument \"%s\"; "
87 "accepted tokens are {setup, established, closing}",
92 uint8_t phase_flags = 0;
100 char *saveptr = NULL;
101 char *token = strtok_r(argdup,
",", &saveptr);
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}",
112 const uint8_t flag = DetectTcpSessionPhaseFlagFromToken(token);
114 SCLogError(
"tcp.session: unknown token \"%s\" in argument "
115 "\"%s\"; accepted tokens are {setup, established, "
122 if (phase_flags & flag) {
123 SCLogError(
"tcp.session: duplicate token \"%s\" in argument "
131 token = strtok_r(NULL,
",", &saveptr);
136 if (phase_flags == 0) {
137 SCLogError(
"tcp.session keyword requires a value: comma-separated "
138 "subset of {setup, established, closing}");
151 static int DetectTcpSessionMatch(
157 if (
f == NULL ||
f->
proto != IPPROTO_TCP) {
161 uint8_t pkt_phase = 0;
194 SCLogError(
"tcp.session requires a TCP rule");
205 DetectTcpSessionFree(
de_ctx, data);
226 "match TCP session lifecycle phase set (setup, established, closing)";
245 static int DetectTcpSessionTest01(
void)
250 DetectTcpSessionFree(NULL, d);
252 d = DetectTcpSessionParse(
"established");
255 DetectTcpSessionFree(NULL, d);
257 d = DetectTcpSessionParse(
"closing");
260 DetectTcpSessionFree(NULL, d);
266 static int DetectTcpSessionTest02(
void)
272 DetectTcpSessionFree(NULL, d);
274 d = DetectTcpSessionParse(
"established,setup");
278 DetectTcpSessionFree(NULL, d);
280 d = DetectTcpSessionParse(
"setup,established,closing");
285 DetectTcpSessionFree(NULL, d);
291 static int DetectTcpSessionTest03(
void)
296 DetectTcpSessionFree(NULL, d);
298 d = DetectTcpSessionParse(
"established,closing");
302 DetectTcpSessionFree(NULL, d);
308 static int DetectTcpSessionTest04(
void)
320 static int DetectTcpSessionTest05(
void)
329 memset(longarg,
'a',
sizeof(longarg) - 1);
330 longarg[
sizeof(longarg) - 1] =
'\0';
336 static int DetectTcpSessionTest06(
void)
345 static Packet *DetectTcpSessionTestBuildPacket(
352 memset(
f, 0,
sizeof(*
f));
353 memset(
ssn, 0,
sizeof(*
ssn));
354 memset(tcph, 0,
sizeof(*tcph));
361 PacketSetTCP(
p, (uint8_t *)tcph);
370 static int DetectTcpSessionTest07(
void)
378 memset(&
tv, 0,
sizeof(
tv));
379 memset(&dtx, 0,
sizeof(dtx));
380 memset(&s, 0,
sizeof(s));
390 DetectTcpSessionFree(NULL, d);
396 static int DetectTcpSessionTest08(
void)
404 memset(&
tv, 0,
sizeof(
tv));
405 memset(&dtx, 0,
sizeof(dtx));
406 memset(&s, 0,
sizeof(s));
414 DetectTcpSessionFree(NULL, setup);
419 DetectTcpSessionFree(NULL, est);
426 static int DetectTcpSessionTest09(
void)
434 memset(&
tv, 0,
sizeof(
tv));
435 memset(&dtx, 0,
sizeof(dtx));
436 memset(&s, 0,
sizeof(s));
445 DetectTcpSessionFree(NULL, est);
450 DetectTcpSessionFree(NULL, setup);
457 static int DetectTcpSessionTest10(
void)
462 memset(&
tv, 0,
sizeof(
tv));
463 memset(&dtx, 0,
sizeof(dtx));
464 memset(&s, 0,
sizeof(s));
475 const bool est_flags[] = {
false,
true };
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++) {
482 Packet *
p = DetectTcpSessionTestBuildPacket(&
f, &
ssn, &tcph, states[si], est_flags[ei]);
485 int ts_setup_r = DetectTcpSessionMatch(&dtx,
p, &s, (
const SigMatchCtx *)ts_setup);
489 int ts_est_r = DetectTcpSessionMatch(&dtx,
p, &s, (
const SigMatchCtx *)ts_est);
497 DetectTcpSessionFree(NULL, ts_setup);
498 DetectTcpSessionFree(NULL, ts_est);
502 static int DetectTcpSessionMatchExhaustive(
void);
504 static void DetectTcpSessionRegisterTests(
void)
516 UtRegisterTest(
"DetectTcpSessionMatchExhaustive", DetectTcpSessionMatchExhaustive);
523 static uint8_t DetectTcpSessionExpectedPhaseMask(
enum TcpState state,
bool flow_pkt_est)
550 static int DetectTcpSessionMatchExhaustive(
void)
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);
561 for (uint8_t pf = 1; pf <= 0x7; pf++) {
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));
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);