mirror of https://github.com/OISF/suricata
DNP3: Lua detect support.
Adds support for access the DNP3 transaction in Lua rules.pull/2391/head
parent
44a69f6355
commit
a59f31a99f
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@
|
|||||||
|
/* Copyright (C) 2015 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 __UTIL_LUA_DNP3_OBJECTS_H__
|
||||||
|
#define __UTIL_LUA_DNP3_OBJECTS_H__
|
||||||
|
|
||||||
|
void DNP3PushPoint(lua_State *luastate, DNP3Object *object,
|
||||||
|
DNP3Point *item);
|
||||||
|
|
||||||
|
#endif /* ! __UTIL_LUA_DNP3_OBJECTS_H__ */
|
@ -0,0 +1,201 @@
|
|||||||
|
/* Copyright (C) 2015 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 "app-layer-dnp3.h"
|
||||||
|
#include "app-layer-dnp3-objects.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LUA
|
||||||
|
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
|
||||||
|
#include "util-lua.h"
|
||||||
|
#include "util-lua-common.h"
|
||||||
|
#include "util-lua-dnp3-objects.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Helper macro to push key and integer value onto a table.
|
||||||
|
*/
|
||||||
|
#define LUA_PUSHT_INT(l, k, v) do { \
|
||||||
|
lua_pushliteral(luastate, k); \
|
||||||
|
lua_pushinteger(luastate, v); \
|
||||||
|
lua_settable(luastate, -3); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
static void DNP3PushPoints(lua_State *luastate, DNP3Object *object)
|
||||||
|
{
|
||||||
|
DNP3Point *point;
|
||||||
|
int i = 1;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(point, object->points, next) {
|
||||||
|
lua_pushinteger(luastate, i++);
|
||||||
|
lua_newtable(luastate);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "index");
|
||||||
|
lua_pushinteger(luastate, point->index);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
DNP3PushPoint(luastate, object, point);
|
||||||
|
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DNP3PushObjects(lua_State *luastate, DNP3ObjectList *objects)
|
||||||
|
{
|
||||||
|
DNP3Object *object = NULL;
|
||||||
|
int i = 1;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(object, objects, next) {
|
||||||
|
lua_pushinteger(luastate, i++);
|
||||||
|
lua_newtable(luastate);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "group");
|
||||||
|
lua_pushinteger(luastate, object->group);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "variation");
|
||||||
|
lua_pushinteger(luastate, object->variation);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "points");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushPoints(luastate, object);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DNP3PushLinkHeader(lua_State *luastate, DNP3LinkHeader *header)
|
||||||
|
{
|
||||||
|
LUA_PUSHT_INT(luastate, "len", header->len);
|
||||||
|
LUA_PUSHT_INT(luastate, "control", header->control);
|
||||||
|
LUA_PUSHT_INT(luastate, "dst", header->dst);
|
||||||
|
LUA_PUSHT_INT(luastate, "src", header->src);
|
||||||
|
LUA_PUSHT_INT(luastate, "crc", header->crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DNP3PushApplicationHeader(lua_State *luastate,
|
||||||
|
DNP3ApplicationHeader *header)
|
||||||
|
{
|
||||||
|
LUA_PUSHT_INT(luastate, "control", header->control);
|
||||||
|
LUA_PUSHT_INT(luastate, "function_code", header->function_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DNP3PushRequest(lua_State *luastate, DNP3Transaction *tx)
|
||||||
|
{
|
||||||
|
/* Link header. */
|
||||||
|
lua_pushliteral(luastate, "link_header");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushLinkHeader(luastate, &tx->request_lh);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
/* Transport header. */
|
||||||
|
LUA_PUSHT_INT(luastate, "transport_header", tx->request_th);
|
||||||
|
|
||||||
|
/* Application header. */
|
||||||
|
lua_pushliteral(luastate, "application_header");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushApplicationHeader(luastate, &tx->request_ah);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "objects");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushObjects(luastate, &tx->request_objects);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DNP3PushResponse(lua_State *luastate, DNP3Transaction *tx)
|
||||||
|
{
|
||||||
|
/* Link header. */
|
||||||
|
lua_pushliteral(luastate, "link_header");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushLinkHeader(luastate, &tx->response_lh);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
/* Transport header. */
|
||||||
|
LUA_PUSHT_INT(luastate, "transport_header", tx->response_th);
|
||||||
|
|
||||||
|
/* Application header. */
|
||||||
|
lua_pushliteral(luastate, "application_header");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushApplicationHeader(luastate, &tx->response_ah);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
/* Internal indicators. */
|
||||||
|
LUA_PUSHT_INT(luastate, "indicators",
|
||||||
|
tx->response_iin.iin1 << 8 | tx->response_iin.iin2);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "objects");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
DNP3PushObjects(luastate, &tx->response_objects);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DNP3GetTx(lua_State *luastate)
|
||||||
|
{
|
||||||
|
if (!LuaStateNeedProto(luastate, ALPROTO_DNP3)) {
|
||||||
|
return LuaCallbackError(luastate, "error: protocol not dnp3");
|
||||||
|
}
|
||||||
|
|
||||||
|
DNP3Transaction *tx = LuaStateGetTX(luastate);
|
||||||
|
if (tx == NULL) {
|
||||||
|
return LuaCallbackError(luastate, "error: no tx");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_newtable(luastate);
|
||||||
|
|
||||||
|
lua_pushliteral(luastate, "tx_num");
|
||||||
|
lua_pushinteger(luastate, tx->tx_num);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
|
||||||
|
LUA_PUSHT_INT(luastate, "has_request", tx->has_request);
|
||||||
|
if (tx->has_request) {
|
||||||
|
lua_pushliteral(luastate, "request");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
LUA_PUSHT_INT(luastate, "done", tx->request_done);
|
||||||
|
LUA_PUSHT_INT(luastate, "complete", tx->request_complete);
|
||||||
|
DNP3PushRequest(luastate, tx);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
LUA_PUSHT_INT(luastate, "has_response", tx->has_response);
|
||||||
|
if (tx->has_response) {
|
||||||
|
lua_pushliteral(luastate, "response");
|
||||||
|
lua_newtable(luastate);
|
||||||
|
LUA_PUSHT_INT(luastate, "done", tx->response_done);
|
||||||
|
LUA_PUSHT_INT(luastate, "complete", tx->response_complete);
|
||||||
|
DNP3PushResponse(luastate, tx);
|
||||||
|
lua_settable(luastate, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaRegisterDNP3Functions(lua_State *luastate)
|
||||||
|
{
|
||||||
|
lua_pushcfunction(luastate, DNP3GetTx);
|
||||||
|
lua_setglobal(luastate, "DNP3GetTx");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_LUA */
|
@ -0,0 +1,27 @@
|
|||||||
|
/* Copyright (C) 2015 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 __UTIL_LUA_DNP3_H__
|
||||||
|
#define __UTIL_LUA_DNP3_H__
|
||||||
|
|
||||||
|
#ifdef HAVE_LUA
|
||||||
|
|
||||||
|
int LuaRegisterDNP3Functions(lua_State *);
|
||||||
|
|
||||||
|
#endif /* HAVE_LUA */
|
||||||
|
|
||||||
|
#endif /* !__UTIL_LUA_DNP3_H__ */
|
Loading…
Reference in New Issue