]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
lua-output: add SCStreamingBuffer
authorVictor Julien <victor@inliniac.net>
Wed, 25 Jun 2014 13:25:53 +0000 (15:25 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 15 Aug 2014 11:58:27 +0000 (13:58 +0200)
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

src/output-lua-common.c
src/output-lua.c
src/util-lua.c
src/util-lua.h

index 2f264386abdb8fee3a884742870eaafff720dcd6..255c2f9371b4a910e0dbe3b2ca5a61c9e38a682d 100644 (file)
@@ -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");
 
index 40cb5190a8747d6a494e464407e39857bf5cd360..d8787c272ee1f267e9ad42ec6338aa28c90c53a6 100644 (file)
@@ -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) {
index 24acfa6d697b58a97e2c22b92e5dd6f990b3b574..446598a5705db102e3e4df79e3af7a93b49ca5ed 100644 (file)
@@ -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);
index a43dea736dd3a9ef188cb5b0d45860cd866bc2b9..eb7a637e35e7e3d4e248f215607612d3c29b27f4 100644 (file)
 
 #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 */