suricata
util-lua-flowvarlib.c
Go to the documentation of this file.
1 /* Copyright (C) 2025 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "suricata-common.h"
19 #include "app-layer-protos.h"
20 #include "flow-var.h"
21 #include "lauxlib.h"
22 #include "util-debug.h"
23 #include "util-lua-common.h"
24 #include "util-lua-flowvarlib.h"
25 #include "util-lua.h"
26 #include "util-var-name.h"
27 #include "detect-lua.h"
28 #include "detect-lua-extensions.h"
29 
30 static const char suricata_flowvar_mt[] = "suricata:flowvar:mt";
31 
32 static DetectLuaData *GetLuaData(lua_State *luastate)
33 {
34  DetectLuaData *ld;
35  lua_pushlightuserdata(luastate, (void *)&luaext_key_ld);
36  lua_gettable(luastate, LUA_REGISTRYINDEX);
37  ld = lua_touserdata(luastate, -1);
38  return ld;
39 }
40 
41 /**
42  * \brief Register a flowvar.
43  *
44  * Ensures that a flowvar exists for the provided name, will be
45  * created if needed.
46  *
47  * The flowvar ID is returned, however as this is most likely to be
48  * used in the scripts "init" method, this ID is unlikely to be used.
49  */
50 static int LuaFlowvarRegister(lua_State *L)
51 {
52  DetectLuaData *ld = GetLuaData(L);
53  const char *name = luaL_checkstring(L, 1);
54  uint32_t *flowvar_id = lua_newuserdata(L, sizeof(*flowvar_id));
56  if (*flowvar_id == 0) {
57  return luaL_error(L, "failed to register flowvar");
58  }
59  ld->flowvar[ld->flowvars++] = *flowvar_id;
60 
61  luaL_getmetatable(L, suricata_flowvar_mt);
62  lua_setmetatable(L, -2);
63 
64  return 1;
65 }
66 
67 static int LuaFlowvarGet(lua_State *L)
68 {
69  const char *name = luaL_checkstring(L, 1);
70  uint32_t *flowvar_id = lua_newuserdata(L, sizeof(*flowvar_id));
72  if (*flowvar_id == 0) {
73  return luaL_error(L, "flowvar does not exist");
74  }
75 
76  luaL_getmetatable(L, suricata_flowvar_mt);
77  lua_setmetatable(L, -2);
78 
79  return 1;
80 }
81 
82 static int LuaFlowvarValue(lua_State *L)
83 {
84  uint32_t *flowvar_id = luaL_checkudata(L, 1, suricata_flowvar_mt);
85  Flow *f = LuaStateGetFlow(L);
86  if (f == NULL) {
87  return LuaCallbackError(L, "flow is NULL");
88  }
89  FlowVar *fv = FlowVarGet(f, *flowvar_id);
90  if (fv == NULL) {
91  lua_pushnil(L);
92  } else {
94  L, (const uint8_t *)fv->data.fv_str.value, (size_t)fv->data.fv_str.value_len);
95  }
96  return 1;
97 }
98 
99 static int LuaFlowvarSet(lua_State *L)
100 {
101  const char *value = luaL_checkstring(L, 2);
102  const int len = (int)luaL_checkinteger(L, 3);
103  uint32_t *flowvar_id = luaL_checkudata(L, 1, suricata_flowvar_mt);
104  Flow *f = LuaStateGetFlow(L);
105  if (f == NULL) {
106  return luaL_error(L, "no flow");
107  }
108 
109  uint8_t *buf = SCMalloc(len + 1);
110  if (buf == NULL) {
111  return luaL_error(L, "alloc failure");
112  }
113  memcpy(buf, value, len);
114  buf[len] = '\0';
115  FlowVarAddIdValue(f, *flowvar_id, buf, (uint16_t)len);
116 
117  return 1;
118 }
119 
120 static const luaL_Reg flowvarlib[] = {
121  // clang-format off
122  { "register", LuaFlowvarRegister, },
123  { "get", LuaFlowvarGet },
124  { NULL, NULL, },
125  // clang-format on
126 };
127 
128 static const luaL_Reg flowvarmt[] = {
129  // clang-format off
130  { "value", LuaFlowvarValue, },
131  { "set", LuaFlowvarSet, },
132  { NULL, NULL, },
133  // clang-format on
134 };
135 
137 {
138  luaL_newmetatable(L, suricata_flowvar_mt);
139  lua_pushvalue(L, -1);
140  lua_setfield(L, -2, "__index");
141  luaL_setfuncs(L, flowvarmt, 0);
142 
143  luaL_newlib(L, flowvarlib);
144  return 1;
145 }
DetectLuaData
Definition: detect-lua.h:39
len
uint8_t len
Definition: app-layer-dnp3.h:2
util-lua-common.h
util-lua.h
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:59
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:40
Flow_
Flow data structure.
Definition: flow.h:356
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:58
detect-lua.h
util-var-name.h
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:48
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:155
lua_State
struct lua_State lua_State
Definition: suricata-common.h:523
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
util-debug.h
FlowVarAddIdValue
void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
Definition: flow-var.c:114
name
const char * name
Definition: tm-threads.c:2123
LuaFlow::f
Flow * f
Definition: util-lua-flowlib.c:41
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:39
detect-lua-extensions.h
suricata-common.h
LuaLoadFlowvarLib
int LuaLoadFlowvarLib(lua_State *L)
Definition: util-lua-flowvarlib.c:136
DetectLuaData::flowvars
uint16_t flowvars
Definition: detect-lua.h:47
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
luaext_key_ld
const char luaext_key_ld[]
Definition: detect-lua-extensions.c:47
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:38
LuaStateGetFlow
Flow * LuaStateGetFlow(lua_State *luastate)
get flow pointer from lua state
Definition: util-lua.c:161
app-layer-protos.h
util-lua-flowvarlib.h
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:78
flow-var.h
FlowVar_
Definition: flow-var.h:49
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