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 DNP3PushPoints(lua_State *luastate, DNP3Object *object)
42 {
43  DNP3Point *point;
44  int i = 1;
45 
46  TAILQ_FOREACH(point, object->points, next) {
47  lua_pushinteger(luastate, i++);
48  lua_newtable(luastate);
49 
50  lua_pushliteral(luastate, "index");
51  lua_pushinteger(luastate, point->index);
52  lua_settable(luastate, -3);
53 
54  DNP3PushPoint(luastate, object, point);
55 
56  lua_settable(luastate, -3);
57  }
58 }
59 
60 static void DNP3PushObjects(lua_State *luastate, DNP3ObjectList *objects)
61 {
62  DNP3Object *object = NULL;
63  int i = 1;
64 
65  TAILQ_FOREACH(object, objects, next) {
66  lua_pushinteger(luastate, i++);
67  lua_newtable(luastate);
68 
69  lua_pushliteral(luastate, "group");
70  lua_pushinteger(luastate, object->group);
71  lua_settable(luastate, -3);
72 
73  lua_pushliteral(luastate, "variation");
74  lua_pushinteger(luastate, object->variation);
75  lua_settable(luastate, -3);
76 
77  lua_pushliteral(luastate, "points");
78  lua_newtable(luastate);
79  DNP3PushPoints(luastate, object);
80  lua_settable(luastate, -3);
81 
82  lua_settable(luastate, -3);
83  }
84 }
85 
86 static void DNP3PushLinkHeader(lua_State *luastate, DNP3LinkHeader *header)
87 {
88  LUA_PUSHT_INT(luastate, "len", header->len);
89  LUA_PUSHT_INT(luastate, "control", header->control);
90  LUA_PUSHT_INT(luastate, "dst", header->dst);
91  LUA_PUSHT_INT(luastate, "src", header->src);
92  LUA_PUSHT_INT(luastate, "crc", header->crc);
93 }
94 
95 static void DNP3PushApplicationHeader(lua_State *luastate,
96  DNP3ApplicationHeader *header)
97 {
98  LUA_PUSHT_INT(luastate, "control", header->control);
99  LUA_PUSHT_INT(luastate, "function_code", header->function_code);
100 }
101 
102 static void DNP3PushRequest(lua_State *luastate, DNP3Transaction *tx)
103 {
104  /* Link header. */
105  lua_pushliteral(luastate, "link_header");
106  lua_newtable(luastate);
107  DNP3PushLinkHeader(luastate, &tx->lh);
108  lua_settable(luastate, -3);
109 
110  /* Transport header. */
111  LUA_PUSHT_INT(luastate, "transport_header", tx->th);
112 
113  /* Application header. */
114  lua_pushliteral(luastate, "application_header");
115  lua_newtable(luastate);
116  DNP3PushApplicationHeader(luastate, &tx->ah);
117  lua_settable(luastate, -3);
118 
119  lua_pushliteral(luastate, "objects");
120  lua_newtable(luastate);
121  DNP3PushObjects(luastate, &tx->objects);
122  lua_settable(luastate, -3);
123 }
124 
125 static void DNP3PushResponse(lua_State *luastate, DNP3Transaction *tx)
126 {
127  /* Link header. */
128  lua_pushliteral(luastate, "link_header");
129  lua_newtable(luastate);
130  DNP3PushLinkHeader(luastate, &tx->lh);
131  lua_settable(luastate, -3);
132 
133  /* Transport header. */
134  LUA_PUSHT_INT(luastate, "transport_header", tx->th);
135 
136  /* Application header. */
137  lua_pushliteral(luastate, "application_header");
138  lua_newtable(luastate);
139  DNP3PushApplicationHeader(luastate, &tx->ah);
140  lua_settable(luastate, -3);
141 
142  /* Internal indicators. */
143  LUA_PUSHT_INT(luastate, "indicators", tx->iin.iin1 << 8 | tx->iin.iin2);
144 
145  lua_pushliteral(luastate, "objects");
146  lua_newtable(luastate);
147  DNP3PushObjects(luastate, &tx->objects);
148  lua_settable(luastate, -3);
149 }
150 
151 static int DNP3GetTx(lua_State *luastate)
152 {
153  if (!LuaStateNeedProto(luastate, ALPROTO_DNP3)) {
154  return LuaCallbackError(luastate, "error: protocol not dnp3");
155  }
156 
157  DNP3Transaction *tx = LuaStateGetTX(luastate);
158  if (tx == NULL) {
159  return LuaCallbackError(luastate, "error: no tx");
160  }
161 
162  lua_newtable(luastate);
163 
164  lua_pushliteral(luastate, "tx_num");
165  lua_pushinteger(luastate, tx->tx_num);
166  lua_settable(luastate, -3);
167 
168  LUA_PUSHT_INT(luastate, "has_request", tx->is_request ? 1 : 0);
169  if (tx->is_request) {
170  lua_pushliteral(luastate, "request");
171  lua_newtable(luastate);
172  LUA_PUSHT_INT(luastate, "done", tx->done);
173  LUA_PUSHT_INT(luastate, "complete", tx->complete);
174  DNP3PushRequest(luastate, tx);
175  lua_settable(luastate, -3);
176  }
177 
178  LUA_PUSHT_INT(luastate, "has_response", tx->is_request ? 0 : 1);
179  if (!tx->is_request) {
180  lua_pushliteral(luastate, "response");
181  lua_newtable(luastate);
182  LUA_PUSHT_INT(luastate, "done", tx->done);
183  LUA_PUSHT_INT(luastate, "complete", tx->complete);
184  DNP3PushResponse(luastate, tx);
185  lua_settable(luastate, -3);
186  }
187 
188  return 1;
189 }
190 
192 {
193  lua_pushcfunction(luastate, DNP3GetTx);
194  lua_setglobal(luastate, "DNP3GetTx");
195 
196  return 0;
197 }
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
LuaRegisterDNP3Functions
int LuaRegisterDNP3Functions(lua_State *luastate)
Definition: util-lua-dnp3.c:191
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:506
DNP3Object_::points
DNP3PointList * points
Definition: app-layer-dnp3.h:201
DNP3Transaction_::ah
DNP3ApplicationHeader ah
Definition: app-layer-dnp3.h:224
DNP3Transaction_::iin
DNP3InternalInd iin
Definition: app-layer-dnp3.h:225
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:44
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:995
DNP3Point_
DNP3 object point.
Definition: app-layer-dnp3.h:175
DNP3Transaction_
DNP3 transaction.
Definition: app-layer-dnp3.h:211