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