suricata
app-layer-dnp3.h
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/**
19 * \file
20 *
21 * DNP3 application layer protocol header file
22 */
23
24#ifndef SURICATA_APP_LAYER_DNP3_H
25#define SURICATA_APP_LAYER_DNP3_H
26
27#include "rust.h"
28#if __BYTE_ORDER == __BIG_ENDIAN
29#include "util-byte.h"
30#endif
31
32/* DNP3 application request function codes. */
33#define DNP3_APP_FC_CONFIRM 0x00
34#define DNP3_APP_FC_READ 0x01
35#define DNP3_APP_FC_WRITE 0x02
36#define DNP3_APP_FC_SELECT 0x03
37#define DNP3_APP_FC_OPERATE 0x04
38#define DNP3_APP_FC_DIR_OPERATE 0x05
39#define DNP3_APP_FC_DIR_OPERATE_NR 0x06
40#define DNP3_APP_FC_FREEZE 0x07
41#define DNP3_APP_FC_FREEZE_NR 0x08
42#define DNP3_APP_FC_FREEZE_CLEAR 0x09
43#define DNP3_APP_FC_FREEZE_CLEAR_NR 0x0a
44#define DNP3_APP_FC_FREEZE_AT_TIME 0x0b
45#define DNP3_APP_FC_FREEZE_AT_TIME_NR 0x0c
46#define DNP3_APP_FC_COLD_RESTART 0x0d
47#define DNP3_APP_FC_WARM_RESTART 0x0e
48#define DNP3_APP_FC_INITIALIZE_DATA 0x0f
49#define DNP3_APP_FC_INITIALIZE_APPLICATION 0x10
50#define DNP3_APP_FC_START_APPLICATION 0x11
51#define DNP3_APP_FC_STOP_APPLICATION 0x12
52#define DNP3_APP_FC_SAVE_CONFIGURATION 0x13
53#define DNP3_APP_FC_ENABLE_UNSOLICITED 0x14
54#define DNP3_APP_FC_DISABLE_UNSOLICITED 0x15
55#define DNP3_APP_FC_ASSIGN_CLASS 0x16
56#define DNP3_APP_FC_DELAY_MEASUREMENT 0x17
57#define DNP3_APP_FC_RECORD_CURRENT_TIME 0x18
58#define DNP3_APP_FC_OPEN_TIME 0x19
59#define DNP3_APP_FC_CLOSE_FILE 0x1a
60#define DNP3_APP_FC_DELETE_FILE 0x1b
61#define DNP3_APP_FC_GET_FILE_INFO 0x1c
62#define DNP3_APP_FC_AUTHENTICATE_FILE 0x1d
63#define DNP3_APP_FC_ABORT_FILE 0x1e
64#define DNP3_APP_FC_ACTIVATE_CONFIG 0x1f
65#define DNP3_APP_FC_AUTH_REQ 0x20
66#define DNP3_APP_FC_AUTH_REQ_NR 0x21
67
68/* DNP3 application response function codes. */
69#define DNP3_APP_FC_RESPONSE 0x81
70#define DNP3_APP_FC_UNSOLICITED_RESP 0x82
71#define DNP3_APP_FC_AUTH_RESP 0x83
72
73/* Extract fields from the link control octet. */
74#define DNP3_LINK_DIR(control) (control & 0x80)
75#define DNP3_LINK_PRI(control) (control & 0x40)
76#define DNP3_LINK_FCB(control) (control & 0x20)
77#define DNP3_LINK_FCV(control) (control & 0x10)
78#define DNP3_LINK_FC(control) (control & 0x0f)
79
80/* Extract fields from transport layer header octet. */
81#define DNP3_TH_FIN(x) (x & 0x80)
82#define DNP3_TH_FIR(x) (x & 0x40)
83#define DNP3_TH_SEQ(x) (x & 0x3f)
84
85/* Extract fields from the application control octet. */
86#define DNP3_APP_FIR(x) (x & 0x80)
87#define DNP3_APP_FIN(x) (x & 0x40)
88#define DNP3_APP_CON(x) (x & 0x20)
89#define DNP3_APP_UNS(x) (x & 0x10)
90#define DNP3_APP_SEQ(x) (x & 0x0f)
91
92/* DNP3 values are stored in little endian on the wire, so swapping will be
93 * needed on big endian architectures. */
94#if __BYTE_ORDER == __BIG_ENDIAN
95#define DNP3_SWAP16(x) SCByteSwap16(x)
96#define DNP3_SWAP32(x) SCByteSwap32(x)
97#define DNP3_SWAP64(x) SCByteSwap64(x)
98#elif __BYTE_ORDER == __LITTLE_ENDIAN
99#define DNP3_SWAP16(x) x
100#define DNP3_SWAP32(x) x
101#define DNP3_SWAP64(x) x
102#endif
103
104/* DNP3 decoder events. */
105enum {
112};
113
114/**
115 * \brief DNP3 link header.
116 */
117typedef struct DNP3LinkHeader_ {
118 uint8_t start_byte0; /**< First check byte. */
119 uint8_t start_byte1; /**< Second check byte. */
120 uint8_t len; /**< Length of PDU without CRCs. */
121 uint8_t control; /**< Control flags. */
122 uint16_t dst; /**< DNP3 destination address. */
123 uint16_t src; /**< DNP3 source address. */
124 uint16_t crc; /**< Link header CRC. */
125} __attribute__((__packed__)) DNP3LinkHeader;
126
127/**
128 * \brief DNP3 transport header.
129 */
130typedef uint8_t DNP3TransportHeader;
131
132/**
133 * \brief DNP3 application header.
134 */
136 uint8_t control; /**< Control flags. */
137 uint8_t function_code; /**< Application function code. */
138} __attribute__((__packed__)) DNP3ApplicationHeader;
139
140/**
141 * \brief DNP3 internal indicators.
142 *
143 * Part of the application header for responses only.
144 */
145typedef struct DNP3InternalInd_ {
146 uint8_t iin1;
147 uint8_t iin2;
148} __attribute__((__packed__)) DNP3InternalInd;
149
150/**
151 * \brief A struct used for buffering incoming data prior to reassembly.
152 */
153typedef struct DNP3Buffer_ {
154 uint8_t *buffer;
155 size_t size;
156 int len;
159
160/**
161 * \brief DNP3 application object header.
162 */
163typedef struct DNP3ObjHeader_ {
164 uint8_t group;
165 uint8_t variation;
166 uint8_t qualifier;
167} __attribute__((packed)) DNP3ObjHeader;
168
169/**
170 * \brief DNP3 object point.
171 *
172 * Each DNP3 object can have 0 or more points representing the values
173 * of the object.
174 */
175typedef struct DNP3Point_ {
176 uint32_t prefix; /**< Prefix value for point. */
177 uint32_t index; /**< Index of point. If the object is prefixed
178 * with an index then this will be that
179 * value. Otherwise this is the place the point
180 * was in the list of points (starting at 0). */
181 uint32_t size; /**< Size of point if the object prefix was a
182 * size. */
183 void *data; /**< Data for this point. */
186
187typedef TAILQ_HEAD(DNP3PointList_, DNP3Point_) DNP3PointList;
188
189/**
190 * \brief Struct to hold the list of decoded objects.
191 */
192typedef struct DNP3Object_ {
193 uint8_t group;
194 uint8_t variation;
195 uint8_t qualifier;
196 uint8_t prefix_code;
197 uint8_t range_code;
198 uint32_t start;
199 uint32_t stop;
200 uint32_t count;
201 DNP3PointList *points; /**< List of points for this object. */
202
205
206typedef TAILQ_HEAD(DNP3ObjectList_, DNP3Object_) DNP3ObjectList;
207
208/**
209 * \brief DNP3 transaction.
210 */
211typedef struct DNP3Transaction_ {
213
214 uint64_t tx_num; /**< Internal transaction ID. */
215 bool is_request; /**< Is this tx a request? */
216
218
219 uint8_t *buffer; /**< Reassembled request buffer. */
220 uint32_t buffer_len;
221 DNP3ObjectList objects;
222 DNP3LinkHeader lh;
224 DNP3ApplicationHeader ah;
225 DNP3InternalInd iin;
226 uint8_t done;
227 uint8_t complete; /**< Was the decode complete. It will not be
228 complete if we hit objects we do not know. */
229
232
234
235/**
236 * \brief Per flow DNP3 state.
237 */
238typedef struct DNP3State_ {
241 DNP3Transaction *curr; /**< Current transaction. */
243 uint16_t events;
244 uint32_t unreplied; /**< Number of unreplied requests. */
245 uint8_t flooded; /**< Flag indicating flood. */
246
247 DNP3Buffer request_buffer; /**< Request buffer for buffering
248 * incomplete request PDUs received
249 * over TCP. */
250 DNP3Buffer response_buffer; /**< Response buffer for buffering
251 * incomplete response PDUs received
252 * over TCP. */
253
255
256void RegisterDNP3Parsers(void);
257void DNP3ParserRegisterTests(void);
258int DNP3PrefixIsSize(uint8_t);
259
260#endif /* SURICATA_APP_LAYER_DNP3_H */
void DNP3ParserRegisterTests(void)
struct DNP3Point_ DNP3Point
DNP3 object point.
struct DNP3Object_ DNP3Object
Struct to hold the list of decoded objects.
int DNP3PrefixIsSize(uint8_t)
Check if the prefix code is a size prefix.
struct DNP3Buffer_ DNP3Buffer
A struct used for buffering incoming data prior to reassembly.
void RegisterDNP3Parsers(void)
Register the DNP3 application protocol parser.
struct DNP3Transaction_ DNP3Transaction
DNP3 transaction.
uint8_t DNP3TransportHeader
DNP3 transport header.
@ DNP3_DECODER_EVENT_MALFORMED
@ DNP3_DECODER_EVENT_LEN_TOO_SMALL
@ DNP3_DECODER_EVENT_UNKNOWN_OBJECT
@ DNP3_DECODER_EVENT_BAD_LINK_CRC
@ DNP3_DECODER_EVENT_FLOODED
@ DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC
struct DNP3State_ DNP3State
Per flow DNP3 state.
struct HtpBodyChunk_ * next
struct AppLayerTxData AppLayerTxData
struct AppLayerStateData AppLayerStateData
struct PrefilterEngineFlowbits __attribute__
DNP3 application header.
#define TAILQ_HEAD(name, type)
Definition queue.h:230
DNP3 application header.
A struct used for buffering incoming data prior to reassembly.
uint8_t * buffer
DNP3 internal indicators.
DNP3 link header.
DNP3 application object header.
Struct to hold the list of decoded objects.
uint8_t qualifier
TAILQ_ENTRY(DNP3Object_) next
DNP3PointList * points
uint8_t range_code
uint8_t prefix_code
uint8_t variation
DNP3 object point.
uint32_t prefix
uint32_t index
uint32_t size
TAILQ_ENTRY(DNP3Point_) next
Per flow DNP3 state.
DNP3Transaction * curr
uint8_t flooded
DNP3Buffer request_buffer
AppLayerStateData state_data
TAILQ_HEAD(, DNP3Transaction_) tx_list
uint64_t transaction_max
DNP3Buffer response_buffer
uint16_t events
uint32_t unreplied
DNP3 transaction.
DNP3LinkHeader lh
DNP3InternalInd iin
DNP3TransportHeader th
DNP3ObjectList objects
AppLayerTxData tx_data
TAILQ_ENTRY(DNP3Transaction_) next
struct DNP3State_ * dnp3
DNP3ApplicationHeader ah