suricata
util-lua-dnp3.c
Go to the documentation of this file.
1 /* Copyright (C) 2015 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "suricata-common.h"
19 
20 #include "app-layer-dnp3.h"
21 #include "app-layer-dnp3-objects.h"
22 
23 #include "lua.h"
24 #include "lualib.h"
25 #include "lauxlib.h"
26 
27 #include "util-lua.h"
28 #include "util-lua-common.h"
29 #include "util-lua-dnp3.h"
30 #include "util-lua-dnp3-objects.h"
31 
32 /**
33  * \brief Helper macro to push key and integer value onto a table.
34  */
35 #define LUA_PUSHT_INT(l, k, v) do { \
36  lua_pushliteral(luastate, k); \
37  lua_pushinteger(luastate, v); \
38  lua_settable(luastate, -3); \
39  } while (0);
40 
41 static void SCLuaPushTableBoolean(lua_State *L, const char *key, bool val)
42 {
43  lua_pushstring(L, key);
44  lua_pushboolean(L, val);
45  lua_settable(L, -3);
46 }
47 
48 static void DNP3PushPoints(lua_State *luastate, DNP3Object *object)
49 {
50  DNP3Point *point;
51  int i = 1;
52 
53  TAILQ_FOREACH(point, object->points, next) {
54  lua_pushinteger(luastate, i++);
55  lua_newtable(luastate);
56 
57  lua_pushliteral(luastate, "index");
58  lua_pushinteger(luastate, point->index);
59  lua_settable(luastate, -3);
60 
61  DNP3PushPoint(luastate, object, point);
62 
63  lua_settable(luastate, -3);
64  }
65 }
66 
67 static void DNP3PushObjects(lua_State *luastate, DNP3ObjectList *objects)
68 {
69  DNP3Object *object = NULL;
70  int i = 1;
71 
72  TAILQ_FOREACH(object, objects, next) {
73  lua_pushinteger(luastate, i++);
74  lua_newtable(luastate);
75 
76  lua_pushliteral(luastate, "group");
77  lua_pushinteger(luastate, object->group);
78  lua_settable(luastate, -3);
79 
80  lua_pushliteral(luastate, "variation");
81  lua_pushinteger(luastate, object->variation);
82  lua_settable(luastate, -3);
83 
84  lua_pushliteral(luastate, "points");
85  lua_newtable(luastate);
86  DNP3PushPoints(luastate, object);
87  lua_settable(luastate, -3);
88 
89  lua_settable(luastate, -3);
90  }
91 }
92 
93 static void DNP3PushLinkHeader(lua_State *luastate, DNP3LinkHeader *header)
94 {
95  LUA_PUSHT_INT(luastate, "len", header->len);
96  LUA_PUSHT_INT(luastate, "control", header->control);
97  LUA_PUSHT_INT(luastate, "dst", header->dst);
98  LUA_PUSHT_INT(luastate, "src", header->src);
99  LUA_PUSHT_INT(luastate, "crc", header->crc);
100 }
101 
102 static void DNP3PushApplicationHeader(lua_State *luastate,
103  DNP3ApplicationHeader *header)
104 {
105  LUA_PUSHT_INT(luastate, "control", header->control);
106  LUA_PUSHT_INT(luastate, "function_code", header->function_code);
107 }
108 
109 static void DNP3PushRequest(lua_State *luastate, DNP3Transaction *tx)
110 {
111  /* Link header. */
112  lua_pushliteral(luastate, "link_header");
113  lua_newtable(luastate);
114  DNP3PushLinkHeader(luastate, &tx->lh);
115  lua_settable(luastate, -3);
116 
117  /* Transport header. */
118  LUA_PUSHT_INT(luastate, "transport_header", tx->th);
119 
120  /* Application header. */
121  lua_pushliteral(luastate, "application_header");
122  lua_newtable(luastate);
123  DNP3PushApplicationHeader(luastate, &tx->ah);
124  lua_settable(luastate, -3);
125 
126  lua_pushliteral(luastate, "objects");
127  lua_newtable(luastate);
128  DNP3PushObjects(luastate, &tx->objects);
129  lua_settable(luastate, -3);
130 }
131 
132 static void DNP3PushResponse(lua_State *luastate, DNP3Transaction *tx)
133 {
134  /* Link header. */
135  lua_pushliteral(luastate, "link_header");
136  lua_newtable(luastate);
137  DNP3PushLinkHeader(luastate, &tx->lh);
138  lua_settable(luastate, -3);
139 
140  /* Transport header. */
141  LUA_PUSHT_INT(luastate, "transport_header", tx->th);
142 
143  /* Application header. */
144  lua_pushliteral(luastate, "application_header");
145  lua_newtable(luastate);
146  DNP3PushApplicationHeader(luastate, &tx->ah);
147  lua_settable(luastate, -3);
148 
149  /* Internal indicators. */
150  LUA_PUSHT_INT(luastate, "indicators", tx->iin.iin1 << 8 | tx->iin.iin2);
151 
152  lua_pushliteral(luastate, "objects");
153  lua_newtable(luastate);
154  DNP3PushObjects(luastate, &tx->objects);
155  lua_settable(luastate, -3);
156 }
157 
158 static int DNP3GetTx(lua_State *luastate)
159 {
160  if (!LuaStateNeedProto(luastate, ALPROTO_DNP3)) {
161  return LuaCallbackError(luastate, "error: protocol not dnp3");
162  }
163 
164  DNP3Transaction *tx = LuaStateGetTX(luastate);
165  if (tx == NULL) {
166  return LuaCallbackError(luastate, "error: no tx");
167  }
168 
169  lua_newtable(luastate);
170 
171  lua_pushliteral(luastate, "tx_num");
172  lua_pushinteger(luastate, tx->tx_num);
173  lua_settable(luastate, -3);
174 
175  SCLuaPushTableBoolean(luastate, "is_request", tx->is_request);
176  if (tx->is_request) {
177  lua_pushliteral(luastate, "request");
178  lua_newtable(luastate);
179  SCLuaPushTableBoolean(luastate, "done", tx->done);
180  SCLuaPushTableBoolean(luastate, "complete", tx->complete);
181  DNP3PushRequest(luastate, tx);
182  lua_settable(luastate, -3);
183  } else {
184  lua_pushliteral(luastate, "response");
185  lua_newtable(luastate);
186  SCLuaPushTableBoolean(luastate, "done", tx->done);
187  SCLuaPushTableBoolean(luastate, "complete", tx->complete);
188  DNP3PushResponse(luastate, tx);
189  lua_settable(luastate, -3);
190  }
191 
192  return 1;
193 }
194 
195 static const struct luaL_Reg dnp3lib[] = {
196  // clang-format off
197  { "get_tx", DNP3GetTx, },
198  { NULL, NULL, }
199  // clang-format on
200 };
201 
203 {
204  luaL_newlib(L, dnp3lib);
205  return 1;
206 }
DNP3Transaction_::complete
uint8_t complete
Definition: app-layer-dnp3.h:227
util-lua-common.h
DNP3Transaction_::done
uint8_t done
Definition: app-layer-dnp3.h:226
DNP3Transaction_::th
DNP3TransportHeader th
Definition: app-layer-dnp3.h:223
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
util-lua.h
DNP3Object_
Struct to hold the list of decoded objects.
Definition: app-layer-dnp3.h:192
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:59
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
DNP3Transaction_::objects
DNP3ObjectList objects
Definition: app-layer-dnp3.h:221
LUA_PUSHT_INT
#define LUA_PUSHT_INT(l, k, v)
Helper macro to push key and integer value onto a table.
Definition: util-lua-dnp3.c:35
lua_State
struct lua_State lua_State
Definition: suricata-common.h:515
DNP3Object_::points
DNP3PointList * points
Definition: app-layer-dnp3.h:201
DNP3Transaction_::ah
DNP3ApplicationHeader ah
Definition: app-layer-dnp3.h:224
SCLuaLoadDnp3Lib
int SCLuaLoadDnp3Lib(lua_State *L)
Definition: util-lua-dnp3.c:202
DNP3Transaction_::iin
DNP3InternalInd iin
Definition: app-layer-dnp3.h:225
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:50
app-layer-dnp3.h
DNP3PushPoint
void DNP3PushPoint(lua_State *luastate, DNP3Object *object, DNP3Point *point)
Push an object point item onto the stack.
Definition: util-lua-dnp3-objects.c:40
util-lua-dnp3-objects.h
DNP3Object_::group
uint8_t group
Definition: app-layer-dnp3.h:193
util-lua-dnp3.h
DNP3Transaction_::is_request
bool is_request
Definition: app-layer-dnp3.h:215
LuaStateGetTX
void * LuaStateGetTX(lua_State *luastate)
get tx pointer from the lua state
Definition: util-lua.c:134
suricata-common.h
DNP3Transaction_::tx_num
uint64_t tx_num
Definition: app-layer-dnp3.h:214
DNP3Object_::variation
uint8_t variation
Definition: app-layer-dnp3.h:194
DNP3Point_::index
uint32_t index
Definition: app-layer-dnp3.h:177
app-layer-dnp3-objects.h
DNP3Transaction_::lh
DNP3LinkHeader lh
Definition: app-layer-dnp3.h:222
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:560
DNP3Point_
DNP3 object point.
Definition: app-layer-dnp3.h:175
DNP3Transaction_
DNP3 transaction.
Definition: app-layer-dnp3.h:211