lua_settable(luastate, -3);
}
+/** \internal
+ * \brief fill lua stack with payload
+ * \param luastate the lua state
+ * \param p packet
+ * \retval cnt number of data items placed on the stack
+ *
+ * Places: payload (string)
+ */
+static int LuaCallbackStreamingBufferPushToStack(lua_State *luastate, const LuaStreamingBuffer *b)
+{
+ //PrintRawDataFp(stdout, (uint8_t *)b->data, b->data_len);
+ lua_pushlstring (luastate, (const char *)b->data, b->data_len);
+ return 1;
+}
+
+/** \internal
+ * \brief Wrapper for getting payload into a lua script
+ * \retval cnt number of items placed on the stack
+ */
+static int LuaCallbackStreamingBuffer(lua_State *luastate)
+{
+ const LuaStreamingBuffer *b = LuaStateGetStreamingBuffer(luastate);
+ if (b == NULL)
+ return LuaCallbackError(luastate, "internal error: no buffer");
+
+ return LuaCallbackStreamingBufferPushToStack(luastate, b);
+}
+
/** \internal
* \brief fill lua stack with payload
* \param luastate the lua state
lua_pushcfunction(luastate, LuaCallbackAppLayerProtoFlow);
lua_setglobal(luastate, "SCFlowAppLayerProto");
+ lua_pushcfunction(luastate, LuaCallbackStreamingBuffer);
+ lua_setglobal(luastate, "SCStreamingBuffer");
+
lua_pushcfunction(luastate, LuaCallbackLogPath);
lua_setglobal(luastate, "SCLogPath");
SCEnter();
void *txptr = NULL;
+ LuaStreamingBuffer b = { data, data_len, flags };
SCLogDebug("flags %02x", flags);
if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) {
if (f && f->alstate)
- txptr = AppLayerParserGetTx(f->proto, ALPROTO_HTTP, f->alstate, tx_id);
+ txptr = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, tx_id);
}
LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
SCMutexLock(&td->lua_ctx->m);
LuaStateSetThreadVars(td->lua_ctx->luastate, tv);
- LuaStateSetTX(td->lua_ctx->luastate, txptr);
+ if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION)
+ LuaStateSetTX(td->lua_ctx->luastate, txptr);
LuaStateSetFlow(td->lua_ctx->luastate, (Flow *)f, /* locked */LUA_FLOW_LOCKED_BY_PARENT);
+ LuaStateSetStreamingBuffer(td->lua_ctx->luastate, &b);
/* prepare data to pass to script */
lua_getglobal(td->lua_ctx->luastate, "log");
lua_newtable(td->lua_ctx->luastate);
- LogLuaPushTableKeyValueInt(td->lua_ctx->luastate, "tx_id", (int)(tx_id));
+
+ if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION)
+ LogLuaPushTableKeyValueInt(td->lua_ctx->luastate, "tx_id", (int)(tx_id));
int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
if (retval != 0) {
om->conf_name = script->val;
om->InitSubFunc = OutputLuaLogInitSub;
- if (opts.alproto == ALPROTO_HTTP) {
+ if (opts.alproto == ALPROTO_HTTP && opts.streaming) {
+ om->StreamingLogFunc = LuaStreamingLogger;
+ om->alproto = ALPROTO_HTTP;
+ } else if (opts.alproto == ALPROTO_HTTP) {
om->TxLogFunc = LuaTxLogger;
om->alproto = ALPROTO_HTTP;
} else if (opts.packet && opts.alerts) {
#include <lualib.h>
#include <lauxlib.h>
+#include "util-lua.h"
+
/* key for tv (threadvars) pointer */
const char lua_ext_key_tv[] = "suricata:lua:tv:ptr";
/* key for tx pointer */
const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr";
/* key for file pointer */
const char lua_ext_key_file[] = "suricata:lua:file:ptr";
+/* key for streaming buffer pointer */
+const char lua_ext_key_streaming_buffer[] = "suricata:lua:streaming_buffer:ptr";
/** \brief get tv pointer from the lua state */
ThreadVars *LuaStateGetThreadVars(lua_State *luastate)
lua_settable(luastate, LUA_REGISTRYINDEX);
}
+LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate)
+{
+ lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer);
+ lua_gettable(luastate, LUA_REGISTRYINDEX);
+ void *b = lua_touserdata(luastate, -1);
+ return (LuaStreamingBuffer *)b;
+}
+
+void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b)
+{
+ lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer);
+ lua_pushlightuserdata(luastate, (void *)b);
+ lua_settable(luastate, LUA_REGISTRYINDEX);
+}
+
/** \brief dump stack from lua state to screen */
void LuaPrintStack(lua_State *state) {
int size = lua_gettop(state);
#ifdef HAVE_LUA
+typedef struct LuaStreamingBuffer_ {
+ const uint8_t *data;
+ uint32_t data_len;
+ uint8_t flags;
+} LuaStreamingBuffer;
+
#define LUA_FLOW_LOCKED_BY_PARENT 0
#define LUA_FLOW_NOT_LOCKED_BY_PARENT 1
/** \brief get file pointer from the lua state */
File *LuaStateGetFile(lua_State *luastate);
+LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate);
+
/* sets */
void LuaStateSetPacket(lua_State *luastate, Packet *p);
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv);
+void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b);
+
void LuaPrintStack(lua_State *state);
#endif /* HAVE_LUA */