lua-output: add SCStreamingBuffer

Add SCStreamingBuffer lua function to retrieve the data passed
to the script per streaming API invocation.

Example:

    function log(args)
        data = SCStreamingBuffer()
        hex_dump(data)
    end
pull/1112/head
Victor Julien 11 years ago
parent ca3be77008
commit f7d890fe00

@ -118,6 +118,34 @@ void LogLuaPushTableKeyValueArray(lua_State *luastate, const char *key, const ui
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
@ -660,6 +688,9 @@ int LogLuaRegisterFunctions(lua_State *luastate)
lua_pushcfunction(luastate, LuaCallbackAppLayerProtoFlow);
lua_setglobal(luastate, "SCFlowAppLayerProto");
lua_pushcfunction(luastate, LuaCallbackStreamingBuffer);
lua_setglobal(luastate, "SCStreamingBuffer");
lua_pushcfunction(luastate, LuaCallbackLogPath);
lua_setglobal(luastate, "SCLogPath");

@ -116,12 +116,13 @@ static int LuaStreamingLogger(ThreadVars *tv, void *thread_data, const Flow *f,
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;
@ -129,13 +130,17 @@ static int LuaStreamingLogger(ThreadVars *tv, void *thread_data, const Flow *f,
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) {
@ -611,7 +616,10 @@ static OutputCtx *OutputLuaLogInit(ConfNode *conf)
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) {

@ -54,6 +54,8 @@
#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 */
@ -69,6 +71,8 @@ const char lua_ext_key_flow_lock_hint[] = "suricata:lua:flow:lock_hint";
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)
@ -181,6 +185,21 @@ void LuaStateSetFile(lua_State *luastate, File *file)
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);

@ -26,6 +26,12 @@
#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
@ -52,6 +58,8 @@ PacketAlert *LuaStateGetPacketAlert(lua_State *luastate);
/** \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);
@ -72,6 +80,8 @@ void LuaStateSetFile(lua_State *luastate, File *file);
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv);
void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b);
void LuaPrintStack(lua_State *state);
#endif /* HAVE_LUA */

Loading…
Cancel
Save