suricata
detect-lua.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 Victor Julien <victor@inliniac.net>
22  *
23  */
24 
25 #include "suricata-common.h"
26 #include "conf.h"
27 
28 #include "decode.h"
29 
30 #include "detect.h"
31 #include "detect-parse.h"
32 
33 #include "detect-engine.h"
34 #include "detect-engine-buffer.h"
35 #include "detect-engine-mpm.h"
36 #include "detect-engine-build.h"
37 
38 #include "detect-byte.h"
39 
40 #include "flow.h"
41 #include "flow-var.h"
42 #include "flow-util.h"
43 
44 #include "util-byte.h"
45 
46 #include "util-unittest.h"
47 #include "util-unittest-helper.h"
48 
49 #include "app-layer.h"
50 #include "app-layer-parser.h"
51 #include "app-layer-htp.h"
52 #include "app-layer-ssl.h"
53 
54 #include "stream-tcp.h"
55 
56 #include "detect-lua.h"
57 #include "detect-lua-extensions.h"
58 
59 #include "util-var-name.h"
60 
61 #include "util-lua.h"
62 #include "util-lua-builtins.h"
63 #include "util-lua-common.h"
64 #include "util-lua-sandbox.h"
65 
66 static int DetectLuaMatch (DetectEngineThreadCtx *,
67  Packet *, const Signature *, const SigMatchCtx *);
68 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
69  Flow *f, uint8_t flags,
70  void *state, void *txv, const Signature *s,
71  const SigMatchCtx *ctx);
72 static int DetectLuaSetup (DetectEngineCtx *, Signature *, const char *);
73 #ifdef UNITTESTS
74 static void DetectLuaRegisterTests(void);
75 #endif
76 static void DetectLuaFree(DetectEngineCtx *, void *);
77 static int g_lua_ja3_list_id = 0;
78 static int g_lua_ja3s_list_id = 0;
79 
80 /**
81  * \brief Registration function for keyword: lua
82  */
84 {
86  sigmatch_table[DETECT_LUA].desc = "match via a lua script";
87  sigmatch_table[DETECT_LUA].url = "/rules/rule-lua-scripting.html";
88  sigmatch_table[DETECT_LUA].Match = DetectLuaMatch;
89  sigmatch_table[DETECT_LUA].AppLayerTxMatch = DetectLuaAppTxMatch;
90  sigmatch_table[DETECT_LUA].Setup = DetectLuaSetup;
91  sigmatch_table[DETECT_LUA].Free = DetectLuaFree;
92 #ifdef UNITTESTS
93  sigmatch_table[DETECT_LUA].RegisterTests = DetectLuaRegisterTests;
94 #endif
95 
96  g_lua_ja3_list_id = DetectBufferTypeRegister("ja3.lua");
101 
102  g_lua_ja3s_list_id = DetectBufferTypeRegister("ja3s.lua");
107 
108  SCLogDebug("registering lua rule option");
109 }
110 
111 /* Flags for DetectLuaThreadData. */
112 #define FLAG_DATATYPE_PACKET BIT_U32(0)
113 #define FLAG_DATATYPE_PAYLOAD BIT_U32(1)
114 #define FLAG_DATATYPE_STREAM BIT_U32(2)
115 #define FLAG_LIST_JA3 BIT_U32(3)
116 #define FLAG_LIST_JA3S BIT_U32(4)
117 #define FLAG_DATATYPE_BUFFER BIT_U32(22)
118 #define FLAG_ERROR_LOGGED BIT_U32(23)
119 #define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
120 #define FLAG_INSTRUCTION_LIMIT_LOGGED BIT_U32(25)
121 #define FLAG_MEMORY_LIMIT_LOGGED BIT_U32(26)
122 
123 #define DEFAULT_LUA_ALLOC_LIMIT 500000
124 #define DEFAULT_LUA_INSTRUCTION_LIMIT 500000
125 
126 /** \brief dump stack from lua state to screen */
127 void LuaDumpStack(lua_State *state, const char *prefix)
128 {
129  int size = lua_gettop(state);
130  printf("%s: size %d\n", prefix, size);
131 
132  for (int i = 1; i <= size; i++) {
133  int type = lua_type(state, i);
134  printf("- %s: Stack size=%d, level=%d, type=%d, ", prefix, size, i, type);
135 
136  switch (type) {
137  case LUA_TFUNCTION:
138  printf("function %s", lua_tostring(state, i));
139  break;
140  case LUA_TBOOLEAN:
141  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
142  break;
143  case LUA_TNUMBER:
144  printf("number %g", lua_tonumber(state, i));
145  break;
146  case LUA_TSTRING:
147  printf("string `%s'", lua_tostring(state, i));
148  break;
149  case LUA_TTABLE:
150  printf("table `%s'", lua_tostring(state, i));
151  break;
152  default:
153  printf("other %s", lua_typename(state, type));
154  break;
155 
156  }
157  printf("\n");
158  }
159 }
160 
161 static void LuaStateSetDetectLuaData(lua_State *state, DetectLuaData *data)
162 {
163  lua_pushlightuserdata(state, (void *)&luaext_key_ld);
164  lua_pushlightuserdata(state, (void *)data);
165  lua_settable(state, LUA_REGISTRYINDEX);
166 }
167 
168 /**
169  * \brief Common function to run the Lua match function and process
170  * the return value.
171  */
172 static int DetectLuaRunMatch(
173  DetectEngineThreadCtx *det_ctx, const DetectLuaData *lua, DetectLuaThreadData *tlua)
174 {
175  /* Reset instruction count. */
177 
178  if (lua_pcall(tlua->luastate, 1, 1, 0) != 0) {
179  const char *reason = lua_tostring(tlua->luastate, -1);
180  SCLuaSbState *context = SCLuaSbGetContext(tlua->luastate);
181  uint32_t flag = 0;
182  if (context->blocked_function_error) {
185  } else if (context->instruction_count_error) {
188  } else if (context->memory_limit_error) {
189  StatsCounterIncr(&det_ctx->tv->stats, det_ctx->lua_memory_limit_errors);
190  reason = "memory limit exceeded";
192  } else {
193  flag = FLAG_ERROR_LOGGED;
194  }
195 
196  /* Log once per thread per error type, the message from Lua
197  * will include the filename. */
198  if (!(tlua->flags & flag)) {
199  SCLogWarning("Lua script failed to run successfully: %s", reason);
200  tlua->flags |= flag;
201  }
202 
203  StatsCounterIncr(&det_ctx->tv->stats, det_ctx->lua_rule_errors);
204  while (lua_gettop(tlua->luastate) > 0) {
205  lua_pop(tlua->luastate, 1);
206  }
207  SCReturnInt(0);
208  }
209 
210  int match = 0;
211 
212  /* process returns from script */
213  if (lua_gettop(tlua->luastate) > 0) {
214  /* script returns a number (return 1 or return 0) */
215  if (lua_type(tlua->luastate, 1) == LUA_TNUMBER) {
216  lua_Integer script_ret = lua_tointeger(tlua->luastate, 1);
217  SCLogDebug("script_ret %lld", script_ret);
218  lua_pop(tlua->luastate, 1);
219  if (script_ret == 1)
220  match = 1;
221  } else {
222  SCLogDebug("Unsupported datatype returned from Lua script");
223  }
224  }
225 
226  if (lua->negated) {
227  if (match == 1)
228  match = 0;
229  else
230  match = 1;
231  }
232 
233  while (lua_gettop(tlua->luastate) > 0) {
234  lua_pop(tlua->luastate, 1);
235  }
236 
237  SCReturnInt(match);
238 }
239 
241  const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset,
242  Flow *f)
243 {
244  SCEnter();
245 
246  if (buffer == NULL || buffer_len == 0)
247  SCReturnInt(0);
248 
249  DetectLuaData *lua = (DetectLuaData *)smd->ctx;
250  if (lua == NULL)
251  SCReturnInt(0);
252 
253  DetectLuaThreadData *tlua =
255  if (tlua == NULL)
256  SCReturnInt(0);
257 
258  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
259 
260  /* prepare data to pass to script */
261  lua_getglobal(tlua->luastate, "match");
262  lua_newtable(tlua->luastate); /* stack at -1 */
263 
264  lua_pushliteral(tlua->luastate, "offset"); /* stack at -2 */
265  lua_pushnumber(tlua->luastate, (int)(offset + 1));
266  lua_settable(tlua->luastate, -3);
267 
268  lua_pushstring(tlua->luastate, lua->buffername); /* stack at -2 */
269  LuaPushStringBuffer(tlua->luastate, (const uint8_t *)buffer, (size_t)buffer_len);
270  lua_settable(tlua->luastate, -3);
271 
272  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
273 }
274 
275 /**
276  * \brief match the specified lua script
277  *
278  * \param t thread local vars
279  * \param det_ctx pattern matcher thread local data
280  * \param p packet
281  * \param s signature being inspected
282  * \param m sigmatch that we will cast into DetectLuaData
283  *
284  * \retval 0 no match
285  * \retval 1 match
286  */
287 static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
288  Packet *p, const Signature *s, const SigMatchCtx *ctx)
289 {
290  SCEnter();
291  DetectLuaData *lua = (DetectLuaData *)ctx;
292  if (lua == NULL)
293  SCReturnInt(0);
294 
296  if (tlua == NULL)
297  SCReturnInt(0);
298 
299  /* setup extension data for use in lua c functions */
300  uint8_t flags = 0;
301  if (p->flowflags & FLOW_PKT_TOSERVER)
302  flags = STREAM_TOSERVER;
303  else if (p->flowflags & FLOW_PKT_TOCLIENT)
304  flags = STREAM_TOCLIENT;
305 
306  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
307 
308  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
309 
310  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
311  SCReturnInt(0);
312  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
313  SCReturnInt(0);
314 
315  lua_getglobal(tlua->luastate, "match");
316  lua_newtable(tlua->luastate); /* stack at -1 */
317 
318  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
319 }
320 
321 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
322  Flow *f, uint8_t flags, void *state,
323  const Signature *s, const SigMatchCtx *ctx)
324 {
325  SCEnter();
326  DetectLuaData *lua = (DetectLuaData *)ctx;
327  if (lua == NULL)
328  SCReturnInt(0);
329 
331  if (tlua == NULL)
332  SCReturnInt(0);
333 
334  /* setup extension data for use in lua c functions */
335  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
336 
337  lua_getglobal(tlua->luastate, "match");
338  lua_newtable(tlua->luastate); /* stack at -1 */
339 
340  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
341 }
342 
343 /**
344  * \brief match the specified lua script in a list with a tx
345  *
346  * \param t thread local vars
347  * \param det_ctx pattern matcher thread local data
348  * \param s signature being inspected
349  * \param m sigmatch that we will cast into DetectLuaData
350  *
351  * \retval 0 no match
352  * \retval 1 match
353  */
354 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
355  Flow *f, uint8_t flags,
356  void *state, void *txv, const Signature *s,
357  const SigMatchCtx *ctx)
358 {
359  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
360 }
361 
362 #ifdef UNITTESTS
363 /* if this ptr is set the lua setup functions will use this buffer as the
364  * lua script instead of calling luaL_loadfile on the filename supplied. */
365 static const char *ut_script = NULL;
366 #endif
367 
368 static void *DetectLuaThreadInit(void *data)
369 {
370  int status;
371  DetectLuaData *lua = (DetectLuaData *)data;
372  BUG_ON(lua == NULL);
373 
375  if (unlikely(t == NULL)) {
376  SCLogError("couldn't alloc ctx memory");
377  return NULL;
378  }
379 
380  t->flags = lua->flags;
381 
383  if (t->luastate == NULL) {
384  SCLogError("luastate pool depleted");
385  goto error;
386  }
387 
388  if (lua->allow_restricted_functions) {
389  luaL_openlibs(t->luastate);
391  } else {
393  }
394 
395  LuaStateSetDetectLuaData(t->luastate, lua);
396 
397  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
398 #ifdef UNITTESTS
399  if (ut_script != NULL) {
400  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
401  if (status) {
402  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
403  goto error;
404  }
405  } else {
406 #endif
407  status = luaL_loadfile(t->luastate, lua->filename);
408  if (status) {
409  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
410  goto error;
411  }
412 #ifdef UNITTESTS
413  }
414 #endif
415 
416  /* prime the script (or something) */
417  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
418  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
419  goto error;
420  }
421 
422  /* thread_init call */
423  lua_getglobal(t->luastate, "thread_init");
424  if (lua_isfunction(t->luastate, -1)) {
425  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
426  SCLogError("couldn't run script 'thread_init' function: %s",
427  lua_tostring(t->luastate, -1));
428  goto error;
429  }
430  } else {
431  lua_pop(t->luastate, 1);
432  }
433 
434  return (void *)t;
435 
436 error:
437  if (t->luastate != NULL)
439  SCFree(t);
440  return NULL;
441 }
442 
443 static void DetectLuaThreadFree(void *ctx)
444 {
445  if (ctx != NULL) {
447  if (t->luastate != NULL)
449  SCFree(t);
450  }
451 }
452 
453 /**
454  * \brief Parse the lua keyword
455  *
456  * \param de_ctx Pointer to the detection engine context
457  * \param str Pointer to the user provided option
458  *
459  * \retval lua pointer to DetectLuaData on success
460  * \retval NULL on failure
461  */
462 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
463 {
464  DetectLuaData *lua = NULL;
465 
466  /* We have a correct lua option */
467  lua = SCCalloc(1, sizeof(DetectLuaData));
468  if (unlikely(lua == NULL))
469  goto error;
470 
471  if (strlen(str) && str[0] == '!') {
472  lua->negated = 1;
473  str++;
474  }
475 
476  /* get full filename */
478  if (lua->filename == NULL) {
479  goto error;
480  }
481 
482  return lua;
483 
484 error:
485  DetectLuaFree(de_ctx, lua);
486  return NULL;
487 }
488 
489 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
490 {
491  int status;
492 
494  if (luastate == NULL)
495  return -1;
496  if (ld->allow_restricted_functions) {
497  luaL_openlibs(luastate);
498  SCLuaRequirefBuiltIns(luastate);
499  } else {
500  SCLuaSbLoadLibs(luastate);
501  }
502  LuaStateSetDetectLuaData(luastate, ld);
503 
504  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
505 #ifdef UNITTESTS
506  if (ut_script != NULL) {
507  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
508  if (status) {
509  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
510  goto error;
511  }
512  } else {
513 #endif
514  status = luaL_loadfile(luastate, ld->filename);
515  if (status) {
516  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
517  goto error;
518  }
519 #ifdef UNITTESTS
520  }
521 #endif
522 
523  /* prime the script (or something) */
524  if (lua_pcall(luastate, 0, 0, 0) != 0) {
525  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
526  goto error;
527  }
528 
529  lua_getglobal(luastate, "init");
530  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
531  SCLogError("no init function in script");
532  goto error;
533  }
534 
535  /* Pass the signature as the first argument, setting up bytevars depends on
536  * access to the signature. */
537  lua_pushlightuserdata(luastate, (void *)s);
538 
539  if (lua_pcall(luastate, 1, 1, 0) != 0) {
540  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
541  goto error;
542  }
543 
544  /* process returns from script */
545  if (lua_gettop(luastate) == 0) {
546  SCLogError("init function in script should return table, nothing returned");
547  goto error;
548  }
549  if (lua_type(luastate, 1) != LUA_TTABLE) {
550  SCLogError("init function in script should return table, returned is not table");
551  goto error;
552  }
553 
554  lua_pushnil(luastate);
555  const char *k;
556  while (lua_next(luastate, -2)) {
557  k = lua_tostring(luastate, -2);
558  if (k == NULL)
559  continue;
560 
561  /* handle flowvar and bytes separately as they have a table as value */
562  if (strcmp(k, "flowvar") == 0) {
563  if (lua_istable(luastate, -1)) {
564  lua_pushnil(luastate);
565  while (lua_next(luastate, -2) != 0) {
566  /* value at -1, key is at -2 which we ignore */
567  const char *value = lua_tostring(luastate, -1);
568  SCLogDebug("value %s", value);
569  /* removes 'value'; keeps 'key' for next iteration */
570  lua_pop(luastate, 1);
571 
572  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
573  SCLogError("too many flowvars registered");
574  goto error;
575  }
576 
577  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
578  if (unlikely(idx == 0))
579  goto error;
580  ld->flowvar[ld->flowvars++] = idx;
581  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
582  }
583  }
584  lua_pop(luastate, 1);
585  continue;
586  } else if (strcmp(k, "flowint") == 0) {
587  if (lua_istable(luastate, -1)) {
588  lua_pushnil(luastate);
589  while (lua_next(luastate, -2) != 0) {
590  /* value at -1, key is at -2 which we ignore */
591  const char *value = lua_tostring(luastate, -1);
592  SCLogDebug("value %s", value);
593  /* removes 'value'; keeps 'key' for next iteration */
594  lua_pop(luastate, 1);
595 
596  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
597  SCLogError("too many flowints registered");
598  goto error;
599  }
600 
601  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
602  if (unlikely(idx == 0))
603  goto error;
604  ld->flowint[ld->flowints++] = idx;
605  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
606  }
607  }
608  lua_pop(luastate, 1);
609  continue;
610  }
611 
612  bool required = lua_toboolean(luastate, -1);
613  lua_pop(luastate, 1);
614  if (!required) {
615  continue;
616  }
617 
618  if (strcmp(k, "ja3") == 0) {
619  ld->flags |= FLAG_LIST_JA3;
620  } else if (strcmp(k, "ja3s") == 0) {
621  ld->flags |= FLAG_LIST_JA3S;
622  } else if (strcmp(k, "packet") == 0) {
624  } else if (strcmp(k, "payload") == 0) {
626  } else if (strcmp(k, "buffer") == 0) {
628 
629  ld->buffername = SCStrdup("buffer");
630  if (ld->buffername == NULL) {
631  SCLogError("alloc error");
632  goto error;
633  }
634  } else if (strcmp(k, "stream") == 0) {
636 
637  ld->buffername = SCStrdup("stream");
638  if (ld->buffername == NULL) {
639  SCLogError("alloc error");
640  goto error;
641  }
642  /* old options no longer supported */
643  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
644  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
645  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
646  SCLogError("data type %s no longer supported, use rule hooks", k);
647  goto error;
648 
649  } else {
650  SCLogError("unsupported data type %s", k);
651  goto error;
652  }
653  }
654 
655  /* pop the table */
656  lua_pop(luastate, 1);
657  SCLuaSbStateClose(luastate);
658  return 0;
659 error:
660  SCLuaSbStateClose(luastate);
661  return -1;
662 }
663 
664 /**
665  * \brief this function is used to parse lua options
666  * \brief into the current signature
667  *
668  * \param de_ctx pointer to the Detection Engine Context
669  * \param s pointer to the Current Signature
670  * \param str pointer to the user provided "lua" option
671  *
672  * \retval 0 on Success
673  * \retval -1 on Failure
674  */
675 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
676 {
677  /* First check if Lua rules are enabled, by default Lua in rules
678  * is disabled. */
679  int enabled = 0;
680  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
681  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
682  return -1;
683  }
684 
685  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
686  if (lua == NULL)
687  return -1;
688 
689  /* Load lua sandbox configurations */
690  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
691  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
692  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
693  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
694  lua->alloc_limit = lua_alloc_limit;
695  lua->instruction_limit = lua_instruction_limit;
696 
697  int allow_restricted_functions = 0;
698  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
699  lua->allow_restricted_functions = allow_restricted_functions;
700 
701  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
702  goto error;
703  }
704 
706  DetectLuaThreadInit, (void *)lua,
707  DetectLuaThreadFree, 0);
708  if (lua->thread_ctx_id == -1)
709  goto error;
710 
711  int list = DetectBufferGetActiveList(de_ctx, s);
712  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
713  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
714  /* what needs to happen here is: we register to the rule hook, so e.g.
715  * http1.request_complete. This means we need a list.
716  *
717  * This includes each pkt, payload, stream, etc. */
718 
720  list = s->init_data->hook.sm_list;
721  SCLogDebug("setting list %d", list);
722  }
723  }
724 
725  if (list == -1) {
726  SCLogError("lua failed to set up");
727  goto error;
728  }
729  if (list == 0) {
730  if (lua->flags & FLAG_LIST_JA3) {
731  list = g_lua_ja3_list_id;
732  } else if (lua->flags & FLAG_LIST_JA3S) {
733  list = g_lua_ja3s_list_id;
734  }
735  }
736 
737  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
738  goto error;
739  }
740 
741  return 0;
742 
743 error:
744  if (lua != NULL)
745  DetectLuaFree(de_ctx, lua);
746  return -1;
747 }
748 
749 /**
750  * \brief this function will free memory associated with DetectLuaData
751  *
752  * \param ptr pointer to DetectLuaData
753  */
754 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
755 {
756  if (ptr != NULL) {
757  DetectLuaData *lua = (DetectLuaData *)ptr;
758 
759  if (lua->buffername)
760  SCFree(lua->buffername);
761  if (lua->filename)
762  SCFree(lua->filename);
763 
764  for (uint16_t i = 0; i < lua->flowints; i++) {
766  }
767  for (uint16_t i = 0; i < lua->flowvars; i++) {
769  }
770  for (uint16_t i = 0; i < lua->bytevars; i++) {
771  SCFree(lua->bytevar[i].name);
772  }
773 
775 
776  SCFree(lua);
777  }
778 }
779 
780 #ifdef UNITTESTS
781 #include "detect-engine-alert.h"
782 
783 /** \test http buffer */
784 static int LuaMatchTest01(void)
785 {
786  SCConfSetFinal("security.lua.allow-rules", "true");
787 
788  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
789  "function init (args)\n"
790  " flowvarlib.register(\"cnt\")\n"
791  " return {}\n"
792  "end\n"
793  "function thread_init (args)\n"
794  " cnt = flowvarlib.get(\"cnt\")\n"
795  "end\n"
796  "\n"
797  "function match(args)\n"
798  " a = cnt:value()\n"
799  " if a then\n"
800  " a = tostring(tonumber(a)+1)\n"
801  " print (a)\n"
802  " cnt:set(a, #a)\n"
803  " else\n"
804  " a = tostring(1)\n"
805  " print (a)\n"
806  " cnt:set(a, #a)\n"
807  " end\n"
808  " \n"
809  " print (\"pre check: \" .. (a))\n"
810  " if tonumber(a) == 2 then\n"
811  " print \"match\"\n"
812  " return 1\n"
813  " end\n"
814  " return 0\n"
815  "end\n"
816  "return 0\n";
817  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
818  "sid:1;)";
819  uint8_t httpbuf1[] =
820  "POST / HTTP/1.1\r\n"
821  "Host: www.emergingthreats.net\r\n\r\n";
822  uint8_t httpbuf2[] =
823  "POST / HTTP/1.1\r\n"
824  "Host: www.openinfosecfoundation.org\r\n\r\n";
825  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
826  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
827  TcpSession ssn;
828  Flow f;
829  ThreadVars th_v;
830  DetectEngineThreadCtx *det_ctx;
831 
833 
834  ut_script = script;
835 
836  memset(&th_v, 0, sizeof(th_v));
837  StatsThreadInit(&th_v.stats);
838  memset(&f, 0, sizeof(f));
839  memset(&ssn, 0, sizeof(ssn));
840 
841  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
842  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
843 
844  FLOW_INITIALIZE(&f);
845  f.protoctx = (void *)&ssn;
846  f.proto = IPPROTO_TCP;
847  f.flags |= FLOW_IPV4;
849 
850  p1->flow = &f;
854  p2->flow = &f;
858 
859  StreamTcpInitConfig(true);
860 
863  de_ctx->flags |= DE_QUIET;
864 
866  FAIL_IF_NULL(s);
867 
869  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
870 
871  int r = AppLayerParserParse(
872  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
873  FAIL_IF(r != 0);
874  HtpState *http_state = f.alstate;
875  FAIL_IF_NULL(http_state);
876 
877  /* do detect for p1 */
878  SCLogDebug("inspecting p1");
879  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
880  FAIL_IF(PacketAlertCheck(p1, 1));
881 
882  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
883  FAIL_IF(r != 0);
884 
885  /* do detect for p2 */
886  SCLogDebug("inspecting p2");
887  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
889 
890  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
891  FAIL_IF(id == 0);
892 
893  FlowVar *fv = FlowVarGet(&f, id);
894  FAIL_IF_NULL(fv);
895  FAIL_IF(fv->data.fv_str.value_len != 1);
896  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
897 
898  UTHFreePackets(&p1, 1);
899  UTHFreePackets(&p2, 1);
900  FLOW_DESTROY(&f);
901 
903  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
905  StreamTcpFreeConfig(true);
906  StatsThreadCleanup(&th_v.stats);
907  PASS;
908 }
909 
910 static int LuaMatchTest01a(void)
911 {
912  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
913  "function init (args)\n"
914  " flowvarlib.register(\"cnt\")\n"
915  " return {}\n"
916  "end\n"
917  "function thread_init (args)\n"
918  " cnt = flowvarlib.get(\"cnt\")\n"
919  "end\n"
920  "\n"
921  "function match(args)\n"
922  " a = cnt:value(0)\n"
923  " if a then\n"
924  " a = tostring(tonumber(a)+1)\n"
925  " print (a)\n"
926  " cnt:set(a, #a)\n"
927  " else\n"
928  " a = tostring(1)\n"
929  " print (a)\n"
930  " cnt:set(a, #a)\n"
931  " end\n"
932  " \n"
933  " print (\"pre check: \" .. (a))\n"
934  " if tonumber(a) == 2 then\n"
935  " print \"match\"\n"
936  " return 1\n"
937  " end\n"
938  " return 0\n"
939  "end\n"
940  "return 0\n";
941  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
942  "sid:1;)";
943  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
944  "Host: www.emergingthreats.net\r\n\r\n";
945  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
946  "Host: www.openinfosecfoundation.org\r\n\r\n";
947  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
948  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
949  TcpSession ssn;
950  Flow f;
951  ThreadVars th_v;
952  DetectEngineThreadCtx *det_ctx;
953 
955 
956  ut_script = script;
957 
958  memset(&th_v, 0, sizeof(th_v));
959  StatsThreadInit(&th_v.stats);
960  memset(&f, 0, sizeof(f));
961  memset(&ssn, 0, sizeof(ssn));
962 
963  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
964  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
965 
966  FLOW_INITIALIZE(&f);
967  f.protoctx = (void *)&ssn;
968  f.proto = IPPROTO_TCP;
969  f.flags |= FLOW_IPV4;
971 
972  p1->flow = &f;
976  p2->flow = &f;
980 
981  StreamTcpInitConfig(true);
982 
985  de_ctx->flags |= DE_QUIET;
986 
988  FAIL_IF_NULL(s);
989 
991  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
992 
993  int r = AppLayerParserParse(
994  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
995  FAIL_IF(r != 0);
996 
997  HtpState *http_state = f.alstate;
998  FAIL_IF_NULL(http_state);
999 
1000  /* do detect for p1 */
1001  SCLogDebug("inspecting p1");
1002  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1003  FAIL_IF(PacketAlertCheck(p1, 1));
1004 
1005  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1006  FAIL_IF(r != 0);
1007  /* do detect for p2 */
1008  SCLogDebug("inspecting p2");
1009  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1010  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1011 
1012  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1013  FAIL_IF(id == 0);
1014 
1015  FlowVar *fv = FlowVarGet(&f, id);
1016  FAIL_IF_NULL(fv);
1017  FAIL_IF(fv->data.fv_str.value_len != 1);
1018  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1019 
1020  UTHFreePackets(&p1, 1);
1021  UTHFreePackets(&p2, 1);
1022  FLOW_DESTROY(&f);
1023 
1025  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1027  StreamTcpFreeConfig(true);
1028  StatsThreadCleanup(&th_v.stats);
1029  PASS;
1030 }
1031 
1032 /** \test payload buffer */
1033 static int LuaMatchTest02(void)
1034 {
1035  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1036  "function init (args)\n"
1037  " flowvarlib.register(\"cnt\")\n"
1038  " local needs = {}\n"
1039  " needs[\"payload\"] = tostring(true)\n"
1040  " return needs\n"
1041  "end\n"
1042  "function thread_init (args)\n"
1043  " cnt = flowvarlib.get(\"cnt\")\n"
1044  "end\n"
1045  "\n"
1046  "function match(args)\n"
1047  " a = cnt:value()\n"
1048  " if a then\n"
1049  " a = tostring(tonumber(a)+1)\n"
1050  " print (a)\n"
1051  " cnt:set(a, #a)\n"
1052  " else\n"
1053  " a = tostring(1)\n"
1054  " print (a)\n"
1055  " cnt:set(a, #a)\n"
1056  " end\n"
1057  " \n"
1058  " print (\"pre check: \" .. (a))\n"
1059  " if tonumber(a) == 2 then\n"
1060  " print \"match\"\n"
1061  " return 1\n"
1062  " end\n"
1063  " return 0\n"
1064  "end\n"
1065  "return 0\n";
1066  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1067  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1068  "Host: www.emergingthreats.net\r\n\r\n";
1069  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1070  "Host: www.openinfosecfoundation.org\r\n\r\n";
1071  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1072  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1073  TcpSession ssn;
1074  Flow f;
1075  ThreadVars th_v;
1076  DetectEngineThreadCtx *det_ctx;
1077 
1078  ut_script = script;
1079 
1080  memset(&th_v, 0, sizeof(th_v));
1081  StatsThreadInit(&th_v.stats);
1082  memset(&f, 0, sizeof(f));
1083  memset(&ssn, 0, sizeof(ssn));
1084 
1085  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1086  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1087 
1088  FLOW_INITIALIZE(&f);
1089  f.protoctx = (void *)&ssn;
1090  f.proto = IPPROTO_TCP;
1091  f.flags |= FLOW_IPV4;
1092  f.alproto = ALPROTO_HTTP1;
1093 
1094  p1->flow = &f;
1098  p2->flow = &f;
1102 
1103  StreamTcpInitConfig(true);
1104 
1107  de_ctx->flags |= DE_QUIET;
1108 
1110  FAIL_IF_NULL(s);
1111 
1113  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1114 
1115  /* do detect for p1 */
1116  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1117 
1118  FAIL_IF(PacketAlertCheck(p1, 1));
1119 
1120  /* do detect for p2 */
1121  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1122 
1123  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1124 
1125  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1126  FAIL_IF(id == 0);
1127 
1128  FlowVar *fv = FlowVarGet(&f, id);
1129  FAIL_IF_NULL(fv);
1130  FAIL_IF(fv->data.fv_str.value_len != 1);
1131  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1132 
1133  UTHFreePackets(&p1, 1);
1134  UTHFreePackets(&p2, 1);
1135  FLOW_DESTROY(&f);
1136 
1137  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1139  StreamTcpFreeConfig(true);
1140  StatsThreadCleanup(&th_v.stats);
1141  PASS;
1142 }
1143 
1144 /** \test payload buffer */
1145 static int LuaMatchTest02a(void)
1146 {
1147  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1148  "function init (args)\n"
1149  " flowvarlib.register(\"cnt\")"
1150  " local needs = {}\n"
1151  " needs[\"payload\"] = tostring(true)\n"
1152  " return needs\n"
1153  "end\n"
1154  "function thread_init (args)\n"
1155  " cnt = flowvarlib.get(\"cnt\")"
1156  "end\n"
1157  "\n"
1158  "function match(args)\n"
1159  " a = cnt:value()\n"
1160  " if a then\n"
1161  " a = tostring(tonumber(a)+1)\n"
1162  " print (a)\n"
1163  " cnt:set(a, #a)\n"
1164  " else\n"
1165  " a = tostring(1)\n"
1166  " print (a)\n"
1167  " cnt:set(a, #a)\n"
1168  " end\n"
1169  " \n"
1170  " print (\"pre check: \" .. (a))\n"
1171  " if tonumber(a) == 2 then\n"
1172  " print \"match\"\n"
1173  " return 1\n"
1174  " end\n"
1175  " return 0\n"
1176  "end\n"
1177  "return 0\n";
1178  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1179  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1180  "Host: www.emergingthreats.net\r\n\r\n";
1181  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1182  "Host: www.openinfosecfoundation.org\r\n\r\n";
1183  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1184  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1185  TcpSession ssn;
1186  Flow f;
1187  ThreadVars th_v;
1188  DetectEngineThreadCtx *det_ctx;
1189 
1190  ut_script = script;
1191 
1192  memset(&th_v, 0, sizeof(th_v));
1193  StatsThreadInit(&th_v.stats);
1194  memset(&f, 0, sizeof(f));
1195  memset(&ssn, 0, sizeof(ssn));
1196 
1197  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1198  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1199 
1200  FLOW_INITIALIZE(&f);
1201  f.protoctx = (void *)&ssn;
1202  f.proto = IPPROTO_TCP;
1203  f.flags |= FLOW_IPV4;
1204  f.alproto = ALPROTO_HTTP1;
1205 
1206  p1->flow = &f;
1210  p2->flow = &f;
1214 
1215  StreamTcpInitConfig(true);
1216 
1219  de_ctx->flags |= DE_QUIET;
1220 
1222  FAIL_IF_NULL(s);
1223 
1225  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1226 
1227  /* do detect for p1 */
1228  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1229  FAIL_IF(PacketAlertCheck(p1, 1));
1230 
1231  /* do detect for p2 */
1232  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1233  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1234 
1235  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1236  FAIL_IF(id == 0);
1237 
1238  FlowVar *fv = FlowVarGet(&f, id);
1239  FAIL_IF_NULL(fv);
1240  FAIL_IF(fv->data.fv_str.value_len != 1);
1241  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1242 
1243  UTHFreePackets(&p1, 1);
1244  UTHFreePackets(&p2, 1);
1245  FLOW_DESTROY(&f);
1246 
1247  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1249  StreamTcpFreeConfig(true);
1250  StatsThreadCleanup(&th_v.stats);
1251  PASS;
1252 }
1253 
1254 /** \test packet buffer */
1255 static int LuaMatchTest03(void)
1256 {
1257  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1258  "function init (args)\n"
1259  " flowvarlib.register(\"cnt\")\n"
1260  " local needs = {}\n"
1261  " needs[\"packet\"] = tostring(true)\n"
1262  " return needs\n"
1263  "end\n"
1264  "\n"
1265  "function thread_init (args)\n"
1266  " cnt = flowvarlib.get(\"cnt\")\n"
1267  "end\n"
1268  "\n"
1269  "function match(args)\n"
1270  " a = cnt:value()\n"
1271  " if a then\n"
1272  " a = tostring(tonumber(a)+1)\n"
1273  " print (a)\n"
1274  " cnt:set(a, #a)\n"
1275  " else\n"
1276  " a = tostring(1)\n"
1277  " print (a)\n"
1278  " cnt:set(a, #a)\n"
1279  " end\n"
1280  " \n"
1281  " print (\"pre check: \" .. (a))\n"
1282  " if tonumber(a) == 2 then\n"
1283  " print \"match\"\n"
1284  " return 1\n"
1285  " end\n"
1286  " return 0\n"
1287  "end\n"
1288  "return 0\n";
1289  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1290  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1291  "Host: www.emergingthreats.net\r\n\r\n";
1292  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1293  "Host: www.openinfosecfoundation.org\r\n\r\n";
1294  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1295  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1296  TcpSession ssn;
1297  Flow f;
1298  ThreadVars th_v;
1299  DetectEngineThreadCtx *det_ctx;
1300 
1301  ut_script = script;
1302 
1303  memset(&th_v, 0, sizeof(th_v));
1304  StatsThreadInit(&th_v.stats);
1305  memset(&f, 0, sizeof(f));
1306  memset(&ssn, 0, sizeof(ssn));
1307 
1308  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1309  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1310 
1311  FLOW_INITIALIZE(&f);
1312  f.protoctx = (void *)&ssn;
1313  f.proto = IPPROTO_TCP;
1314  f.flags |= FLOW_IPV4;
1315  f.alproto = ALPROTO_HTTP1;
1316 
1317  p1->flow = &f;
1321  p2->flow = &f;
1325 
1326  StreamTcpInitConfig(true);
1327 
1330  de_ctx->flags |= DE_QUIET;
1331 
1333  FAIL_IF_NULL(s);
1334 
1336  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1337 
1338  /* do detect for p1 */
1339  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1340  FAIL_IF(PacketAlertCheck(p1, 1));
1341 
1342  /* do detect for p2 */
1343  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1344  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1345 
1346  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1347  FAIL_IF(id == 0);
1348  FlowVar *fv = FlowVarGet(&f, id);
1349  FAIL_IF_NULL(fv);
1350  FAIL_IF(fv->data.fv_str.value_len != 1);
1351  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1352 
1353  UTHFreePackets(&p1, 1);
1354  UTHFreePackets(&p2, 1);
1355  FLOW_DESTROY(&f);
1356 
1357  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1359  StreamTcpFreeConfig(true);
1360  StatsThreadCleanup(&th_v.stats);
1361  PASS;
1362 }
1363 
1364 /** \test packet buffer */
1365 static int LuaMatchTest03a(void)
1366 {
1367  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1368  "function init (args)\n"
1369  " flowvarlib.register(\"cnt\")\n"
1370  " local needs = {}\n"
1371  " needs[\"packet\"] = tostring(true)\n"
1372  " return needs\n"
1373  "end\n"
1374  "\n"
1375  "function thread_init (args)\n"
1376  " cnt = flowvarlib.get(\"cnt\")\n"
1377  "end\n"
1378  "\n"
1379  "function match(args)\n"
1380  " a = cnt:value()\n"
1381  " if a then\n"
1382  " a = tostring(tonumber(a)+1)\n"
1383  " print (a)\n"
1384  " cnt:set(a, #a)\n"
1385  " else\n"
1386  " a = tostring(1)\n"
1387  " print (a)\n"
1388  " cnt:set(a, #a)\n"
1389  " end\n"
1390  " \n"
1391  " print (\"pre check: \" .. (a))\n"
1392  " if tonumber(a) == 2 then\n"
1393  " print \"match\"\n"
1394  " return 1\n"
1395  " end\n"
1396  " return 0\n"
1397  "end\n"
1398  "return 0\n";
1399  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1400  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1401  "Host: www.emergingthreats.net\r\n\r\n";
1402  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1403  "Host: www.openinfosecfoundation.org\r\n\r\n";
1404  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1405  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1406  TcpSession ssn;
1407  Flow f;
1408  ThreadVars th_v;
1409  DetectEngineThreadCtx *det_ctx;
1410 
1411  ut_script = script;
1412 
1413  memset(&th_v, 0, sizeof(th_v));
1414  StatsThreadInit(&th_v.stats);
1415  memset(&f, 0, sizeof(f));
1416  memset(&ssn, 0, sizeof(ssn));
1417 
1418  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1419  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1420 
1421  FLOW_INITIALIZE(&f);
1422  f.protoctx = (void *)&ssn;
1423  f.proto = IPPROTO_TCP;
1424  f.flags |= FLOW_IPV4;
1425  f.alproto = ALPROTO_HTTP1;
1426 
1427  p1->flow = &f;
1431  p2->flow = &f;
1435 
1436  StreamTcpInitConfig(true);
1437 
1440  de_ctx->flags |= DE_QUIET;
1441 
1443  FAIL_IF_NULL(s);
1444 
1446  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1447 
1448  /* do detect for p1 */
1449  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1450  FAIL_IF(PacketAlertCheck(p1, 1));
1451 
1452  /* do detect for p2 */
1453  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1454  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1455 
1456  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1457  FAIL_IF(id == 0);
1458  FlowVar *fv = FlowVarGet(&f, id);
1459  FAIL_IF_NULL(fv);
1460  FAIL_IF(fv->data.fv_str.value_len != 1);
1461  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1462 
1463  UTHFreePackets(&p1, 1);
1464  UTHFreePackets(&p2, 1);
1465  FLOW_DESTROY(&f);
1466 
1467  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1469  StreamTcpFreeConfig(true);
1470  StatsThreadCleanup(&th_v.stats);
1471  PASS;
1472 }
1473 
1474 /** \test http buffer, flowints */
1475 static int LuaMatchTest04(void)
1476 {
1477  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1478  "function init (args)\n"
1479  " flowintlib.register(\"cnt\")\n"
1480  " return {}\n"
1481  "end\n"
1482  "\n"
1483  "function thread_init (args)\n"
1484  " cnt = flowintlib.get(\"cnt\")\n"
1485  "end\n"
1486  "\n"
1487  "function match(args)\n"
1488  " print \"inspecting\""
1489  " a = cnt:value()\n"
1490  " if a then\n"
1491  " cnt:set(a + 1)\n"
1492  " else\n"
1493  " cnt:set(1)\n"
1494  " end\n"
1495  " \n"
1496  " a = cnt:value()\n"
1497  " if a == 2 then\n"
1498  " print \"match\"\n"
1499  " return 1\n"
1500  " end\n"
1501  " return 0\n"
1502  "end\n"
1503  "return 0\n";
1504  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1505  "sid:1;)";
1506  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1507  "Host: www.emergingthreats.net\r\n\r\n";
1508  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1509  "Host: www.openinfosecfoundation.org\r\n\r\n";
1510  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1511  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1512  TcpSession ssn;
1513  Flow f;
1514  ThreadVars th_v;
1515  DetectEngineThreadCtx *det_ctx;
1516 
1518 
1519  ut_script = script;
1520 
1521  memset(&th_v, 0, sizeof(th_v));
1522  StatsThreadInit(&th_v.stats);
1523  memset(&f, 0, sizeof(f));
1524  memset(&ssn, 0, sizeof(ssn));
1525 
1526  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1527  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1528 
1529  FLOW_INITIALIZE(&f);
1530  f.protoctx = (void *)&ssn;
1531  f.proto = IPPROTO_TCP;
1532  f.flags |= FLOW_IPV4;
1533  f.alproto = ALPROTO_HTTP1;
1534 
1535  p1->flow = &f;
1539 
1540  p2->flow = &f;
1544 
1545  StreamTcpInitConfig(true);
1546 
1549  de_ctx->flags |= DE_QUIET;
1550 
1552  FAIL_IF_NULL(s);
1553 
1555  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1556 
1557  int r = AppLayerParserParse(
1558  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1559  FAIL_IF(r != 0);
1560  HtpState *http_state = f.alstate;
1561  FAIL_IF_NULL(http_state);
1562 
1563  /* do detect for p1 */
1564  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1565  FAIL_IF(PacketAlertCheck(p1, 1));
1566 
1567  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1568  FAIL_IF(r != 0);
1569 
1570  /* do detect for p2 */
1571  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1572  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1573 
1574  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1575  FAIL_IF(id == 0);
1576  FlowVar *fv = FlowVarGet(&f, id);
1577  FAIL_IF_NULL(fv);
1578  FAIL_IF(fv->data.fv_int.value != 2);
1579 
1580  UTHFreePackets(&p1, 1);
1581  UTHFreePackets(&p2, 1);
1582  FLOW_DESTROY(&f);
1583 
1585  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1587  StreamTcpFreeConfig(true);
1588  StatsThreadCleanup(&th_v.stats);
1589  PASS;
1590 }
1591 
1592 /** \test http buffer, flowints */
1593 static int LuaMatchTest04a(void)
1594 {
1595  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1596  "function init (args)\n"
1597  " flowintlib.register(\"cnt\")\n"
1598  " return {}\n"
1599  "end\n"
1600  "\n"
1601  "function thread_init (args)\n"
1602  " cnt = flowintlib.get(\"cnt\")\n"
1603  "end\n"
1604  "\n"
1605  "function match(args)\n"
1606  " print \"inspecting\""
1607  " a = cnt:value()\n"
1608  " if a then\n"
1609  " cnt:set(a + 1)\n"
1610  " else\n"
1611  " cnt:set(1)\n"
1612  " end\n"
1613  " \n"
1614  " a = cnt:value()\n"
1615  " if a == 2 then\n"
1616  " print \"match\"\n"
1617  " return 1\n"
1618  " end\n"
1619  " return 0\n"
1620  "end\n"
1621  "return 0\n";
1622  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1623  "sid:1;)";
1624  uint8_t httpbuf1[] =
1625  "POST / HTTP/1.1\r\n"
1626  "Host: www.emergingthreats.net\r\n\r\n";
1627  uint8_t httpbuf2[] =
1628  "POST / HTTP/1.1\r\n"
1629  "Host: www.openinfosecfoundation.org\r\n\r\n";
1630  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1631  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1632  TcpSession ssn;
1633  Flow f;
1634  ThreadVars th_v;
1635  DetectEngineThreadCtx *det_ctx;
1636 
1638 
1639  ut_script = script;
1640 
1641  memset(&th_v, 0, sizeof(th_v));
1642  StatsThreadInit(&th_v.stats);
1643  memset(&f, 0, sizeof(f));
1644  memset(&ssn, 0, sizeof(ssn));
1645 
1646  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1647  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1648 
1649  FLOW_INITIALIZE(&f);
1650  f.protoctx = (void *)&ssn;
1651  f.proto = IPPROTO_TCP;
1652  f.flags |= FLOW_IPV4;
1653  f.alproto = ALPROTO_HTTP1;
1654 
1655  p1->flow = &f;
1659 
1660  p2->flow = &f;
1664 
1665  StreamTcpInitConfig(true);
1666 
1669  de_ctx->flags |= DE_QUIET;
1670 
1672  FAIL_IF_NULL(s);
1673 
1675  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1676 
1677  int r = AppLayerParserParse(
1678  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1679  FAIL_IF(r != 0);
1680  HtpState *http_state = f.alstate;
1681  FAIL_IF_NULL(http_state);
1682 
1683  /* do detect for p1 */
1684  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1685  FAIL_IF(PacketAlertCheck(p1, 1));
1686 
1687  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1688  FAIL_IF(r != 0);
1689 
1690  /* do detect for p2 */
1691  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1692  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1693 
1694  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1695  FAIL_IF(id == 0);
1696  FlowVar *fv = FlowVarGet(&f, id);
1697  FAIL_IF_NULL(fv);
1698  FAIL_IF(fv->data.fv_int.value != 2);
1699 
1700  UTHFreePackets(&p1, 1);
1701  UTHFreePackets(&p2, 1);
1702  FLOW_DESTROY(&f);
1703 
1705  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1707  StreamTcpFreeConfig(true);
1708  StatsThreadCleanup(&th_v.stats);
1709  PASS;
1710 }
1711 
1712 /** \test http buffer, flowints */
1713 static int LuaMatchTest05(void)
1714 {
1715  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1716  "function init (args)\n"
1717  " flowintlib.register(\"cnt\")\n"
1718  " return {}\n"
1719  "end\n"
1720  "\n"
1721  "function thread_init (args)\n"
1722  " cnt = flowintlib.get(\"cnt\")\n"
1723  "end\n"
1724  "\n"
1725  "function match(args)\n"
1726  " print \"inspecting\""
1727  " a = cnt:incr()\n"
1728  " if a == 2 then\n"
1729  " print \"match\"\n"
1730  " return 1\n"
1731  " end\n"
1732  " return 0\n"
1733  "end\n"
1734  "return 0\n";
1735  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1736  "sid:1;)";
1737  uint8_t httpbuf1[] =
1738  "POST / HTTP/1.1\r\n"
1739  "Host: www.emergingthreats.net\r\n\r\n";
1740  uint8_t httpbuf2[] =
1741  "POST / HTTP/1.1\r\n"
1742  "Host: www.openinfosecfoundation.org\r\n\r\n";
1743  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1744  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1745  TcpSession ssn;
1746  Flow f;
1747  ThreadVars th_v;
1748  DetectEngineThreadCtx *det_ctx;
1749 
1751 
1752  ut_script = script;
1753 
1754  memset(&th_v, 0, sizeof(th_v));
1755  StatsThreadInit(&th_v.stats);
1756  memset(&f, 0, sizeof(f));
1757  memset(&ssn, 0, sizeof(ssn));
1758 
1759  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1760  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1761 
1762  FLOW_INITIALIZE(&f);
1763  f.protoctx = (void *)&ssn;
1764  f.proto = IPPROTO_TCP;
1765  f.flags |= FLOW_IPV4;
1766  f.alproto = ALPROTO_HTTP1;
1767 
1768  p1->flow = &f;
1772 
1773  p2->flow = &f;
1777 
1778  StreamTcpInitConfig(true);
1779 
1782  de_ctx->flags |= DE_QUIET;
1783 
1785  FAIL_IF_NULL(s);
1786 
1788  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1789 
1790  int r = AppLayerParserParse(
1791  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1792  FAIL_IF(r != 0);
1793  HtpState *http_state = f.alstate;
1794  FAIL_IF_NULL(http_state);
1795 
1796  /* do detect for p1 */
1797  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1798  FAIL_IF(PacketAlertCheck(p1, 1));
1799 
1800  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1801  FAIL_IF(r != 0);
1802 
1803  /* do detect for p2 */
1804  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1805  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1806 
1807  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1808  FAIL_IF(id == 0);
1809  FlowVar *fv = FlowVarGet(&f, id);
1810  FAIL_IF_NULL(fv);
1811  FAIL_IF(fv->data.fv_int.value != 2);
1812 
1813  UTHFreePackets(&p1, 1);
1814  UTHFreePackets(&p2, 1);
1815  FLOW_DESTROY(&f);
1816 
1818  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1820  StreamTcpFreeConfig(true);
1821  StatsThreadCleanup(&th_v.stats);
1822  PASS;
1823 }
1824 
1825 /** \test http buffer, flowints */
1826 static int LuaMatchTest05a(void)
1827 {
1828  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1829  "function init (args)\n"
1830  " flowintlib.register(\"cnt\")\n"
1831  " return {}\n"
1832  "end\n"
1833  "\n"
1834  "function thread_init (args)\n"
1835  " cnt = flowintlib.get(\"cnt\")\n"
1836  "end\n"
1837  "\n"
1838  "function match(args)\n"
1839  " print \"inspecting\""
1840  " a = cnt:incr()\n"
1841  " if a == 2 then\n"
1842  " print \"match\"\n"
1843  " return 1\n"
1844  " end\n"
1845  " return 0\n"
1846  "end\n"
1847  "return 0\n";
1848  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1849  "sid:1;)";
1850  uint8_t httpbuf1[] =
1851  "POST / HTTP/1.1\r\n"
1852  "Host: www.emergingthreats.net\r\n\r\n";
1853  uint8_t httpbuf2[] =
1854  "POST / HTTP/1.1\r\n"
1855  "Host: www.openinfosecfoundation.org\r\n\r\n";
1856  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1857  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1858  TcpSession ssn;
1859  Flow f;
1860  ThreadVars th_v;
1861  DetectEngineThreadCtx *det_ctx;
1862 
1864 
1865  ut_script = script;
1866 
1867  memset(&th_v, 0, sizeof(th_v));
1868  StatsThreadInit(&th_v.stats);
1869  memset(&f, 0, sizeof(f));
1870  memset(&ssn, 0, sizeof(ssn));
1871 
1872  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1873  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1874 
1875  FLOW_INITIALIZE(&f);
1876  f.protoctx = (void *)&ssn;
1877  f.proto = IPPROTO_TCP;
1878  f.flags |= FLOW_IPV4;
1879  f.alproto = ALPROTO_HTTP1;
1880 
1881  p1->flow = &f;
1885 
1886  p2->flow = &f;
1890 
1891  StreamTcpInitConfig(true);
1892 
1895  de_ctx->flags |= DE_QUIET;
1896 
1898  FAIL_IF_NULL(s);
1899 
1901  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1902 
1903  int r = AppLayerParserParse(
1904  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1905  FAIL_IF(r != 0);
1906  HtpState *http_state = f.alstate;
1907  FAIL_IF_NULL(http_state);
1908 
1909  /* do detect for p1 */
1910  SCLogInfo("p1");
1911  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1912  FAIL_IF(PacketAlertCheck(p1, 1));
1913 
1914  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1915  FAIL_IF(r != 0);
1916  /* do detect for p2 */
1917  SCLogInfo("p2");
1918  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1919 
1920  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1921 
1922  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1923  FAIL_IF(id == 0);
1924  FlowVar *fv = FlowVarGet(&f, id);
1925  FAIL_IF_NULL(fv);
1926  FAIL_IF(fv->data.fv_int.value != 2);
1927 
1928  UTHFreePackets(&p1, 1);
1929  UTHFreePackets(&p2, 1);
1930  FLOW_DESTROY(&f);
1931 
1933  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1935  StreamTcpFreeConfig(true);
1936  StatsThreadCleanup(&th_v.stats);
1937  PASS;
1938 }
1939 
1940 /** \test http buffer, flowints */
1941 static int LuaMatchTest06(void)
1942 {
1943  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1944  "function init (args)\n"
1945  " flowintlib.register(\"cnt\")\n"
1946  " return {}\n"
1947  "end\n"
1948  "\n"
1949  "function thread_init (args)\n"
1950  " cnt = flowintlib.get(\"cnt\")\n"
1951  "end\n"
1952  "\n"
1953  "function match(args)\n"
1954  " print \"inspecting\""
1955  " a = cnt:value()\n"
1956  " if a == nil then\n"
1957  " print \"new var set to 2\""
1958  " cnt:set(2)\n"
1959  " end\n"
1960  " a = cnt:decr()\n"
1961  " if a == 0 then\n"
1962  " print \"match\"\n"
1963  " return 1\n"
1964  " end\n"
1965  " return 0\n"
1966  "end\n"
1967  "return 0\n";
1968  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1969  "sid:1;)";
1970  uint8_t httpbuf1[] =
1971  "POST / HTTP/1.1\r\n"
1972  "Host: www.emergingthreats.net\r\n\r\n";
1973  uint8_t httpbuf2[] =
1974  "POST / HTTP/1.1\r\n"
1975  "Host: www.openinfosecfoundation.org\r\n\r\n";
1976  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1977  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1978  TcpSession ssn;
1979  Flow f;
1980  ThreadVars th_v;
1981  DetectEngineThreadCtx *det_ctx;
1982 
1984 
1985  ut_script = script;
1986 
1987  memset(&th_v, 0, sizeof(th_v));
1988  StatsThreadInit(&th_v.stats);
1989  memset(&f, 0, sizeof(f));
1990  memset(&ssn, 0, sizeof(ssn));
1991 
1992  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1993  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1994 
1995  FLOW_INITIALIZE(&f);
1996  f.protoctx = (void *)&ssn;
1997  f.proto = IPPROTO_TCP;
1998  f.flags |= FLOW_IPV4;
1999  f.alproto = ALPROTO_HTTP1;
2000 
2001  p1->flow = &f;
2005 
2006  p2->flow = &f;
2010 
2011  StreamTcpInitConfig(true);
2012 
2015  de_ctx->flags |= DE_QUIET;
2016 
2018  FAIL_IF_NULL(s);
2019 
2021  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2022 
2023  int r = AppLayerParserParse(
2024  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2025  FAIL_IF(r != 0);
2026  HtpState *http_state = f.alstate;
2027  FAIL_IF_NULL(http_state);
2028 
2029  /* do detect for p1 */
2030  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2031  FAIL_IF(PacketAlertCheck(p1, 1));
2032 
2033  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2034  FAIL_IF(r != 0);
2035 
2036  /* do detect for p2 */
2037  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2038  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2039 
2040  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2041  FAIL_IF(id == 0);
2042  FlowVar *fv = FlowVarGet(&f, id);
2043  FAIL_IF_NULL(fv);
2044  FAIL_IF(fv->data.fv_int.value != 0);
2045 
2046  UTHFreePackets(&p1, 1);
2047  UTHFreePackets(&p2, 1);
2048  FLOW_DESTROY(&f);
2049 
2051  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2053  StreamTcpFreeConfig(true);
2054  StatsThreadCleanup(&th_v.stats);
2055  PASS;
2056 }
2057 
2058 /** \test http buffer, flowints */
2059 static int LuaMatchTest06a(void)
2060 {
2061  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2062  "function init (args)\n"
2063  " flowintlib.register(\"cnt\")\n"
2064  " return {}\n"
2065  "end\n"
2066  "\n"
2067  "function thread_init (args)\n"
2068  " cnt = flowintlib.get(\"cnt\")\n"
2069  "end\n"
2070  "\n"
2071  "function match(args)\n"
2072  " print \"inspecting\""
2073  " a = cnt:value()\n"
2074  " if a == nil then\n"
2075  " print \"new var set to 2\""
2076  " cnt:set(2)\n"
2077  " end\n"
2078  " a = cnt:decr()\n"
2079  " if a == 0 then\n"
2080  " print \"match\"\n"
2081  " return 1\n"
2082  " end\n"
2083  " return 0\n"
2084  "end\n"
2085  "return 0\n";
2086  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2087  "sid:1;)";
2088  uint8_t httpbuf1[] =
2089  "POST / HTTP/1.1\r\n"
2090  "Host: www.emergingthreats.net\r\n\r\n";
2091  uint8_t httpbuf2[] =
2092  "POST / HTTP/1.1\r\n"
2093  "Host: www.openinfosecfoundation.org\r\n\r\n";
2094  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2095  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2096  TcpSession ssn;
2097  Flow f;
2098  ThreadVars th_v;
2099  DetectEngineThreadCtx *det_ctx;
2100 
2102 
2103  ut_script = script;
2104 
2105  memset(&th_v, 0, sizeof(th_v));
2106  StatsThreadInit(&th_v.stats);
2107  memset(&f, 0, sizeof(f));
2108  memset(&ssn, 0, sizeof(ssn));
2109 
2110  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2111  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2112 
2113  FLOW_INITIALIZE(&f);
2114  f.protoctx = (void *)&ssn;
2115  f.proto = IPPROTO_TCP;
2116  f.flags |= FLOW_IPV4;
2117  f.alproto = ALPROTO_HTTP1;
2118 
2119  p1->flow = &f;
2123 
2124  p2->flow = &f;
2128 
2129  StreamTcpInitConfig(true);
2130 
2133  de_ctx->flags |= DE_QUIET;
2134 
2136  FAIL_IF_NULL(s);
2137 
2139  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2140 
2141  int r = AppLayerParserParse(
2142  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2143  FAIL_IF(r != 0);
2144  HtpState *http_state = f.alstate;
2145  FAIL_IF_NULL(http_state);
2146 
2147  /* do detect for p1 */
2148  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2149  FAIL_IF(PacketAlertCheck(p1, 1));
2150 
2151  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2152  FAIL_IF(r != 0);
2153 
2154  /* do detect for p2 */
2155  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2156  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2157 
2158  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2159  FAIL_IF(id == 0);
2160  FlowVar *fv = FlowVarGet(&f, id);
2161  FAIL_IF_NULL(fv);
2162  FAIL_IF(fv->data.fv_int.value != 0);
2163 
2164  UTHFreePackets(&p1, 1);
2165  UTHFreePackets(&p2, 1);
2166  FLOW_DESTROY(&f);
2167 
2169  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2171  StreamTcpFreeConfig(true);
2172  StatsThreadCleanup(&th_v.stats);
2173  PASS;
2174 }
2175 
2176 void DetectLuaRegisterTests(void)
2177 {
2178  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2179  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2180  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2181  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2182  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2183  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2184  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2185  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2186  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2187  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2188  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2189  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2190 }
2191 #endif
FLAG_MEMORY_LIMIT_LOGGED
#define FLAG_MEMORY_LIMIT_LOGGED
Definition: detect-lua.c:121
util-byte.h
DetectLuaData::bytevars
uint16_t bytevars
Definition: detect-lua.h:54
DetectLuaData
Definition: detect-lua.h:44
SigTableElmt_::url
const char * url
Definition: detect.h:1461
SCLuaSbState::memory_limit_error
bool memory_limit_error
Definition: util-lua-sandbox.h:56
detect-engine.h
LuaStateSetThreadVars
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv)
Definition: util-lua.c:110
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:1460
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1268
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
util-lua-common.h
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1445
SignatureHook_::sm_list
int sm_list
Definition: detect.h:573
FLAG_BLOCKED_FUNCTION_LOGGED
#define FLAG_BLOCKED_FUNCTION_LOGGED
Definition: detect-lua.c:119
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1458
FlowVar_::data
union FlowVar_::@117 data
stream-tcp.h
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3729
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
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
DetectLuaDataBytevarEntry_::name
char * name
Definition: detect-lua.h:40
DetectLuaData::flags
uint32_t flags
Definition: detect-lua.h:48
SCLuaSbGetContext
SCLuaSbState * SCLuaSbGetContext(lua_State *L)
Definition: util-lua-sandbox.c:352
Flow_::proto
uint8_t proto
Definition: flow.h:370
util-lua.h
ALPROTO_QUIC
@ ALPROTO_QUIC
Definition: app-layer-protos.h:57
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:142
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:41
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:368
Packet_::flags
uint32_t flags
Definition: decode.h:544
SCLuaSbState
Definition: util-lua-sandbox.h:40
Flow_
Flow data structure.
Definition: flow.h:348
DetectLuaData::allow_restricted_functions
int allow_restricted_functions
Definition: detect-lua.h:58
FLAG_INSTRUCTION_LIMIT_LOGGED
#define FLAG_INSTRUCTION_LIMIT_LOGGED
Definition: detect-lua.c:120
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:124
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:64
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2634
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1423
DETECT_LUA_MAX_FLOWVARS
#define DETECT_LUA_MAX_FLOWVARS
Definition: detect-lua.h:35
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:324
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
util-var-name.h
TLS_STATE_SERVER_HELLO_DONE
@ TLS_STATE_SERVER_HELLO_DONE
Definition: app-layer-ssl.h:89
SCConfGetBool
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:497
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:365
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2418
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:53
util-lua-builtins.h
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:155
DetectEngineThreadCtx_::lua_instruction_limit_errors
StatsCounterId lua_instruction_limit_errors
Definition: detect.h:1381
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3447
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:532
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:272
Flow_::protoctx
void * protoctx
Definition: flow.h:433
SigMatchData_
Data needed for Match()
Definition: detect.h:365
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1440
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:112
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:100
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:606
util-unittest.h
HtpState_
Definition: app-layer-htp.h:181
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
DetectLuaThreadData::flags
uint32_t flags
Definition: detect-lua.h:32
DetectLuaThreadData::luastate
lua_State * luastate
Definition: detect-lua.h:31
lua_State
struct lua_State lua_State
Definition: suricata-common.h:523
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:65
DetectLuaData::buffername
char * buffername
Definition: detect-lua.h:49
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:496
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
DetectLuaData::negated
int negated
Definition: detect-lua.h:46
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:271
app-layer-htp.h
FLAG_LIST_JA3S
#define FLAG_LIST_JA3S
Definition: detect-lua.c:116
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
find name for id+type at packet time. As the active store won't be modified, we don't need locks.
Definition: util-var-name.c:326
decode.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1245
DetectEngineThreadCtx_::lua_memory_limit_errors
StatsCounterId lua_memory_limit_errors
Definition: detect.h:1384
DetectLuaData::thread_ctx_id
int thread_ctx_id
Definition: detect-lua.h:45
DetectLuaData::instruction_limit
uint64_t instruction_limit
Definition: detect-lua.h:57
TLS_STATE_CLIENT_HELLO_DONE
@ TLS_STATE_CLIENT_HELLO_DONE
Definition: app-layer-ssl.h:79
SCConfGetInt
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:414
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:23
DETECT_LUA
@ DETECT_LUA
Definition: detect-engine-register.h:92
SignatureInitData_::list
int list
Definition: detect.h:628
SCEnter
#define SCEnter(...)
Definition: util-debug.h:281
detect-engine-mpm.h
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:388
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DetectLuaRegister
void DetectLuaRegister(void)
Registration function for keyword: lua.
Definition: detect-lua.c:83
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3364
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:204
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:165
DETECT_LUA_MAX_FLOWINTS
#define DETECT_LUA_MAX_FLOWINTS
Definition: detect-lua.h:36
FLAG_DATATYPE_PAYLOAD
#define FLAG_DATATYPE_PAYLOAD
Definition: detect-lua.c:113
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:259
app-layer-parser.h
DetectLuaMatchBuffer
int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset, Flow *f)
Definition: detect-lua.c:240
SignatureInitData_::hook
SignatureHook hook
Definition: detect.h:590
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:547
DetectEngineThreadCtx_::lua_rule_errors
StatsCounterId lua_rule_errors
Definition: detect.h:1375
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
DetectLuaData::bytevar
DetectLuaDataBytevarEntry bytevar[DETECT_LUA_MAX_BYTEVARS]
Definition: detect-lua.h:55
DetectLuaData::alloc_limit
uint64_t alloc_limit
Definition: detect-lua.h:56
DetectLuaData::flowints
uint16_t flowints
Definition: detect-lua.h:51
Packet_
Definition: decode.h:501
detect-engine-build.h
type
uint16_t type
Definition: decode-vlan.c:106
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:208
FLAG_DATATYPE_STREAM
#define FLAG_DATATYPE_STREAM
Definition: detect-lua.c:114
SCLuaSbStateClose
void SCLuaSbStateClose(lua_State *L)
Definition: util-lua-sandbox.c:361
DetectLuaData::flowint
uint32_t flowint[DETECT_LUA_MAX_FLOWINTS]
Definition: detect-lua.h:50
detect-engine-alert.h
conf.h
FLAG_ERROR_LOGGED
#define FLAG_ERROR_LOGGED
Definition: detect-lua.c:118
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:747
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1420
detect-byte.h
SCLuaRequirefBuiltIns
void SCLuaRequirefBuiltIns(lua_State *L)
Register Suricata built-in modules for loading in a non-sandboxed environment.
Definition: util-lua-builtins.c:85
SCLuaSbState::blocked_function_error
bool blocked_function_error
Definition: util-lua-sandbox.h:54
DetectLuaThreadData
Definition: detect-lua.h:30
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:226
LuaExtensionsMatchSetup
void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p, const Signature *s, uint8_t flags)
Definition: detect-lua-extensions.c:47
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:229
LuaDumpStack
void LuaDumpStack(lua_State *state, const char *prefix)
dump stack from lua state to screen
Definition: detect-lua.c:127
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:46
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2194
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:318
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1258
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:297
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
util-lua-sandbox.h
SCLuaSbLoadLibs
void SCLuaSbLoadLibs(lua_State *L)
Definition: util-lua-sandbox.c:280
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:40
Packet_::flow
struct Flow_ * flow
Definition: decode.h:546
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1214
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:867
flags
uint8_t flags
Definition: decode-gre.h:0
DetectRegisterThreadCtxFuncs
int DetectRegisterThreadCtxFuncs(DetectEngineCtx *de_ctx, const char *name, void *(*InitFunc)(void *), void *data, void(*FreeFunc)(void *), int mode)
Register Thread keyword context Funcs.
Definition: detect-engine.c:3659
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1277
detect-lua-extensions.h
suricata-common.h
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DEFAULT_LUA_ALLOC_LIMIT
#define DEFAULT_LUA_ALLOC_LIMIT
Definition: detect-lua.c:123
SignatureHook_::type
enum SignatureHookType type
Definition: detect.h:572
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3601
detect-engine-buffer.h
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *L)
Definition: util-lua-sandbox.c:388
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
DetectEngineInspectGenericList
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:1946
DetectLuaData::flowvars
uint16_t flowvars
Definition: detect-lua.h:52
luaext_key_ld
const char luaext_key_ld[]
Definition: detect-lua-extensions.c:45
str
#define str(s)
Definition: suricata-common.h:308
DetectEngineThreadCtx_::tv
ThreadVars * tv
Definition: detect.h:1253
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:271
FLAG_DATATYPE_BUFFER
#define FLAG_DATATYPE_BUFFER
Definition: detect-lua.c:117
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alstate
void * alstate
Definition: flow.h:471
Flow_::flags
uint32_t flags
Definition: flow.h:413
detect-parse.h
Signature_
Signature container.
Definition: detect.h:668
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:39
VAR_TYPE_FLOW_INT
@ VAR_TYPE_FLOW_INT
Definition: util-var.h:37
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:227
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2595
SCLuaSbState::instruction_count_error
bool instruction_count_error
Definition: util-lua-sandbox.h:55
DetectLoadCompleteSigPath
char * DetectLoadCompleteSigPath(const DetectEngineCtx *de_ctx, const char *sig_file)
Create the path if default-rule-path was specified.
Definition: detect-engine-loader.c:106
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:273
SCLuaSbStateNew
lua_State * SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit)
Allocate a new Lua sandbox.
Definition: util-lua-sandbox.c:320
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:935
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:84
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:60
DetectUnregisterThreadCtxFuncs
int DetectUnregisterThreadCtxFuncs(DetectEngineCtx *de_ctx, void *data, const char *name)
Remove Thread keyword context registration.
Definition: detect-engine.c:3711
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:442
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:285
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-buffer.c:109
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1354
flow-var.h
DetectLuaData::filename
char * filename
Definition: detect-lua.h:47
FlowVar_
Definition: flow-var.h:55
app-layer-ssl.h
DetectEngineThreadCtx_::lua_blocked_function_errors
StatsCounterId lua_blocked_function_errors
Definition: detect.h:1378
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1264
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1447
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319
app-layer.h
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:456
FLAG_LIST_JA3
#define FLAG_LIST_JA3
Definition: detect-lua.c:115