-/* 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
* 02110-1301, USA.
*/
-
/**
* \file
*
*/
#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;
}