]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
lua: convert dns function into suricata.dns lib
authorJason Ish <jason.ish@oisf.net>
Tue, 11 Mar 2025 22:52:09 +0000 (16:52 -0600)
committerVictor Julien <victor@inliniac.net>
Thu, 20 Mar 2025 12:12:03 +0000 (13:12 +0100)
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

rust/src/dns/lua.rs
src/detect-lua-extensions.c
src/output-lua.c
src/util-lua-builtins.c
src/util-lua-dns.c
src/util-lua-dns.h

index 64c4f32e8bb8813d44ffcb30e47e0680f1a1878f..240d55428ea7f4dcf93598f0f125e394ee9ae1c4 100644 (file)
@@ -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]
index d950f61bd9791647216c15cc587eb3acd72b2756..045957e4c39266b5ed5603bd6acc7e0f2cde12a8 100644 (file)
@@ -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);
index 7f1944b32223e7dfedb34d271653db2a5d2908d1..55c54e9ef300eaf3015b0e8ec884c2cd034de9ad 100644 (file)
@@ -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);
index 9071834c03d2f07534f59f3b6292c7848cf6887d..7c5bb08e61f52972cab1a08f61efd9b631077597 100644 (file)
@@ -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 },
index 798855f3be07f56def22a4394bda67d5ab849474..77a9e2558b57d57d46596b3632ec5e78a2c78c63 100644 (file)
@@ -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
  *
  */
 
 #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;
 }
index 99566cabf1a5a1a1cae49e7bf7129c2026f51003..650f45eb3687e645978d0a864485bad6457659d3 100644 (file)
@@ -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__ */