]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
lua: document new suricata.dns lua library
authorJason Ish <jason.ish@oisf.net>
Wed, 12 Mar 2025 15:52:54 +0000 (09:52 -0600)
committerVictor Julien <victor@inliniac.net>
Thu, 20 Mar 2025 12:12:03 +0000 (13:12 +0100)
Ticket: #7602

doc/userguide/lua/libs/dns.rst [new file with mode: 0644]
doc/userguide/lua/libs/index.rst
doc/userguide/lua/lua-functions.rst
src/util-lua-dns.c

diff --git a/doc/userguide/lua/libs/dns.rst b/doc/userguide/lua/libs/dns.rst
new file mode 100644 (file)
index 0000000..7787fa2
--- /dev/null
@@ -0,0 +1,164 @@
+DNS
+---
+
+DNS transaction details are exposes to Lua scripts with the
+``suricata.dns`` library, For example::
+
+  local dns = require("suricata.dns")
+
+Setup
+^^^^^
+
+If your purpose is to create a logging script, initialize the buffer as:
+
+::
+
+  function init (args)
+     local needs = {}
+     needs["protocol"] = "dns"
+     return needs
+  end
+
+If you are going to use the script for rule matching, choose one of
+the available DNS buffers listed in :ref:`lua-detection` and follow
+the pattern:
+
+::
+
+  function init (args)
+     local needs = {}
+     needs["dns.rrname"] = tostring(true)
+     return needs
+  end
+
+Transaction
+~~~~~~~~~~~
+
+DNS is transaction based, and the current transaction must be obtained before use::
+
+  local tx, err = dns.get_tx()
+  if tx == err then
+      print(err)
+  end
+
+All other functions are methods on the transaction table.
+
+Transaction Methods
+~~~~~~~~~~~~~~~~~~~
+
+``answers()``
+^^^^^^^^^^^^^
+
+Get the ``answers`` response section as a table of tables.
+
+Example::
+
+  local tx = dns.get_tx()
+  local answers = tx:answers()
+  if answers ~= nil then
+      for n, t in pairs(answers) do
+          rrname = t["rrname"]
+          rrtype = t["type"]
+          ttl = t["ttl"]
+
+          print ("ANSWER: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
+                 ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
+                 dstip .. ":" .. dp)
+      end
+  end
+
+``authorities()``
+^^^^^^^^^^^^^^^^^
+
+Get the ``authorities`` response section as a table of tables.
+
+Example::
+
+  local tx = dns.get_tx()
+  local authorities = tx:authorities();
+  if authorities ~= nil then
+      for n, t in pairs(authorities) do
+          rrname = t["rrname"]
+          rrtype = t["type"]
+          ttl = t["ttl"]
+           print ("AUTHORITY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
+                 ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
+                 dstip .. ":" .. dp)
+      end
+  end
+
+``queries()``
+^^^^^^^^^^^^^
+
+Get the ``queries`` request or response section as a table of tables.
+
+Example::
+
+  local tx = dns.get_tx()
+  local queries = tx:queries();
+  if queries ~= nil then
+      for n, t in pairs(queries) do
+          rrname = t["rrname"]
+          rrtype = t["type"]
+
+          print ("QUERY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
+                 "TODO" .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
+                 dstip .. ":" .. dp)
+      end
+  end
+
+``rcode()``
+^^^^^^^^^^^
+
+Get the ``rcode`` value as an integer.
+
+Example::
+
+  local tx = dns.get_tx()
+  local rcode = tx:rcode()
+  print (rcode)
+
+``rcode_string()``
+^^^^^^^^^^^^^^^^^^
+
+Get the ``rcode`` value as a string.
+
+Example::
+
+  local tx = dns.get_tx()
+  local rcode_string = tx:rcode_string();
+  print (rcode_string)
+
+``recursion_desired()``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Return the value of the recursion desired (RD) flag as a boolean.
+
+Example::
+
+  local tx = dns.get_tx()
+  if tx:recursion_desired() == true then
+      print ("RECURSION DESIRED")
+  end
+
+``rrname()``
+^^^^^^^^^^^^
+
+Return the resource name from the first query object.
+
+Example::
+
+  local tx = dns.get_tx()
+  local rrname = tx:rrname()
+  print(rrname)
+
+``txid()``
+^^^^^^^^^^
+
+Return the DNS transaction ID found in the DNS message.
+
+Example::
+
+  local tx = dns.get_tx()
+  local txid = tx:txid()
+  print(txid)
index d9b4c393ccbc9245a1582badee6bbe89e39609d5..e5a12e5d7b126bb43b7f0e14cbab32d049f695fb 100644 (file)
@@ -9,5 +9,6 @@ environment without access to additional modules.
 .. toctree::
 
    base64
+   dns
    hashlib
    packetlib
