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