suricata
util-lua.c
Go to the documentation of this file.
1 /* Copyright (C) 2014 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
24  */
25 
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "detect.h"
29 #include "pkt-var.h"
30 #include "conf.h"
31 
32 #include "threads.h"
33 #include "threadvars.h"
34 #include "tm-threads.h"
35 
36 #include "util-print.h"
37 #include "util-unittest.h"
38 
39 #include "util-debug.h"
40 
41 #include "output.h"
42 #include "app-layer-htp.h"
43 #include "app-layer.h"
44 #include "app-layer-parser.h"
45 #include "util-privs.h"
46 #include "util-buffer.h"
47 #include "util-proto-name.h"
48 #include "util-logopenfile.h"
49 #include "util-time.h"
50 
51 #ifdef HAVE_LUA
52 
53 #include <lua.h>
54 #include <lualib.h>
55 #include <lauxlib.h>
56 
57 #include "util-lua.h"
58 
59 lua_State *LuaGetState(void)
60 {
61  lua_State *s = NULL;
62 #ifdef HAVE_LUAJIT
63  s = LuajitGetState();
64 #else
65  s = luaL_newstate();
66 #endif
67  return s;
68 }
69 
70 void LuaReturnState(lua_State *s)
71 {
72  if (s != NULL) {
73  /* clear the stack */
74  while (lua_gettop(s) > 0) {
75  lua_pop(s, 1);
76  }
77 #ifdef HAVE_LUAJIT
78  LuajitReturnState(s);
79 #else
80  lua_close(s);
81 #endif
82  }
83 }
84 
85 /* key for tv (threadvars) pointer */
86 const char lua_ext_key_tv[] = "suricata:lua:tv:ptr";
87 /* key for tx pointer */
88 const char lua_ext_key_tx[] = "suricata:lua:tx:ptr";
89 /* key for p (packet) pointer */
90 const char lua_ext_key_p[] = "suricata:lua:pkt:ptr";
91 /* key for f (flow) pointer */
92 const char lua_ext_key_flow[] = "suricata:lua:flow:ptr";
93 /* key for flow lock hint bool */
94 const char lua_ext_key_flow_lock_hint[] = "suricata:lua:flow:lock_hint";
95 /* key for direction */
96 const char lua_ext_key_direction[] = "suricata:lua:direction";
97 
98 /* key for pa (packet alert) pointer */
99 const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr";
100 /* key for file pointer */
101 const char lua_ext_key_file[] = "suricata:lua:file:ptr";
102 /* key for streaming buffer pointer */
103 const char lua_ext_key_streaming_buffer[] = "suricata:lua:streaming_buffer:ptr";
104 
105 /** \brief get tv pointer from the lua state */
106 ThreadVars *LuaStateGetThreadVars(lua_State *luastate)
107 {
108  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tv);
109  lua_gettable(luastate, LUA_REGISTRYINDEX);
110  void *tv = lua_touserdata(luastate, -1);
111  return (ThreadVars *)tv;
112 }
113 
114 void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv)
115 {
116  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tv);
117  lua_pushlightuserdata(luastate, (void *)tv);
118  lua_settable(luastate, LUA_REGISTRYINDEX);
119 }
120 
121 /** \brief get packet pointer from the lua state */
122 Packet *LuaStateGetPacket(lua_State *luastate)
123 {
124  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_p);
125  lua_gettable(luastate, LUA_REGISTRYINDEX);
126  void *p = lua_touserdata(luastate, -1);
127  return (Packet *)p;
128 }
129 
130 void LuaStateSetPacket(lua_State *luastate, Packet *p)
131 {
132  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_p);
133  lua_pushlightuserdata(luastate, (void *)p);
134  lua_settable(luastate, LUA_REGISTRYINDEX);
135 }
136 
137 /** \brief get tx pointer from the lua state */
138 void *LuaStateGetTX(lua_State *luastate)
139 {
140  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tx);
141  lua_gettable(luastate, LUA_REGISTRYINDEX);
142  void *tx = lua_touserdata(luastate, -1);
143  return tx;
144 }
145 
146 void LuaStateSetTX(lua_State *luastate, void *txptr)
147 {
148  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tx);
149  lua_pushlightuserdata(luastate, (void *)txptr);
150  lua_settable(luastate, LUA_REGISTRYINDEX);
151 }
152 
153 Flow *LuaStateGetFlow(lua_State *luastate)
154 {
155  Flow *f = NULL;
156 
157  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow);
158  lua_gettable(luastate, LUA_REGISTRYINDEX);
159  f = lua_touserdata(luastate, -1);
160 
161  /* need flow lock hint */
162  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow_lock_hint);
163  lua_gettable(luastate, LUA_REGISTRYINDEX);
164 
165  return f;
166 }
167 
168 void LuaStateSetFlow(lua_State *luastate, Flow *f)
169 {
170  /* flow */
171  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow);
172  lua_pushlightuserdata(luastate, (void *)f);
173  lua_settable(luastate, LUA_REGISTRYINDEX);
174 
175  /* flow lock status hint */
176  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow_lock_hint);
177  /* locking is not required, set to 0 for backwards compatibility */
178  lua_pushboolean(luastate, 0);
179  lua_settable(luastate, LUA_REGISTRYINDEX);
180 }
181 
182 /** \brief get packet alert pointer from the lua state */
183 PacketAlert *LuaStateGetPacketAlert(lua_State *luastate)
184 {
185  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_pa);
186  lua_gettable(luastate, LUA_REGISTRYINDEX);
187  void *pa = lua_touserdata(luastate, -1);
188  return (PacketAlert *)pa;
189 }
190 
191 void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa)
192 {
193  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_pa);
194  lua_pushlightuserdata(luastate, (void *)pa);
195  lua_settable(luastate, LUA_REGISTRYINDEX);
196 }
197 
198 /** \brief get file pointer from the lua state */
199 File *LuaStateGetFile(lua_State *luastate)
200 {
201  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_file);
202  lua_gettable(luastate, LUA_REGISTRYINDEX);
203  void *file = lua_touserdata(luastate, -1);
204  return (File *)file;
205 }
206 
207 void LuaStateSetFile(lua_State *luastate, File *file)
208 {
209  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_file);
210  lua_pushlightuserdata(luastate, (void *)file);
211  lua_settable(luastate, LUA_REGISTRYINDEX);
212 }
213 
214 LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate)
215 {
216  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer);
217  lua_gettable(luastate, LUA_REGISTRYINDEX);
218  void *b = lua_touserdata(luastate, -1);
219  return (LuaStreamingBuffer *)b;
220 }
221 
222 void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b)
223 {
224  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer);
225  lua_pushlightuserdata(luastate, (void *)b);
226  lua_settable(luastate, LUA_REGISTRYINDEX);
227 }
228 
229 /** \brief get packet pointer from the lua state */
230 int LuaStateGetDirection(lua_State *luastate)
231 {
232  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_direction);
233  lua_gettable(luastate, LUA_REGISTRYINDEX);
234  int dir = lua_toboolean(luastate, -1);
235  return dir;
236 }
237 
238 void LuaStateSetDirection(lua_State *luastate, int direction)
239 {
240  lua_pushlightuserdata(luastate, (void *)&lua_ext_key_direction);
241  lua_pushboolean(luastate, direction);
242  lua_settable(luastate, LUA_REGISTRYINDEX);
243 }
244 
245 /** \brief dump stack from lua state to screen */
246 void LuaPrintStack(lua_State *state) {
247  int size = lua_gettop(state);
248  int i;
249 
250  for (i = 1; i <= size; i++) {
251  int type = lua_type(state, i);
252  printf("Stack size=%d, level=%d, type=%d, ", size, i, type);
253 
254  switch (type) {
255  case LUA_TFUNCTION:
256  printf("function %s", lua_tostring(state, i) ? "true" : "false");
257  break;
258  case LUA_TBOOLEAN:
259  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
260  break;
261  case LUA_TNUMBER:
262  printf("number %g", lua_tonumber(state, i));
263  break;
264  case LUA_TSTRING:
265  printf("string `%s'", lua_tostring(state, i));
266  break;
267  case LUA_TTABLE:
268  printf("table `%s'", lua_tostring(state, i));
269  break;
270  default:
271  printf("other %s", lua_typename(state, type));
272  break;
273 
274  }
275  printf("\n");
276  }
277 }
278 
279 int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
280 {
281  if (input_len % 4 != 0) {
282  /* we're using a buffer sized at a multiple of 4 as lua_pushlstring generates
283  * invalid read errors in valgrind otherwise. Adding in a nul to be sure.
284  *
285  * Buffer size = len + 1 (for nul) + whatever makes it a multiple of 4 */
286  size_t buflen = input_len + 1 + ((input_len + 1) % 4);
287  uint8_t buf[buflen];
288  memset(buf, 0x00, buflen);
289  memcpy(buf, input, input_len);
290  buf[input_len] = '\0';
291 
292  /* return value through luastate, as a luastring */
293  lua_pushlstring(luastate, (char *)buf, input_len);
294  } else {
295  lua_pushlstring(luastate, (char *)input, input_len);
296  }
297  return 1;
298 }
299 
300 int LuaPushInteger(lua_State *luastate, lua_Integer n)
301 {
302  lua_pushinteger(luastate, n);
303  return 1;
304 }
305 
306 #endif /* HAVE_LUA */
uint8_t type
Per thread variable structure.
Definition: threadvars.h:57
Flow data structure.
Definition: flow.h:325