suricata
util-lua-bytevarlib.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 "detect-byte.h"
20 #include "util-lua-common.h"
21 #include "util-lua-bytevarlib.h"
22 #include "util-lua.h"
23 #include "detect-lua.h"
24 #include "detect-lua-extensions.h"
25 
26 #include "lauxlib.h"
27 
28 static const char suricata_bytevar_mt[] = "suricata:bytevar:mt";
29 
30 static DetectLuaData *GetLuaData(lua_State *luastate)
31 {
32  DetectLuaData *ld;
33  lua_pushlightuserdata(luastate, (void *)&luaext_key_ld);
34  lua_gettable(luastate, LUA_REGISTRYINDEX);
35  ld = lua_touserdata(luastate, -1);
36  return ld;
37 }
38 
39 static int LuaBytevarMap(lua_State *L)
40 {
41  const Signature *s = lua_touserdata(L, -2);
42  const char *name = luaL_checkstring(L, -1);
43  DetectLuaData *ld = GetLuaData(L);
44 
45  /* Is this name already mapped? */
46  for (uint16_t i = 0; i < ld->bytevars; i++) {
47  if (strcmp(ld->bytevar[i].name, name) == 0) {
48  lua_pushinteger(L, ld->bytevar[i].id);
49  return 1;
50  }
51  }
52 
53  if (ld->bytevars == DETECT_LUA_MAX_BYTEVARS) {
54  luaL_error(L, "too many bytevars mapped");
55  }
56 
58  if (!DetectByteRetrieveSMVar(name, s, -1, &idx)) {
59  luaL_error(L, "unknown byte_extract or byte_math variable: %s", name);
60  }
61 
62  ld->bytevar[ld->bytevars].name = SCStrdup(name);
63  if (ld->bytevar[ld->bytevars].name == NULL) {
64  luaL_error(L, "failed to allocate memory for bytevar name: %s", name);
65  }
66  ld->bytevar[ld->bytevars++].id = idx;
67 
68  return 1;
69 }
70 
71 static int LuaBytevarGet(lua_State *L)
72 {
73  const char *name = luaL_checkstring(L, 1);
74  DetectLuaData *ld = GetLuaData(L);
75  if (ld == NULL) {
76  return luaL_error(L, "internal error: no lua data");
77  }
78 
79  for (uint16_t i = 0; i < ld->bytevars; i++) {
80  if (strcmp(ld->bytevar[i].name, name) == 0) {
81  uint32_t *bytevar_id = lua_newuserdata(L, sizeof(*bytevar_id));
82  *bytevar_id = ld->bytevar[i].id;
83  luaL_getmetatable(L, suricata_bytevar_mt);
84  lua_setmetatable(L, -2);
85  return 1;
86  }
87  }
88 
89  return luaL_error(L, "unknown bytevar: %s", name);
90 }
91 
92 static int LuaBytevarValue(lua_State *L)
93 {
94  uint32_t *bytevar_id = luaL_checkudata(L, 1, suricata_bytevar_mt);
96  if (det_ctx == NULL) {
97  return LuaCallbackError(L, "internal error: no det_ctx");
98  }
99  lua_pushinteger(L, det_ctx->byte_values[*bytevar_id]);
100  return 1;
101 }
102 
103 static const luaL_Reg bytevarlib[] = {
104  // clang-format off
105  { "map", LuaBytevarMap, },
106  { "get", LuaBytevarGet, },
107  { NULL, NULL, },
108  // clang-format on
109 };
110 
111 static const luaL_Reg bytevarmt[] = {
112  // clang-format off
113  { "value", LuaBytevarValue, },
114  { NULL, NULL, },
115  // clang-format on
116 };
117 
119 {
120  luaL_newmetatable(L, suricata_bytevar_mt);
121  lua_pushvalue(L, -1);
122  lua_setfield(L, -2, "__index");
123  luaL_setfuncs(L, bytevarmt, 0);
124 
125  luaL_newlib(L, bytevarlib);
126  return 1;
127 }
DetectEngineThreadCtx_::byte_values
uint64_t * byte_values
Definition: detect.h:1279
DetectLuaData::bytevars
uint16_t bytevars
Definition: detect-lua.h:54
DetectLuaData
Definition: detect-lua.h:44
util-lua-common.h
DetectLuaDataBytevarEntry_::name
char * name
Definition: detect-lua.h:40
util-lua.h
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:39
util-lua-bytevarlib.h
detect-lua.h
LuaStateGetDetCtx
DetectEngineThreadCtx * LuaStateGetDetCtx(lua_State *luastate)
get DetectEngineThreadCtx pointer from the lua state
Definition: util-lua.c:239
DetectByteIndexType
uint8_t DetectByteIndexType
Definition: detect-byte.h:28
lua_State
struct lua_State lua_State
Definition: suricata-common.h:523
LuaLoadBytevarLib
int LuaLoadBytevarLib(lua_State *L)
Definition: util-lua-bytevarlib.c:118
DetectEngineThreadCtx_
Definition: detect.h:1244
DETECT_LUA_MAX_BYTEVARS
#define DETECT_LUA_MAX_BYTEVARS
Definition: detect-lua.h:37
DetectLuaData::bytevar
DetectLuaDataBytevarEntry bytevar[DETECT_LUA_MAX_BYTEVARS]
Definition: detect-lua.h:55
name
const char * name
Definition: tm-threads.c:2163
detect-byte.h
detect-lua-extensions.h
suricata-common.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
luaext_key_ld
const char luaext_key_ld[]
Definition: detect-lua-extensions.c:45
Signature_
Signature container.
Definition: detect.h:668
DetectByteRetrieveSMVar
bool DetectByteRetrieveSMVar(const char *arg, const Signature *s, int sm_list, DetectByteIndexType *index)
Used to retrieve args from BM.
Definition: detect-byte.c:41
DetectLuaDataBytevarEntry_::id
uint32_t id
Definition: detect-lua.h:41