From: Jason Ish Date: Tue, 11 Mar 2025 22:52:09 +0000 (-0600) Subject: lua: convert dns function into suricata.dns lib X-Git-Tag: suricata-8.0.0-beta1~251 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1206c1c5af95479e8fd32f199bc7bfd3bafc56de;p=thirdparty%2Fsuricata.git lua: convert dns function into suricata.dns lib Notable changes from the previous API: - rcode will return the rcode as an integer - rcode_string will return the string representation Also fixes an issue where an rcode of 0 was returned as nil. Ticket: #7602 --- diff --git a/rust/src/dns/lua.rs b/rust/src/dns/lua.rs index 64c4f32e8b..240d55428e 100644 --- a/rust/src/dns/lua.rs +++ b/rust/src/dns/lua.rs @@ -22,10 +22,11 @@ use crate::dns::log::*; use crate::lua::*; #[no_mangle] -pub extern "C" fn SCDnsLuaGetTxId(clua: &mut CLuaState, tx: &mut DNSTransaction) { +pub extern "C" fn SCDnsLuaGetTxId(clua: &mut CLuaState, tx: &mut DNSTransaction) -> c_int { let lua = LuaState { lua: clua }; lua.pushinteger(tx.tx_id() as i64); + return 1; } #[no_mangle] @@ -50,14 +51,15 @@ pub extern "C" fn SCDnsLuaGetRrname(clua: &mut CLuaState, tx: &mut DNSTransactio #[no_mangle] pub extern "C" fn SCDnsLuaGetRcode(clua: &mut CLuaState, tx: &mut DNSTransaction) -> c_int { let lua = LuaState { lua: clua }; + lua.pushinteger(tx.rcode() as i64); + return 1; +} - let rcode = tx.rcode(); - if rcode > 0 { - lua.pushstring(&dns_rcode_string(rcode)); - return 1; - } - - return 0; +#[no_mangle] +pub extern "C" fn SCDnsLuaGetRcodeString(clua: &mut CLuaState, tx: &mut DNSTransaction) -> c_int { + let lua = LuaState { lua: clua }; + lua.pushstring(&dns_rcode_string(tx.rcode())); + return 1; } #[no_mangle] diff --git a/src/detect-lua-extensions.c b/src/detect-lua-extensions.c index d950f61bd9..045957e4c3 100644 --- a/src/detect-lua-extensions.c +++ b/src/detect-lua-extensions.c @@ -551,7 +551,6 @@ int LuaRegisterExtensions(lua_State *lua_state) LuaRegisterFunctions(lua_state); LuaRegisterHttpFunctions(lua_state); - LuaRegisterDnsFunctions(lua_state); LuaRegisterJa3Functions(lua_state); LuaRegisterTlsFunctions(lua_state); LuaRegisterSshFunctions(lua_state); diff --git a/src/output-lua.c b/src/output-lua.c index 7f1944b322..55c54e9ef3 100644 --- a/src/output-lua.c +++ b/src/output-lua.c @@ -594,7 +594,6 @@ static lua_State *LuaScriptSetup(const char *filename, LogLuaMasterCtx *ctx) /* unconditionally register http function. They will only work * if the tx is registered in the state at runtime though. */ LuaRegisterHttpFunctions(luastate); - LuaRegisterDnsFunctions(luastate); LuaRegisterJa3Functions(luastate); LuaRegisterTlsFunctions(luastate); LuaRegisterSshFunctions(luastate); diff --git a/src/util-lua-builtins.c b/src/util-lua-builtins.c index 9071834c03..7c5bb08e61 100644 --- a/src/util-lua-builtins.c +++ b/src/util-lua-builtins.c @@ -19,6 +19,7 @@ #include "util-lua-builtins.h" #include "util-lua-base64lib.h" #include "util-lua-dataset.h" +#include "util-lua-dns.h" #include "util-lua-hashlib.h" #include "util-lua-packetlib.h" @@ -27,6 +28,7 @@ static const luaL_Reg builtins[] = { { "suricata.base64", SCLuaLoadBase64Lib }, { "suricata.dataset", LuaLoadDatasetLib }, + { "suricata.dns", SCLuaLoadDnsLib }, { "suricata.hashlib", SCLuaLoadHashlib }, { "suricata.packet", LuaLoadPacketLib }, { NULL, NULL }, diff --git a/src/util-lua-dns.c b/src/util-lua-dns.c index 798855f3be..77a9e2558b 100644 --- a/src/util-lua-dns.c +++ b/src/util-lua-dns.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Open Information Security Foundation +/* Copyright (C) 2014-2025 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -15,7 +15,6 @@ * 02110-1301, USA. */ - /** * \file * @@ -24,135 +23,150 @@ */ #include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" +#include "util-lua-dns.h" +#include "util-lua.h" +#include "util-lua-common.h" #include "rust.h" -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" +// #define DNS_MT "suricata:dns:tx" +static const char dns_tx[] = "suricata:dns:tx"; -#include "util-lua.h" -#include "util-lua-common.h" -#include "util-lua-dns.h" +struct LuaTx { + RSDNSTransaction *tx; +}; -static int DnsGetDnsRrname(lua_State *luastate) +static int LuaDnsGetTx(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); + if (!(LuaStateNeedProto(L, ALPROTO_DNS))) { + return LuaCallbackError(L, "error: protocol not dns"); + } + RSDNSTransaction *tx = LuaStateGetTX(L); if (tx == NULL) { - return LuaCallbackError(luastate, "internal error: no tx"); - } - return SCDnsLuaGetRrname(luastate, tx); + return LuaCallbackError(L, "error: no tx available"); + } + struct LuaTx *ltx = (struct LuaTx *)lua_newuserdata(L, sizeof(*ltx)); + if (ltx == NULL) { + return LuaCallbackError(L, "error: fail to allocate user data"); + } + ltx->tx = tx; + + luaL_getmetatable(L, dns_tx); + lua_setmetatable(L, -2); + + return 1; } -static int DnsGetTxid(lua_State *luastate) +static int LuaDnsTxGetRrname(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); if (tx == NULL) { - return LuaCallbackError(luastate, "internal error: no tx"); - } - SCDnsLuaGetTxId(luastate, tx); - return 1; + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetRrname(L, tx->tx); +} + +static int LuaDnsTxGetTxid(lua_State *L) +{ + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); + if (tx == NULL) { + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetTxId(L, tx->tx); } -static int DnsGetRcode(lua_State *luastate) +static int LuaDnsTxGetRcode(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); if (tx == NULL) { - return LuaCallbackError(luastate, "internal error: no tx"); - } - return SCDnsLuaGetRcode(luastate, tx); + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetRcode(L, tx->tx); } -static int DnsGetRecursionDesired(lua_State *luastate) +static int LuaDnsTxGetRcodeString(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); if (tx == NULL) { - return LuaCallbackError(luastate, "internal error: no tx"); - } - uint16_t flags = SCDnsTxGetResponseFlags(tx); + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetRcodeString(L, tx->tx); +} + +static int LuaDnsTxGetRecursionDesired(lua_State *L) +{ + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); + if (tx == NULL) { + lua_pushnil(L); + return 1; + } + uint16_t flags = SCDnsTxGetResponseFlags(tx->tx); int recursion_desired = flags & 0x0080 ? 1 : 0; - lua_pushboolean(luastate, recursion_desired); + lua_pushboolean(L, recursion_desired); return 1; } -static int DnsGetQueryTable(lua_State *luastate) +static int LuaDnsTxGetQueries(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); if (tx == NULL) { - return LuaCallbackError(luastate, "internal error: no tx"); - } - return SCDnsLuaGetQueryTable(luastate, tx); + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetQueryTable(L, tx->tx); } -static int DnsGetAnswerTable(lua_State *luastate) +static int LuaDnsTxGetAnswers(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); - return SCDnsLuaGetAnswerTable(luastate, tx); + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); + if (tx == NULL) { + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetAnswerTable(L, tx->tx); } -static int DnsGetAuthorityTable(lua_State *luastate) +static int LuaDnsTxGetAuthorities(lua_State *L) { - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - RSDNSTransaction *tx = LuaStateGetTX(luastate); - return SCDnsLuaGetAuthorityTable(luastate, tx); + struct LuaTx *tx = luaL_testudata(L, 1, dns_tx); + if (tx == NULL) { + lua_pushnil(L); + return 1; + } + return SCDnsLuaGetAuthorityTable(L, tx->tx); } -/** \brief register http lua extensions in a luastate */ -int LuaRegisterDnsFunctions(lua_State *luastate) +static const struct luaL_Reg txlib[] = { + // clang-format off + { "answers", LuaDnsTxGetAnswers }, + { "authorities", LuaDnsTxGetAuthorities }, + { "queries", LuaDnsTxGetQueries }, + { "rcode", LuaDnsTxGetRcode }, + { "rcode_string", LuaDnsTxGetRcodeString }, + { "recursion_desired", LuaDnsTxGetRecursionDesired }, + { "rrname", LuaDnsTxGetRrname }, + { "txid", LuaDnsTxGetTxid }, + { NULL, NULL, } + // clang-format on +}; + +static const struct luaL_Reg dnslib[] = { + // clang-format off + { "get_tx", LuaDnsGetTx }, + { NULL, NULL,}, + // clang-format on +}; + +int SCLuaLoadDnsLib(lua_State *L) { - /* registration of the callbacks */ - lua_pushcfunction(luastate, DnsGetDnsRrname); - lua_setglobal(luastate, "DnsGetDnsRrname"); + luaL_newmetatable(L, dns_tx); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, txlib, 0); - lua_pushcfunction(luastate, DnsGetQueryTable); - lua_setglobal(luastate, "DnsGetQueries"); - - lua_pushcfunction(luastate, DnsGetAnswerTable); - lua_setglobal(luastate, "DnsGetAnswers"); - - lua_pushcfunction(luastate, DnsGetAuthorityTable); - lua_setglobal(luastate, "DnsGetAuthorities"); - - lua_pushcfunction(luastate, DnsGetTxid); - lua_setglobal(luastate, "DnsGetTxid"); - - lua_pushcfunction(luastate, DnsGetRcode); - lua_setglobal(luastate, "DnsGetRcode"); - - lua_pushcfunction(luastate, DnsGetRecursionDesired); - lua_setglobal(luastate, "DnsGetRecursionDesired"); - return 0; + luaL_newlib(L, dnslib); + return 1; } diff --git a/src/util-lua-dns.h b/src/util-lua-dns.h index 99566cabf1..650f45eb36 100644 --- a/src/util-lua-dns.h +++ b/src/util-lua-dns.h @@ -24,6 +24,8 @@ #ifndef SURICATA_UTIL_LUA_DNS_H #define SURICATA_UTIL_LUA_DNS_H -int LuaRegisterDnsFunctions(lua_State *luastate); +#include "lua.h" + +int SCLuaLoadDnsLib(lua_State *L); #endif /* __UTIL_LUA_HTTP_H__ */