ntp: expose logged fields to lua

This includes:
- version
- mode
- stratum
- reference_id

Ticket: #8533
This commit is contained in:
Jason Ish
2026-05-06 12:38:50 +00:00
committed by Victor Julien
parent 81692dd2c1
commit 899e9f045e
9 changed files with 274 additions and 0 deletions
+1
View File
@@ -20,6 +20,7 @@ environment without access to additional modules.
hashlib
http
log
ntp
packetlib
rule
smtp
+69
View File
@@ -0,0 +1,69 @@
NTP
###
NTP transaction details are exposed to Lua scripts with the
``suricata.ntp`` library, for example::
local ntp = require("suricata.ntp")
Setup
*****
If your purpose is to create a logging script, initialize the buffer as:
::
function init (args)
local needs = {}
needs["protocol"] = "ntp"
return needs
end
Transaction
***********
NTP is transaction based, and the current transaction must be obtained
before use::
local tx, err = ntp.get_tx()
if tx == nil then
print(err)
end
All other functions are methods on the transaction table.
Transaction Methods
*******************
``version()``
=============
Get the NTP version as an integer.
``mode()``
==========
Get the NTP mode as an integer.
``stratum()``
=============
Get the NTP stratum as an integer.
``reference_id()``
==================
Get the NTP reference ID as a raw 4-byte binary string.
Example::
local tx, err = ntp.get_tx()
local ref_id = tx:reference_id()
if ref_id == "\x4c\x4f\x43\x4c" then
-- ref_id matches "LOCL"
end
-- If looking for a specific printable string, this is also valid
if ref_id == "LOCL" then
...
end
+49
View File
@@ -0,0 +1,49 @@
/* Copyright (C) 2026 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
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use std::os::raw::c_int;
use super::ntp::NTPTransaction;
use crate::lua::*;
#[no_mangle]
pub extern "C" fn SCNtpLuaGetVersion(clua: &mut CLuaState, tx: &mut NTPTransaction) -> c_int {
let lua = LuaState { lua: clua };
lua.pushinteger(tx.version as i64);
1
}
#[no_mangle]
pub extern "C" fn SCNtpLuaGetMode(clua: &mut CLuaState, tx: &mut NTPTransaction) -> c_int {
let lua = LuaState { lua: clua };
lua.pushinteger(tx.mode as i64);
1
}
#[no_mangle]
pub extern "C" fn SCNtpLuaGetStratum(clua: &mut CLuaState, tx: &mut NTPTransaction) -> c_int {
let lua = LuaState { lua: clua };
lua.pushinteger(tx.stratum as i64);
1
}
#[no_mangle]
pub extern "C" fn SCNtpLuaGetReferenceId(clua: &mut CLuaState, tx: &mut NTPTransaction) -> c_int {
let lua = LuaState { lua: clua };
lua.pushbytes(&tx.reference_id);
1
}
+1
View File
@@ -21,4 +21,5 @@
pub mod detect;
pub mod log;
pub mod lua;
pub mod ntp;
+2
View File
@@ -526,6 +526,7 @@ noinst_HEADERS = \
util-lua-http.h \
util-lua-ja3.h \
util-lua-log.h \
util-lua-ntp.h \
util-lua-packetlib.h \
util-lua-rule.h \
util-lua-sandbox.h \
@@ -1084,6 +1085,7 @@ libsuricata_c_a_SOURCES = \
util-lua-http.c \
util-lua-ja3.c \
util-lua-log.c \
util-lua-ntp.c \
util-lua-packetlib.c \
util-lua-rule.c \
util-lua-sandbox.c \
+8
View File
@@ -525,6 +525,8 @@ static int LuaScriptInit(const char *filename, LogLuaScriptOptions *options, Log
options->alproto = ALPROTO_SSH;
else if (strcmp(k,"protocol") == 0 && strcmp(v, "smtp") == 0)
options->alproto = ALPROTO_SMTP;
else if (strcmp(k, "protocol") == 0 && strcmp(v, "ntp") == 0)
options->alproto = ALPROTO_NTP;
else if (strcmp(k, "type") == 0 && strcmp(v, "packet") == 0)
options->packet = 1;
else if (strcmp(k, "filter") == 0 && strcmp(v, "alerts") == 0)
@@ -812,6 +814,12 @@ static OutputInitResult OutputLuaLogInit(SCConfNode *conf)
om->ts_log_progress = -1;
om->tc_log_progress = -1;
SCAppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SMTP);
} else if (opts.alproto == ALPROTO_NTP) {
om->TxLogFunc = LuaTxLogger;
om->alproto = ALPROTO_NTP;
om->ts_log_progress = -1;
om->tc_log_progress = -1;
SCAppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_NTP);
} else if (opts.packet && opts.alerts) {
om->PacketLogFunc = LuaPacketLoggerAlerts;
om->PacketConditionFunc = LuaPacketConditionAlerts;
+2
View File
@@ -36,6 +36,7 @@
#include "util-lua-ja3.h"
#include "util-lua-filelib.h"
#include "util-lua-log.h"
#include "util-lua-ntp.h"
#include "util-lua-util.h"
#include "lauxlib.h"
@@ -55,6 +56,7 @@ static const luaL_Reg builtins[] = {
{ "suricata.http", SCLuaLoadHttpLib },
{ "suricata.ja3", SCLuaLoadJa3Lib },
{ "suricata.log", SCLuaLoadLogLib },
{ "suricata.ntp", SCLuaLoadNtpLib },
{ "suricata.packet", LuaLoadPacketLib },
{ "suricata.rule", SCLuaLoadRuleLib },
{ "suricata.smtp", SCLuaLoadSmtpLib },
+117
View File
@@ -0,0 +1,117 @@
/* Copyright (C) 2026 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
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "suricata-common.h"
#include "util-lua-ntp.h"
#include "util-lua.h"
#include "util-lua-common.h"
#include "rust.h"
static const char ntp_tx[] = "suricata:ntp:tx";
struct LuaTx {
NTPTransaction *tx;
};
static int LuaNtpGetTx(lua_State *L)
{
if (!(LuaStateNeedProto(L, ALPROTO_NTP))) {
return LuaCallbackError(L, "error: protocol not ntp");
}
NTPTransaction *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, ntp_tx);
lua_setmetatable(L, -2);
return 1;
}
static int LuaNtpTxGetVersion(lua_State *L)
{
struct LuaTx *tx = luaL_testudata(L, 1, ntp_tx);
if (tx == NULL) {
lua_pushnil(L);
return 1;
}
return SCNtpLuaGetVersion(L, tx->tx);
}
static int LuaNtpTxGetMode(lua_State *L)
{
struct LuaTx *tx = luaL_testudata(L, 1, ntp_tx);
if (tx == NULL) {
lua_pushnil(L);
return 1;
}
return SCNtpLuaGetMode(L, tx->tx);
}
static int LuaNtpTxGetStratum(lua_State *L)
{
struct LuaTx *tx = luaL_testudata(L, 1, ntp_tx);
if (tx == NULL) {
lua_pushnil(L);
return 1;
}
return SCNtpLuaGetStratum(L, tx->tx);
}
static int LuaNtpTxGetReferenceId(lua_State *L)
{
struct LuaTx *tx = luaL_testudata(L, 1, ntp_tx);
if (tx == NULL) {
lua_pushnil(L);
return 1;
}
return SCNtpLuaGetReferenceId(L, tx->tx);
}
static const struct luaL_Reg txlib[] = {
// clang-format off
{ "mode", LuaNtpTxGetMode },
{ "reference_id", LuaNtpTxGetReferenceId },
{ "stratum", LuaNtpTxGetStratum },
{ "version", LuaNtpTxGetVersion },
{ NULL, NULL, }
// clang-format on
};
static const struct luaL_Reg ntplib[] = {
// clang-format off
{ "get_tx", LuaNtpGetTx },
{ NULL, NULL,}
// clang-format on
};
int SCLuaLoadNtpLib(lua_State *L)
{
luaL_newmetatable(L, ntp_tx);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
luaL_setfuncs(L, txlib, 0);
luaL_newlib(L, ntplib);
return 1;
}
+25
View File
@@ -0,0 +1,25 @@
/* Copyright (C) 2026 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
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef SURICATA_UTIL_LUA_NTP_H
#define SURICATA_UTIL_LUA_NTP_H
#include "lua.h"
int SCLuaLoadNtpLib(lua_State *L);
#endif /* SURICATA_UTIL_LUA_NTP_H */