53 #define MODULE_NAME "LuaLog"
60 typedef struct LogLuaMasterCtx_ {
64 typedef struct LogLuaCtx_ {
70 typedef struct LogLuaThreadCtx_ {
74 static TmEcode LuaLogThreadInit(
ThreadVars *t,
const void *initdata,
void **data);
85 static int LuaTxLogger(
ThreadVars *
tv,
void *thread_data,
const Packet *p,
Flow *f,
void *alstate,
void *txptr, uint64_t tx_id)
89 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
93 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
94 LuaStateSetPacket(td->lua_ctx->luastate, (
Packet *)p);
95 LuaStateSetTX(td->lua_ctx->luastate, txptr, tx_id);
96 LuaStateSetFlow(td->lua_ctx->luastate, f);
99 lua_getglobal(td->lua_ctx->luastate,
"log");
100 lua_newtable(td->lua_ctx->luastate);
101 LuaPushTableKeyValueInt(td->lua_ctx->luastate,
"tx_id", (
int)(tx_id));
103 int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
105 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
118 static int LuaStreamingLogger(
ThreadVars *
tv,
void *thread_data,
const Flow *f,
119 const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t
flags)
124 LuaStreamingBuffer b = { data, data_len,
flags };
133 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
137 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
139 LuaStateSetTX(td->lua_ctx->luastate, txptr, tx_id);
140 LuaStateSetFlow(td->lua_ctx->luastate, (
Flow *)f);
141 LuaStateSetStreamingBuffer(td->lua_ctx->luastate, &b);
144 lua_getglobal(td->lua_ctx->luastate,
"log");
145 lua_newtable(td->lua_ctx->luastate);
148 LuaPushTableKeyValueInt(td->lua_ctx->luastate,
"tx_id", (
int)(tx_id));
150 int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
152 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
173 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
178 if (!(PacketIsIPv4(p)) && !(PacketIsIPv6(p))) {
192 lua_getglobal(td->lua_ctx->luastate,
"log");
199 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
200 LuaStateSetPacket(td->lua_ctx->luastate, (
Packet *)p);
201 LuaStateSetTX(td->lua_ctx->luastate, txptr, pa->
tx_id);
202 LuaStateSetFlow(td->lua_ctx->luastate, p->
flow);
203 LuaStateSetPacketAlert(td->lua_ctx->luastate, (
PacketAlert *)pa);
208 int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0);
210 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
236 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
240 if ((!(PacketIsIPv4(p))) && (!(PacketIsIPv6(p)))) {
248 lua_getglobal(td->lua_ctx->luastate,
"log");
250 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
251 LuaStateSetPacket(td->lua_ctx->luastate, (
Packet *)p);
252 LuaStateSetFlow(td->lua_ctx->luastate, p->
flow);
255 lua_newtable(td->lua_ctx->luastate);
257 int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
259 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
279 void *tx,
const uint64_t tx_id, uint8_t dir)
282 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
284 if ((!(PacketIsIPv4(p))) && (!(PacketIsIPv6(p))))
293 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
294 LuaStateSetPacket(td->lua_ctx->luastate, (
Packet *)p);
295 LuaStateSetTX(td->lua_ctx->luastate, tx, tx_id);
296 LuaStateSetFlow(td->lua_ctx->luastate, p->
flow);
297 LuaStateSetFile(td->lua_ctx->luastate, (
File *)ff);
300 lua_getglobal(td->lua_ctx->luastate,
"log");
302 int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0);
304 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
320 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
326 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
327 LuaStateSetFlow(td->lua_ctx->luastate, f);
330 lua_getglobal(td->lua_ctx->luastate,
"log");
332 int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0);
334 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
345 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
349 lua_State *luastate = td->lua_ctx->luastate;
351 lua_getglobal(td->lua_ctx->luastate,
"log");
359 lua_newtable(luastate);
361 for (; u < st->
nstats; u++) {
362 lua_pushinteger(luastate, u + 1);
364 lua_newtable(luastate);
366 lua_pushstring(luastate,
"name");
367 lua_pushstring(luastate, st->
stats[u].
name);
368 lua_settable(luastate, -3);
370 lua_pushstring(luastate,
"tmname");
372 lua_settable(luastate, -3);
374 lua_pushstring(luastate,
"value");
375 lua_pushinteger(luastate, st->
stats[u].
value);
376 lua_settable(luastate, -3);
378 lua_pushstring(luastate,
"pvalue");
380 lua_settable(luastate, -3);
382 lua_settable(luastate, -3);
385 int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
387 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
394 typedef struct LogLuaScriptOptions_ {
404 } LogLuaScriptOptions;
416 static int LuaScriptInit(
const char *filename, LogLuaScriptOptions *options) {
418 if (luastate == NULL)
420 luaL_openlibs(luastate);
422 int status = luaL_loadfile(luastate, filename);
424 SCLogError(
"couldn't load file: %s", lua_tostring(luastate, -1));
429 if (lua_pcall(luastate, 0, 0, 0) != 0) {
430 SCLogError(
"couldn't prime file: %s", lua_tostring(luastate, -1));
434 lua_getglobal(luastate,
"init");
435 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
440 lua_newtable(luastate);
441 if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) {
446 lua_pushliteral(luastate,
"script_api_ver");
447 lua_pushnumber (luastate, 1);
448 lua_settable(luastate, -3);
450 if (lua_pcall(luastate, 1, 1, 0) != 0) {
451 SCLogError(
"couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
456 if (lua_gettop(luastate) == 0) {
457 SCLogError(
"init function in script should return table, nothing returned");
460 if (lua_type(luastate, 1) != LUA_TTABLE) {
461 SCLogError(
"init function in script should return table, returned is not table");
465 lua_pushnil(luastate);
467 while (lua_next(luastate, -2)) {
468 k = lua_tostring(luastate, -2);
472 v = lua_tostring(luastate, -1);
473 lua_pop(luastate, 1);
479 if (strcmp(k,
"protocol") == 0 && strcmp(v,
"http") == 0)
481 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"dns") == 0)
483 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"tls") == 0)
485 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"ssh") == 0)
487 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"smtp") == 0)
489 else if (strcmp(k,
"type") == 0 && strcmp(v,
"packet") == 0)
491 else if (strcmp(k,
"filter") == 0 && strcmp(v,
"alerts") == 0)
493 else if (strcmp(k,
"type") == 0 && strcmp(v,
"file") == 0)
495 else if (strcmp(k,
"type") == 0 && strcmp(v,
"streaming") == 0)
496 options->streaming = 1;
497 else if (strcmp(k,
"type") == 0 && strcmp(v,
"flow") == 0)
499 else if (strcmp(k,
"filter") == 0 && strcmp(v,
"tcp") == 0)
500 options->tcp_data = 1;
501 else if (strcmp(k,
"type") == 0 && strcmp(v,
"stats") == 0)
504 SCLogInfo(
"unknown key and/or value: k='%s', v='%s'", k, v);
507 if (((options->alproto !=
ALPROTO_UNKNOWN)) + options->packet + options->file > 1) {
508 SCLogError(
"invalid combination of 'needs' in the script");
512 lua_getglobal(luastate,
"setup");
513 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
518 lua_getglobal(luastate,
"log");
519 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
524 lua_getglobal(luastate,
"deinit");
525 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
530 LuaReturnState(luastate);
534 LuaReturnState(luastate);
544 static lua_State *LuaScriptSetup(
const char *filename)
547 if (luastate == NULL) {
552 luaL_openlibs(luastate);
554 int status = luaL_loadfile(luastate, filename);
556 SCLogError(
"couldn't load file: %s", lua_tostring(luastate, -1));
561 if (lua_pcall(luastate, 0, 0, 0) != 0) {
562 SCLogError(
"couldn't prime file: %s", lua_tostring(luastate, -1));
566 lua_getglobal(luastate,
"setup");
569 LuaRegisterFunctions(luastate);
572 LuaRegisterHttpFunctions(luastate);
573 LuaRegisterDnsFunctions(luastate);
574 LuaRegisterJa3Functions(luastate);
575 LuaRegisterTlsFunctions(luastate);
576 LuaRegisterSshFunctions(luastate);
577 LuaRegisterHasshFunctions(luastate);
578 LuaRegisterSmtpFunctions(luastate);
580 if (lua_pcall(luastate, 0, 0, 0) != 0) {
581 SCLogError(
"couldn't run script 'setup' function: %s", lua_tostring(luastate, -1));
585 SCLogDebug(
"lua_State %p is set up", luastate);
589 LuaReturnState(luastate);
593 static void LogLuaSubFree(
OutputCtx *oc) {
609 LogLuaCtx *lua_ctx =
SCCalloc(1,
sizeof(LogLuaCtx));
621 const char *dir =
"";
622 if (parent_ctx && parent_ctx->
data) {
623 LogLuaMasterCtx *mc = parent_ctx->
data;
627 char path[PATH_MAX] =
"";
628 int ret = snprintf(path,
sizeof(path),
"%s%s%s", dir, strlen(dir) ?
"/" :
"", conf->
val);
629 if (ret < 0 || ret ==
sizeof(path)) {
630 SCLogError(
"failed to construct lua script path");
636 lua_ctx->luastate = LuaScriptSetup(path);
638 if (lua_ctx->luastate == NULL)
643 output_ctx->
data = lua_ctx;
644 output_ctx->
DeInit = LogLuaSubFree;
646 result.
ctx = output_ctx;
656 static void LogLuaMasterFree(
OutputCtx *oc)
683 if (scripts == NULL) {
694 output_ctx->
DeInit = LogLuaMasterFree;
695 output_ctx->
data =
SCCalloc(1,
sizeof(LogLuaMasterCtx));
700 LogLuaMasterCtx *master_config = output_ctx->
data;
701 strlcpy(master_config->path, dir,
sizeof(master_config->path));
708 LogLuaScriptOptions opts;
709 memset(&opts, 0x00,
sizeof(opts));
711 char path[PATH_MAX] =
"";
712 snprintf(path,
sizeof(path),
"%s%s%s", dir, strlen(dir) ?
"/" :
"", script->
val);
715 int r = LuaScriptInit(path, &opts);
771 }
else if (opts.packet && opts.alerts) {
774 }
else if (opts.packet && opts.alerts == 0) {
777 }
else if (opts.file) {
780 }
else if (opts.streaming && opts.tcp_data) {
783 }
else if (opts.flow) {
785 }
else if (opts.stats) {
796 result.
ctx = output_ctx;
802 output_ctx->
DeInit(output_ctx);
804 int failure_fatal = 0;
805 if (
ConfGetBool(
"engine.init-failure-fatal", &failure_fatal) != 1) {
806 SCLogDebug(
"ConfGetBool could not load the value.");
809 FatalError(
"Error during setup of lua output. Details should be "
810 "described in previous error messages. Shutting down...");
819 static void OutputLuaLogDoDeinit(LogLuaCtx *lua_ctx)
823 lua_getglobal(luastate,
"deinit");
824 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
830 if (lua_pcall(luastate, 0, 0, 0) != 0) {
831 SCLogError(
"couldn't run script 'deinit' function: %s", lua_tostring(luastate, -1));
834 LuaReturnState(luastate);
842 static TmEcode LuaLogThreadInit(
ThreadVars *t,
const void *initdata,
void **data)
844 LogLuaThreadCtx *td =
SCCalloc(1,
sizeof(*td));
848 if (initdata == NULL) {
849 SCLogDebug(
"Error getting context for LuaLog. \"initdata\" argument NULL");
854 LogLuaCtx *lua_ctx = ((
OutputCtx *)initdata)->data;
856 td->lua_ctx = lua_ctx;
868 LogLuaThreadCtx *td = (LogLuaThreadCtx *)data;
874 if (td->lua_ctx->deinit_once == 0) {
875 OutputLuaLogDoDeinit(td->lua_ctx);
876 td->lua_ctx->deinit_once = 1;
881 memset(td, 0,
sizeof(*td));