index 3d0116de82f6f69080237468ca5ea2a6a14f5efd..fd35be7a7ff5b12587616f09cfd5bebdbe144bda 100644 (file)
@@ -297,113 +297,6 @@ HttpGetResponseHeaders
       print(n,v)
   end
 
-DNS
----
-
-If your purpose is to create a logging script, initialize the buffer as:
-
-::
-
-  function init (args)
-     local needs = {}
-     needs["protocol"] = "dns"
-     return needs
-  end
-
-If you are going to use the script for rule matching, choose one of the available DNS buffers listed in
-:ref:`lua-detection` and follow the pattern:
-
-::
-
-  function init (args)
-     local needs = {}
-     needs["dns.rrname"] = tostring(true)
-     return needs
-  end
-
-DnsGetQueries
-~~~~~~~~~~~~~
-
-::
-
-  dns_query = DnsGetQueries();
-  if dns_query ~= nil then
-      for n, t in pairs(dns_query) do
-          rrname = t["rrname"]
-          rrtype = t["type"]
-
-          print ("QUERY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
-                 "TODO" .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
-                 dstip .. ":" .. dp)
-      end
-  end
-
-returns a table of tables
-
-DnsGetAnswers
-~~~~~~~~~~~~~
-
-::
-
-  dns_answers = DnsGetAnswers();
-  if dns_answers ~= nil then
-      for n, t in pairs(dns_answers) do
-          rrname = t["rrname"]
-          rrtype = t["type"]
-          ttl = t["ttl"]
-
-          print ("ANSWER: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
-                 ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
-                 dstip .. ":" .. dp)
-      end
-  end
-
-returns a table of tables
-
-DnsGetAuthorities
-~~~~~~~~~~~~~~~~~
-
-::
-
-  dns_auth = DnsGetAuthorities();
-  if dns_auth ~= nil then
-      for n, t in pairs(dns_auth) do
-          rrname = t["rrname"]
-          rrtype = t["type"]
-          ttl = t["ttl"]
-
-          print ("AUTHORITY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
-                 ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
-                 dstip .. ":" .. dp)
-      end
-  end
-
-returns a table of tables
-
-DnsGetRcode
-~~~~~~~~~~~
-
-::
-
-  rcode = DnsGetRcode();
-  if rcode == nil then
-      return 0
-  end
-  print (rcode)
-
-returns a lua string with the error message, or nil
-
-DnsGetRecursionDesired
-~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-  if DnsGetRecursionDesired() == true then
-      print ("RECURSION DESIRED")
-  end
-
-returns a bool
-
 TLS
 ---
 
index 77a9e2558b57d57d46596b3632ec5e78a2c78c63..5bfa60166a0d4dcfd48bf0240045deaa7e719739 100644 (file)
@@ -39,15 +39,15 @@ static int LuaDnsGetTx(lua_State *L)
 {
     if (!(LuaStateNeedProto(L, ALPROTO_DNS))) {
         return LuaCallbackError(L, "error: protocol not dns");
-    }        
+    }
     RSDNSTransaction *tx = LuaStateGetTX(L);
     if (tx == NULL) {
         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);
@@ -62,9 +62,9 @@ static int LuaDnsTxGetRrname(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetRrname(L, tx->tx);
-}    
+}
 
 static int LuaDnsTxGetTxid(lua_State *L)
 {
@@ -72,7 +72,7 @@ static int LuaDnsTxGetTxid(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetTxId(L, tx->tx);
 }
 
@@ -82,7 +82,7 @@ static int LuaDnsTxGetRcode(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetRcode(L, tx->tx);
 }
 
@@ -92,7 +92,7 @@ static int LuaDnsTxGetRcodeString(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetRcodeString(L, tx->tx);
 }
 
@@ -102,7 +102,7 @@ static int LuaDnsTxGetRecursionDesired(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     uint16_t flags = SCDnsTxGetResponseFlags(tx->tx);
     int recursion_desired = flags & 0x0080 ? 1 : 0;
     lua_pushboolean(L, recursion_desired);
@@ -115,7 +115,7 @@ static int LuaDnsTxGetQueries(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetQueryTable(L, tx->tx);
 }
 
@@ -125,7 +125,7 @@ static int LuaDnsTxGetAnswers(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetAnswerTable(L, tx->tx);
 }
 
@@ -135,7 +135,7 @@ static int LuaDnsTxGetAuthorities(lua_State *L)
     if (tx == NULL) {
         lua_pushnil(L);
         return 1;
-    }        
+    }
     return SCDnsLuaGetAuthorityTable(L, tx->tx);
 }
 
@@ -151,7 +151,7 @@ static const struct luaL_Reg txlib[] = {
     { "txid", LuaDnsTxGetTxid },
     { NULL, NULL, }
     // clang-format on
-};    
+};
 
 static const struct luaL_Reg dnslib[] = {
     // clang-format off