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;
186 for (cnt = 0; cnt < p->
alerts.
cnt; cnt++) {
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));
238 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
250 lua_getglobal(td->lua_ctx->luastate,
"log");
252 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
253 LuaStateSetPacket(td->lua_ctx->luastate, (
Packet *)p);
254 LuaStateSetFlow(td->lua_ctx->luastate, p->
flow);
257 lua_newtable(td->lua_ctx->luastate);
259 int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
261 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
281 void *tx,
const uint64_t tx_id, uint8_t dir)
284 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
295 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
296 LuaStateSetPacket(td->lua_ctx->luastate, (
Packet *)p);
297 LuaStateSetTX(td->lua_ctx->luastate, tx, tx_id);
298 LuaStateSetFlow(td->lua_ctx->luastate, p->
flow);
299 LuaStateSetFile(td->lua_ctx->luastate, (
File *)ff);
302 lua_getglobal(td->lua_ctx->luastate,
"log");
304 int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0);
306 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
322 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
328 LuaStateSetThreadVars(td->lua_ctx->luastate,
tv);
329 LuaStateSetFlow(td->lua_ctx->luastate, f);
332 lua_getglobal(td->lua_ctx->luastate,
"log");
334 int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0);
336 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
347 LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
351 lua_State *luastate = td->lua_ctx->luastate;
353 lua_getglobal(td->lua_ctx->luastate,
"log");
361 lua_newtable(luastate);
363 for (; u < st->
nstats; u++) {
364 lua_pushinteger(luastate, u + 1);
366 lua_newtable(luastate);
368 lua_pushstring(luastate,
"name");
369 lua_pushstring(luastate, st->
stats[u].
name);
370 lua_settable(luastate, -3);
372 lua_pushstring(luastate,
"tmname");
374 lua_settable(luastate, -3);
376 lua_pushstring(luastate,
"value");
377 lua_pushinteger(luastate, st->
stats[u].
value);
378 lua_settable(luastate, -3);
380 lua_pushstring(luastate,
"pvalue");
382 lua_settable(luastate, -3);
384 lua_settable(luastate, -3);
387 int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
389 SCLogInfo(
"failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
396 typedef struct LogLuaScriptOptions_ {
406 } LogLuaScriptOptions;
418 static int LuaScriptInit(
const char *filename, LogLuaScriptOptions *options) {
420 if (luastate == NULL)
422 luaL_openlibs(luastate);
424 int status = luaL_loadfile(luastate, filename);
426 SCLogError(
"couldn't load file: %s", lua_tostring(luastate, -1));
431 if (lua_pcall(luastate, 0, 0, 0) != 0) {
432 SCLogError(
"couldn't prime file: %s", lua_tostring(luastate, -1));
436 lua_getglobal(luastate,
"init");
437 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
442 lua_newtable(luastate);
443 if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) {
448 lua_pushliteral(luastate,
"script_api_ver");
449 lua_pushnumber (luastate, 1);
450 lua_settable(luastate, -3);
452 if (lua_pcall(luastate, 1, 1, 0) != 0) {
453 SCLogError(
"couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
458 if (lua_gettop(luastate) == 0) {
459 SCLogError(
"init function in script should return table, nothing returned");
462 if (lua_type(luastate, 1) != LUA_TTABLE) {
463 SCLogError(
"init function in script should return table, returned is not table");
467 lua_pushnil(luastate);
469 while (lua_next(luastate, -2)) {
470 k = lua_tostring(luastate, -2);
474 v = lua_tostring(luastate, -1);
475 lua_pop(luastate, 1);
481 if (strcmp(k,
"protocol") == 0 && strcmp(v,
"http") == 0)
483 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"dns") == 0)
485 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"tls") == 0)
487 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"ssh") == 0)
489 else if (strcmp(k,
"protocol") == 0 && strcmp(v,
"smtp") == 0)
491 else if (strcmp(k,
"type") == 0 && strcmp(v,
"packet") == 0)
493 else if (strcmp(k,
"filter") == 0 && strcmp(v,
"alerts") == 0)
495 else if (strcmp(k,
"type") == 0 && strcmp(v,
"file") == 0)
497 else if (strcmp(k,
"type") == 0 && strcmp(v,
"streaming") == 0)
498 options->streaming = 1;
499 else if (strcmp(k,
"type") == 0 && strcmp(v,
"flow") == 0)
501 else if (strcmp(k,
"filter") == 0 && strcmp(v,
"tcp") == 0)
502 options->tcp_data = 1;
503 else if (strcmp(k,
"type") == 0 && strcmp(v,
"stats") == 0)
506 SCLogInfo(
"unknown key and/or value: k='%s', v='%s'", k, v);
509 if (((options->alproto !=
ALPROTO_UNKNOWN)) + options->packet + options->file > 1) {
510 SCLogError(
"invalid combination of 'needs' in the script");
514 lua_getglobal(luastate,
"setup");
515 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
520 lua_getglobal(luastate,
"log");
521 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
526 lua_getglobal(luastate,
"deinit");
527 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
532 LuaReturnState(luastate);
536 LuaReturnState(luastate);
546 static lua_State *LuaScriptSetup(
const char *filename)
549 if (luastate == NULL) {
554 luaL_openlibs(luastate);
556 int status = luaL_loadfile(luastate, filename);
558 SCLogError(
"couldn't load file: %s", lua_tostring(luastate, -1));
563 if (lua_pcall(luastate, 0, 0, 0) != 0) {
564 SCLogError(
"couldn't prime file: %s", lua_tostring(luastate, -1));
568 lua_getglobal(luastate,
"setup");
571 LuaRegisterFunctions(luastate);
574 LuaRegisterHttpFunctions(luastate);
575 LuaRegisterDnsFunctions(luastate);
576 LuaRegisterJa3Functions(luastate);
577 LuaRegisterTlsFunctions(luastate);
578 LuaRegisterSshFunctions(luastate);
579 LuaRegisterHasshFunctions(luastate);
580 LuaRegisterSmtpFunctions(luastate);
582 if (lua_pcall(luastate, 0, 0, 0) != 0) {
583 SCLogError(
"couldn't run script 'setup' function: %s", lua_tostring(luastate, -1));
587 SCLogDebug(
"lua_State %p is set up", luastate);
591 LuaReturnState(luastate);
595 static void LogLuaSubFree(
OutputCtx *oc) {
611 LogLuaCtx *lua_ctx =
SCMalloc(
sizeof(LogLuaCtx));
614 memset(lua_ctx, 0x00,
sizeof(*lua_ctx));
624 const char *dir =
"";
625 if (parent_ctx && parent_ctx->
data) {
626 LogLuaMasterCtx *mc = parent_ctx->
data;
630 char path[PATH_MAX] =
"";
631 int ret = snprintf(path,
sizeof(path),
"%s%s%s", dir, strlen(dir) ?
"/" :
"", conf->
val);
632 if (ret < 0 || ret ==
sizeof(path)) {
633 SCLogError(
"failed to construct lua script path");
639 lua_ctx->luastate = LuaScriptSetup(path);
641 if (lua_ctx->luastate == NULL)
646 output_ctx->
data = lua_ctx;
647 output_ctx->
DeInit = LogLuaSubFree;
649 result.
ctx = output_ctx;
659 static void LogLuaMasterFree(
OutputCtx *oc)
686 if (scripts == NULL) {
697 output_ctx->
DeInit = LogLuaMasterFree;
698 output_ctx->
data =
SCCalloc(1,
sizeof(LogLuaMasterCtx));
703 LogLuaMasterCtx *master_config = output_ctx->
data;
704 strlcpy(master_config->path, dir,
sizeof(master_config->path));
711 LogLuaScriptOptions opts;
712 memset(&opts, 0x00,
sizeof(opts));
714 char path[PATH_MAX] =
"";
715 snprintf(path,
sizeof(path),
"%s%s%s", dir, strlen(dir) ?
"/" :
"", script->
val);
718 int r = LuaScriptInit(path, &opts);
774 }
else if (opts.packet && opts.alerts) {
777 }
else if (opts.packet && opts.alerts == 0) {
780 }
else if (opts.file) {
783 }
else if (opts.streaming && opts.tcp_data) {
786 }
else if (opts.flow) {
788 }
else if (opts.stats) {
799 result.
ctx = output_ctx;
805 output_ctx->
DeInit(output_ctx);
807 int failure_fatal = 0;
808 if (
ConfGetBool(
"engine.init-failure-fatal", &failure_fatal) != 1) {
809 SCLogDebug(
"ConfGetBool could not load the value.");
812 FatalError(
"Error during setup of lua output. Details should be "
813 "described in previous error messages. Shutting down...");
822 static void OutputLuaLogDoDeinit(LogLuaCtx *lua_ctx)
826 lua_getglobal(luastate,
"deinit");
827 if (lua_type(luastate, -1) != LUA_TFUNCTION) {
833 if (lua_pcall(luastate, 0, 0, 0) != 0) {
834 SCLogError(
"couldn't run script 'deinit' function: %s", lua_tostring(luastate, -1));
837 LuaReturnState(luastate);
845 static TmEcode LuaLogThreadInit(
ThreadVars *t,
const void *initdata,
void **data)
847 LogLuaThreadCtx *td =
SCMalloc(
sizeof(*td));
850 memset(td, 0,
sizeof(*td));
852 if (initdata == NULL) {
853 SCLogDebug(
"Error getting context for LuaLog. \"initdata\" argument NULL");
858 LogLuaCtx *lua_ctx = ((
OutputCtx *)initdata)->data;
860 td->lua_ctx = lua_ctx;
872 LogLuaThreadCtx *td = (LogLuaThreadCtx *)data;
878 if (td->lua_ctx->deinit_once == 0) {
879 OutputLuaLogDoDeinit(td->lua_ctx);
880 td->lua_ctx->deinit_once = 1;
885 memset(td, 0,
sizeof(*td));