From fe6cf00a8a017359b5e9c2c29264cacac46c9877 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 20 Feb 2014 15:57:00 +0100 Subject: [PATCH] output-lua: add stack utility functions Add utility functions for placing things on the stack for use by the scripts. Functions for numbers, strings and byte arrays. Add callback for returing IP header info: ip version, src ip, dst ip, proto, sp, dp (or type and code for icmp and icmpv6): SCPacketTuple --- src/output-lua-common.c | 96 +++++++++++++++++++++++++++++++++++++++++ src/output-lua-common.h | 7 +++ src/output-lua.c | 14 ------ 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/src/output-lua-common.c b/src/output-lua-common.c index c62f19c83a..3892d64a61 100644 --- a/src/output-lua-common.c +++ b/src/output-lua-common.c @@ -144,4 +144,100 @@ const char *LuaGetStringArgument(lua_State *luastate, int argc) return str; } +void LogLuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value) +{ + lua_pushstring(luastate, key); + lua_pushnumber(luastate, value); + lua_settable(luastate, -3); +} + +/** \brief Push a key plus string value to the stack + * + * If value is NULL, string "(null")" will be put on the stack. + */ +void LogLuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value) +{ + lua_pushstring(luastate, key); + lua_pushstring(luastate, value ? value : "(null)"); + lua_settable(luastate, -3); +} + +void LogLuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len) +{ + lua_pushstring(luastate, key); + LuaReturnStringBuffer(luastate, value, len); + lua_settable(luastate, -3); +} + +/** \internal + * \brief fill lua stack with header info + * \param luastate the lua state + * \param p packet + * \retval cnt number of data items placed on the stack + * + * Places: ipver (number), src ip (string), dst ip (string), protocol (number), + * sp or icmp type (number), dp or icmp code (number). + */ +static int LuaCallbackTuplePushToStackFromPacket(lua_State *luastate, const Packet *p) +{ + int ipver = 0; + if (PKT_IS_IPV4(p)) { + ipver = 4; + } else if (PKT_IS_IPV6(p)) { + ipver = 6; + } + lua_pushnumber (luastate, ipver); + if (ipver == 0) + return 1; + + char srcip[46] = "", dstip[46] = ""; + if (PKT_IS_IPV4(p)) { + PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); + PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); + } else if (PKT_IS_IPV6(p)) { + PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); + PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); + } + + lua_pushstring (luastate, srcip); + lua_pushstring (luastate, dstip); + + /* proto and ports (or type/code) */ + lua_pushnumber (luastate, p->proto); + if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) { + lua_pushnumber (luastate, p->sp); + lua_pushnumber (luastate, p->dp); + + } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) { + lua_pushnumber (luastate, p->type); + lua_pushnumber (luastate, p->code); + } else { + lua_pushnumber (luastate, 0); + lua_pushnumber (luastate, 0); + } + + return 6; +} + +/** \internal + * \brief Wrapper for getting tuple info into a lua script + * \retval cnt number of items placed on the stack + */ +static int LuaCallbackTuple(lua_State *luastate) +{ + const Packet *p = LuaStateGetPacket(luastate); + if (p == NULL) + return LuaCallbackError(luastate, "internal error: no packet"); + + return LuaCallbackTuplePushToStackFromPacket(luastate, p); +} + +int LogLuaRegisterFunctions(lua_State *luastate) +{ + /* registration of the callbacks */ + lua_pushcfunction(luastate, LuaCallbackTuple); + lua_setglobal(luastate, "SCPacketTuple"); + return 0; +} + #endif /* HAVE_LUA */ diff --git a/src/output-lua-common.h b/src/output-lua-common.h index d5f46f6469..0f8b26d9cb 100644 --- a/src/output-lua-common.h +++ b/src/output-lua-common.h @@ -30,10 +30,17 @@ void LuaPrintStack(lua_State *state); Packet *LuaStateGetPacket(lua_State *luastate); void *LuaStateGetTX(lua_State *luastate); + int LuaCallbackError(lua_State *luastate, const char *msg); int LuaReturnStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len); const char *LuaGetStringArgument(lua_State *luastate, int argc); +void LogLuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value); +void LogLuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value); +void LogLuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len); + +int LogLuaRegisterFunctions(lua_State *luastate); + #endif /* HAVE_LUA */ #endif /* __OUTPUT_LUA_COMMON_H__ */ diff --git a/src/output-lua.c b/src/output-lua.c index 762ef66683..09a9cc6ced 100644 --- a/src/output-lua.c +++ b/src/output-lua.c @@ -101,20 +101,6 @@ static int LuaTxLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow SCReturnInt(0); } -void LogLuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value) -{ - lua_pushstring(luastate, key); - lua_pushnumber(luastate, value); - lua_settable(luastate, -3); -} - -void LogLuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value) -{ - lua_pushstring(luastate, key); - lua_pushstring(luastate, value ? value : "(null)"); - lua_settable(luastate, -3); -} - static int LuaPacketLogger(ThreadVars *tv, void *thread_data, const Packet *p) { LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;