suricata
util-lua-common.c
Go to the documentation of this file.
1 /* Copyright (C) 2014-2021 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  * Common function for Lua Output
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "threads.h"
29 #include "threadvars.h"
30 
31 #include "output.h"
32 #include "util-conf.h"
33 
34 #include "flow.h"
35 #include "app-layer-parser.h"
36 
37 #include "lua.h"
38 
39 #include "util-lua.h"
40 #include "util-lua-common.h"
41 
42 void *SCLuaNewUserData(lua_State *L, uint32_t type_id, size_t size)
43 {
44  uint8_t *block = (uint8_t *)lua_newuserdata(L, sizeof(SCLuaUserDataHeader) + size);
45  if (block == NULL) {
46  return NULL;
47  }
49  h->magic = SCLUA_UD_MAGIC;
50  h->type_id = type_id;
51  return block + sizeof(SCLuaUserDataHeader);
52 }
53 
54 /*
55  * The types whose payload is a tx handle (SCLuaTxRef first member):
56  * they wrap parser-owned memory that is freed at state teardown or on
57  * per-tx eviction while a script may still hold the userdata.
58  */
59 static int SCLuaUserDataIsTxType(uint32_t type_id)
60 {
61  switch (type_id) {
62  case SCLUA_TUD_HTTP_TX:
63  case SCLUA_TUD_DNS_TX:
64  case SCLUA_TUD_SMTP_TX:
65  case SCLUA_TUD_SSH_TX:
66  case SCLUA_TUD_NTP_TX:
67  case SCLUA_TUD_JA3_TX:
70  return 1;
71  default:
72  return 0;
73  }
74 }
75 
76 /*
77  * Uniform liveness check for the tx types. Raises when the handle is
78  * well-tagged but stale; a stale handle must fail closed, the accessors
79  * must never see a dangling tx pointer.
80  */
81 static void SCLuaTxRefStaleRaise(lua_State *L)
82 {
83  luaL_error(L, "tx no longer valid: the transaction or its flow state was freed");
84  /* luaL_error raises; the return keeps the fail-closed path
85  * explicit if it ever did not */
86 }
87 
88 static uint8_t *SCLuaUserDataPayload(lua_State *L, int idx, const char *mt, uint32_t type_id)
89 {
90  void *block = luaL_testudata(L, idx, mt);
91  if (block == NULL) {
92  return NULL;
93  }
95  if (h->magic != SCLUA_UD_MAGIC || h->type_id != type_id) {
96  return NULL;
97  }
98  return (uint8_t *)block + sizeof(SCLuaUserDataHeader);
99 }
100 
101 void *SCLuaCheckUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
102 {
103  uint8_t *block = (uint8_t *)luaL_checkudata(L, idx, mt);
104  if (block == NULL) {
105  return NULL;
106  }
108  if (h->magic != SCLUA_UD_MAGIC || h->type_id != type_id) {
109  luaL_error(L, "invalid handle: type mismatch");
110  /* luaL_error raises; the return keeps the fail-closed path
111  * explicit if it ever did not */
112  return NULL;
113  }
114  uint8_t *payload = block + sizeof(SCLuaUserDataHeader);
115  if (SCLuaUserDataIsTxType(type_id) &&
116  !SCLuaTxRefResolve(L, (const SCLuaTxRef *)payload, NULL)) {
117  SCLuaTxRefStaleRaise(L);
118  return NULL;
119  }
120  return payload;
121 }
122 
123 void *SCLuaTestUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
124 {
125  uint8_t *payload = SCLuaUserDataPayload(L, idx, mt, type_id);
126  if (payload == NULL) {
127  return NULL;
128  }
129  if (SCLuaUserDataIsTxType(type_id) &&
130  !SCLuaTxRefResolve(L, (const SCLuaTxRef *)payload, NULL)) {
131  SCLuaTxRefStaleRaise(L);
132  return NULL;
133  }
134  return payload;
135 }
136 
137 void *SCLuaCheckUserDataPayload(lua_State *L, int idx, const char *mt, uint32_t type_id)
138 {
139  uint8_t *block = (uint8_t *)luaL_checkudata(L, idx, mt);
140  if (block == NULL) {
141  return NULL;
142  }
144  if (h->magic != SCLUA_UD_MAGIC || h->type_id != type_id) {
145  luaL_error(L, "invalid handle: type mismatch");
146  return NULL;
147  }
148  return block + sizeof(SCLuaUserDataHeader);
149 }
150 
151 void *SCLuaCheckUserDataSoft(lua_State *L, int idx, const char *mt, uint32_t type_id)
152 {
153  void *payload = SCLuaCheckUserDataPayload(L, idx, mt, type_id);
154  if (payload == NULL) {
155  return NULL;
156  }
157  if (SCLuaUserDataIsTxType(type_id) &&
158  !SCLuaTxRefResolve(L, (const SCLuaTxRef *)payload, NULL)) {
159  return NULL;
160  }
161  return payload;
162 }
163 
164 void SCLuaTxRefInit(lua_State *L, SCLuaTxRef *ref, uint64_t tx_id)
165 {
166  Flow *f = LuaStateGetFlow(L);
167  ref->flow = f;
168  if (f != NULL) {
169  ref->flow_hash = f->flow_hash;
170  ref->start_sec = SCTIME_SECS(f->startts);
171  ref->start_usec = SCTIME_USECS(f->startts);
172  ref->alproto = f->alproto;
173  } else {
174  ref->flow_hash = 0;
175  ref->start_sec = 0;
176  ref->start_usec = 0;
177  ref->alproto = ALPROTO_UNKNOWN;
178  }
179  ref->tx_id = tx_id;
180 }
181 
182 int SCLuaTxRefResolve(lua_State *L, const SCLuaTxRef *ref, void **tx)
183 {
184  /* only the current flow is dereferenced; the recorded one is
185  * compared by pointer and may itself be long gone */
186  Flow *f = LuaStateGetFlow(L);
187  if (f == NULL || ref->flow == NULL || f != ref->flow) {
188  return 0;
189  }
190  /* flow address reused by another protocol: the pinned alproto
191  * mismatches and resolving would read a foreign tx the accessors
192  * would cast - fail closed */
193  if (f->alproto != ref->alproto) {
194  return 0;
195  }
196  /* same address and protocol: a same-protocol flow took the old
197  * one's place - the flow identity (hash + full start ts) pins
198  * the original flow */
199  if (f->flow_hash != ref->flow_hash || SCTIME_SECS(f->startts) != ref->start_sec ||
200  SCTIME_USECS(f->startts) != ref->start_usec) {
201  return 0;
202  }
203  if (f->alstate == NULL || f->alproto == ALPROTO_UNKNOWN) {
204  return 0;
205  }
206  /* the tx must still be on the live state's list: per-tx eviction
207  * frees a tx while the state stays alive */
208  void *t = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, ref->tx_id);
209  if (t == NULL) {
210  return 0;
211  }
212  if (tx != NULL) {
213  *tx = t;
214  }
215  return 1;
216 }
217 
218 int LuaCallbackError(lua_State *luastate, const char *msg)
219 {
220  lua_pushnil(luastate);
221  lua_pushstring(luastate, msg);
222  return 2;
223 }
224 
225 const char *LuaGetStringArgument(lua_State *luastate, int idx)
226 {
227  /* get argument */
228  if (!lua_isstring(luastate, idx))
229  return NULL;
230  const char *str = lua_tostring(luastate, idx);
231  if (str == NULL)
232  return NULL;
233  if (strlen(str) == 0)
234  return NULL;
235  return str;
236 }
237 
238 void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value)
239 {
240  lua_pushstring(luastate, key);
241  lua_pushnumber(luastate, value);
242  lua_settable(luastate, -3);
243 }
244 
245 void LuaPushTableKeyValueBoolean(lua_State *luastate, const char *key, bool value)
246 {
247  lua_pushstring(luastate, key);
248  lua_pushboolean(luastate, value);
249  lua_settable(luastate, -3);
250 }
251 
252 /** \brief Push a key plus string value to the stack
253  *
254  * If value is NULL, string "(null")" will be put on the stack.
255  */
256 void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value)
257 {
258  lua_pushstring(luastate, key);
259  lua_pushstring(luastate, value ? value : "(null)");
260  lua_settable(luastate, -3);
261 }
262 
263 /** \brief Push a key plus string value with length to the stack.
264  */
266  lua_State *luastate, const char *key, const char *value, size_t len)
267 {
268  lua_pushstring(luastate, key);
269  lua_pushlstring(luastate, value, len);
270  lua_settable(luastate, -3);
271 }
272 
274  lua_State *luastate, const char *key, const uint8_t *value, size_t len)
275 {
276  lua_pushstring(luastate, key);
277  LuaPushStringBuffer(luastate, value, len);
278  lua_settable(luastate, -3);
279 }
280 
281 /*
282  * Protocol check for the tx libs. Returns a plain boolean: 1 when the
283  * flow's app protocol matches, 0 otherwise (including the no-flow
284  * case). Errors are reported by the callers, so nothing is pushed on
285  * the stack. The previous implementation returned
286  * LuaCallbackError's 2 for the no-flow case, which the boolean callers
287  * treat as a protocol match.
288  */
289 int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
290 {
291  Flow *flow = LuaStateGetFlow(luastate);
292  if (flow == NULL)
293  return 0;
294 
295  return (alproto == flow->alproto);
296 }
297 
298 /***** Unittests *****/
299 
300 #ifdef UNITTESTS
301 
302 #include "string.h"
303 
304 #include "util-unittest.h"
305 
306 /* wrapper around the common validation entry point: pushes a boolean
307  * "validated" when the handle at index 1 passes, raises when it is a
308  * stale tx handle */
309 static int TestTxHandleWrapper(lua_State *L)
310 {
311  void *r = SCLuaTestUserData(L, 1, "suricata:dns:tx", SCLUA_TUD_DNS_TX);
312  lua_pushboolean(L, r != NULL);
313  return 1;
314 }
315 
316 /* build a dns tx userdata carrying the given liveness anchor */
317 static void *TestNewDnsTxData(lua_State *L, const SCLuaTxRef *ref)
318 {
319  void *ud = SCLuaNewUserData(L, SCLUA_TUD_DNS_TX, sizeof(*ref));
320  if (ud == NULL) {
321  return NULL;
322  }
323  memcpy(ud, ref, sizeof(*ref));
324  luaL_getmetatable(L, "suricata:dns:tx");
325  lua_setmetatable(L, -2);
326  return ud;
327 }
328 
329 /* a fake "current" flow the state runs on; only the fields
330  * SCLuaTxRefResolve reads are set. ALPROTO_TLS: its GetTx returns
331  * the state itself, so the resolution is exercised without a real
332  * parser state */
333 static Flow *TestMakeFlow(void)
334 {
335  Flow *f = calloc(1, sizeof(Flow));
336  if (f == NULL) {
337  return NULL;
338  }
339  f->alstate = (void *)0x1234;
340  f->alproto = ALPROTO_TLS;
341  f->proto = IPPROTO_TCP;
342  return f;
343 }
344 
345 static SCLuaTxRef TestMakeRef(const Flow *f)
346 {
347  SCLuaTxRef ref;
348  memset(&ref, 0, sizeof(ref));
349  ref.flow = (Flow *)f;
350  ref.flow_hash = f->flow_hash;
351  ref.start_sec = SCTIME_SECS(f->startts);
353  ref.alproto = f->alproto;
354  ref.tx_id = 0;
355  return ref;
356 }
357 
358 /**
359  * \test the uniform tx resolution: a (flow, identity, alproto, tx id)
360  * anchor naming the flow's live state resolves to the state's tx;
361  * each failure mode is stale - handle from another (freed) flow,
362  * state freed, no flow running, unknown proto, flow address reused
363  * by another protocol, same-protocol flow reusing the address. The
364  * evicted-tx case needs a real parser state (the tx-list lookup) and
365  * is covered end to end by the lua-sbx UAF reproducers
366  */
367 static int SCLuaTxRefResolveTest(void)
368 {
369  lua_State *L = LuaGetState();
370  FAIL_IF_NULL(L);
371 
372  Flow *f = TestMakeFlow();
373  FAIL_IF_NULL(f);
374  Flow *f2 = TestMakeFlow();
375  FAIL_IF_NULL(f2);
376  LuaStateSetFlow(L, f);
377 
378  SCLuaTxRef ref = TestMakeRef(f);
379  void *tx = NULL;
380  /* the anchor names the live state's tx */
381  FAIL_IF_NOT(SCLuaTxRefResolve(L, &ref, &tx));
382  FAIL_IF_NOT(tx == f->alstate);
383 
384  ref.flow = f2; /* the handle's flow is gone, another runs now */
385  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
386  ref = TestMakeRef(f);
387 
388  f->alstate = NULL; /* state freed, not yet re-allocated */
389  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
390  f->alstate = (void *)0x1234;
391 
392  LuaStateSetFlow(L, NULL); /* no flow running now */
393  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
394  LuaStateSetFlow(L, f);
395 
397  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
398  f->alproto = ALPROTO_TLS;
399 
400  /* the flow's address was reused by a flow of another protocol:
401  * the pinned alproto mismatches, fail closed */
403  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
404  f->alproto = ALPROTO_TLS;
405 
406  /* same address and protocol: a same-protocol flow took the old
407  * flow's place - the flow identity mismatches, fail closed */
408  f->flow_hash = 42;
409  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
410  f->flow_hash = 0;
411  f->startts.secs = 42;
412  FAIL_IF_NOT(!SCLuaTxRefResolve(L, &ref, NULL));
413  f->startts.secs = 0;
414 
415  LuaReturnState(L);
416  free(f);
417  free(f2);
418  PASS;
419 }
420 
421 /**
422  * \test the common validation entry point fails closed on a stale tx
423  * handle: it raises a lua error instead of handing out a dangling
424  * pointer
425  */
426 static int SCLuaTestUserDataStaleTest(void)
427 {
428  lua_State *L = LuaGetState();
429  FAIL_IF_NULL(L);
430 
431  luaL_newmetatable(L, "suricata:dns:tx");
432  lua_pop(L, 1);
433 
434  Flow *f = TestMakeFlow();
435  FAIL_IF_NULL(f);
436  LuaStateSetFlow(L, f);
437 
438  SCLuaTxRef ref = TestMakeRef(f);
439  f->alstate = NULL; /* stale: the state is gone */
440 
441  void *ud = TestNewDnsTxData(L, &ref);
442  FAIL_IF_NULL(ud);
443 
444  int udidx = lua_gettop(L);
445  lua_pushcfunction(L, TestTxHandleWrapper);
446  lua_pushvalue(L, udidx);
447  int rc = lua_pcall(L, 1, 0, 0);
448  FAIL_IF_NOT(rc == LUA_ERRRUN);
449  const char *err = lua_tostring(L, -1);
450  FAIL_IF_NULL(err);
451  FAIL_IF_NOT(strstr(err, "tx no longer valid") != NULL);
452  lua_pop(L, 1);
453 
454  LuaReturnState(L);
455  free(f);
456  PASS;
457 }
458 
459 /**
460  * \test a live tx handle passes the common validation entry point and
461  * a mistyped argument still fails quietly (the SCLuaTestUserData
462  * contract), with no raise
463  */
464 static int SCLuaTestUserDataLiveTest(void)
465 {
466  lua_State *L = LuaGetState();
467  FAIL_IF_NULL(L);
468 
469  luaL_newmetatable(L, "suricata:dns:tx");
470  lua_pop(L, 1);
471 
472  Flow *f = TestMakeFlow();
473  FAIL_IF_NULL(f);
474  LuaStateSetFlow(L, f);
475 
476  SCLuaTxRef ref = TestMakeRef(f);
477  void *ud = TestNewDnsTxData(L, &ref);
478  FAIL_IF_NULL(ud);
479 
480  /* live handle: validation passes, the wrapper reports it */
481  int udidx = lua_gettop(L);
482  lua_pushcfunction(L, TestTxHandleWrapper);
483  lua_pushvalue(L, udidx);
484  int rc = lua_pcall(L, 1, 1, 0);
485  FAIL_IF_NOT(rc == LUA_OK);
486  FAIL_IF_NOT(lua_toboolean(L, -1));
487  lua_pop(L, 1);
488 
489  /* mistyped argument: no metatable match, no raise */
490  lua_pushinteger(L, 42);
491  int numidx = lua_gettop(L);
492  lua_pushcfunction(L, TestTxHandleWrapper);
493  lua_pushvalue(L, numidx);
494  rc = lua_pcall(L, 1, 1, 0);
495  FAIL_IF_NOT(rc == LUA_OK);
496  FAIL_IF_NOT(!lua_toboolean(L, -1));
497  lua_pop(L, 1);
498 
499  LuaReturnState(L);
500  free(f);
501  PASS;
502 }
503 
505 {
506  UtRegisterTest("SCLuaTxRefResolveTest", SCLuaTxRefResolveTest);
507  UtRegisterTest("SCLuaTestUserDataStaleTest", SCLuaTestUserDataStaleTest);
508  UtRegisterTest("SCLuaTestUserDataLiveTest", SCLuaTestUserDataLiveTest);
509 }
510 
511 #endif /* UNITTESTS */
SCLuaUserDataHeader_
Definition: util-lua-common.h:43
SCLuaUserDataHeader_::magic
uint32_t magic
Definition: util-lua-common.h:44
len
uint8_t len
Definition: app-layer-dnp3.h:2
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SCLUA_TUD_NTP_TX
@ SCLUA_TUD_NTP_TX
Definition: util-lua-common.h:66
util-lua-common.h
LuaPushTableKeyValueInt
void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value)
Definition: util-lua-common.c:238
SCLUA_TUD_HTTP_TX
@ SCLUA_TUD_HTTP_TX
Definition: util-lua-common.h:62
Flow_::startts
SCTime_t startts
Definition: flow.h:500
SCLUA_TUD_DNS_TX
@ SCLUA_TUD_DNS_TX
Definition: util-lua-common.h:63
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
Flow_::proto
uint8_t proto
Definition: flow.h:382
util-lua.h
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:87
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:218
SCLuaTxRef_
Definition: util-lua-common.h:92
SCLuaTxRef_::start_usec
uint32_t start_usec
Definition: util-lua-common.h:96
LuaGetState
lua_State * LuaGetState(void)
Definition: util-lua.c:56
threads.h
Flow_
Flow data structure.
Definition: flow.h:360
LuaStateSetFlow
void LuaStateSetFlow(lua_State *luastate, Flow *f)
set a flow pointer in the lua state
Definition: util-lua.c:267
LuaGetStringArgument
const char * LuaGetStringArgument(lua_State *luastate, int idx)
Definition: util-lua-common.c:225
util-unittest.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
lua_State
struct lua_State lua_State
Definition: suricata-common.h:527
SCLUA_TUD_DNP3_POINTS
@ SCLUA_TUD_DNP3_POINTS
Definition: util-lua-common.h:68
SCLuaTxRef_::tx_id
uint64_t tx_id
Definition: util-lua-common.h:98
SCLuaTxRef_::start_sec
uint64_t start_sec
Definition: util-lua-common.h:95
SCLUA_TUD_SSH_TX
@ SCLUA_TUD_SSH_TX
Definition: util-lua-common.h:65
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
SCLuaTxRefResolve
int SCLuaTxRefResolve(lua_State *L, const SCLuaTxRef *ref, void **tx)
Definition: util-lua-common.c:182
SCTime_t::secs
uint64_t secs
Definition: util-time.h:41
SCLuaTxRef_::flow
struct Flow_ * flow
Definition: util-lua-common.h:93
SCLuaUserDataHeader
struct SCLuaUserDataHeader_ SCLuaUserDataHeader
SCLuaCheckUserData
void * SCLuaCheckUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:101
app-layer-parser.h
SCLuaTestUserData
void * SCLuaTestUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:123
Flow_::flow_hash
uint32_t flow_hash
Definition: flow.h:403
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1219
SCLuaNewUserData
void * SCLuaNewUserData(lua_State *L, uint32_t type_id, size_t size)
Definition: util-lua-common.c:42
LuaPushTableKeyValueArray
void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len)
Definition: util-lua-common.c:273
util-conf.h
suricata-common.h
SCLUA_UD_MAGIC
#define SCLUA_UD_MAGIC
Definition: util-lua-common.h:41
SCLuaUserDataHeader_::type_id
uint32_t type_id
Definition: util-lua-common.h:45
SCLuaCommonRegisterTests
void SCLuaCommonRegisterTests(void)
Definition: util-lua-common.c:504
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
SCLUA_TUD_TLS_STATE
@ SCLUA_TUD_TLS_STATE
Definition: util-lua-common.h:61
SCLUA_TUD_SMTP_TX
@ SCLUA_TUD_SMTP_TX
Definition: util-lua-common.h:64
threadvars.h
str
#define str(s)
Definition: suricata-common.h:313
Flow_::alstate
void * alstate
Definition: flow.h:486
LuaStateGetFlow
Flow * LuaStateGetFlow(lua_State *luastate)
get flow pointer from lua state
Definition: util-lua.c:260
ALPROTO_HTTP
@ ALPROTO_HTTP
Definition: app-layer-protos.h:77
SCLuaTxRef_::flow_hash
uint32_t flow_hash
Definition: util-lua-common.h:94
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
LuaPushTableKeyValueBoolean
void LuaPushTableKeyValueBoolean(lua_State *luastate, const char *key, bool value)
Definition: util-lua-common.c:245
LuaPushTableKeyValueLString
void LuaPushTableKeyValueLString(lua_State *luastate, const char *key, const char *value, size_t len)
Push a key plus string value with length to the stack.
Definition: util-lua-common.c:265
SCLuaTxRef_::alproto
AppProto alproto
Definition: util-lua-common.h:97
SCLuaTxRefInit
void SCLuaTxRefInit(lua_State *L, SCLuaTxRef *ref, uint64_t tx_id)
Definition: util-lua-common.c:164
SCLuaCheckUserDataSoft
void * SCLuaCheckUserDataSoft(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:151
LuaPushTableKeyValueString
void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value)
Push a key plus string value to the stack.
Definition: util-lua-common.c:256
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:457
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:289
SCLuaCheckUserDataPayload
void * SCLuaCheckUserDataPayload(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:137
output.h
SCLUA_TUD_JA3_TX
@ SCLUA_TUD_JA3_TX
Definition: util-lua-common.h:67
LuaReturnState
void LuaReturnState(lua_State *s)
Definition: util-lua.c:63
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:380
SCTIME_USECS
#define SCTIME_USECS(t)
Definition: util-time.h:56
f
Flow f
Definition: fuzz_dataset.c:32