]> git.ipfire.org Git - people/ms/suricata.git/blob - src/app-layer-dnp3.c
7f75d9f1edd367b01f71de30d84c81f961a16598
[people/ms/suricata.git] / src / app-layer-dnp3.c
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 #include "stream.h"
20 #include "util-byte.h"
21 #include "util-unittest.h"
22 #include "util-hashlist.h"
23
24 #include "util-print.h"
25
26 #include "app-layer-protos.h"
27 #include "app-layer-parser.h"
28 #include "app-layer-detect-proto.h"
29
30 #include "app-layer-dnp3.h"
31 #include "app-layer-dnp3-objects.h"
32
33 /* For hexdump(). */
34 #include "app-layer-dcerpc-common.h"
35
36 /* Default number of unreplied requests to be considered a flood. */
37 #define DNP3_DEFAULT_REQ_FLOOD_COUNT 500
38
39 #define DNP3_DEFAULT_PORT "20000"
40
41 /* Expected values for the start bytes. */
42 #define DNP3_START_BYTE0 0x05
43 #define DNP3_START_BYTE1 0x64
44
45 /* Minimum length for a DNP3 frame. */
46 #define DNP3_MIN_LEN 5
47
48 /* Length of each CRC. */
49 #define DNP3_CRC_LEN 2
50
51 /* DNP3 block size. After the link header a CRC is inserted after
52 * after 16 bytes of data. */
53 #define DNP3_BLOCK_SIZE 16
54
55 /* Maximum transport layer sequence number. */
56 #define DNP3_MAX_TRAN_SEQNO 64
57
58 /* Maximum application layer sequence number. */
59 #define DNP3_MAX_APP_SEQNO 16
60
61 /* The number of bytes in the header that are counted as part of the
62 * header length field. */
63 #define DNP3_LINK_HDR_LEN 5
64
65 /* Link function codes. */
66 enum {
67 DNP3_LINK_FC_CONFIRMED_USER_DATA = 3,
68 DNP3_LINK_FC_UNCONFIRMED_USER_DATA
69 };
70
71 /* Reserved addresses. */
72 #define DNP3_RESERVED_ADDR_MIN 0xfff0
73 #define DNP3_RESERVED_ADDR_MAX 0xfffb
74
75 /* Source addresses must be < 0xfff0. */
76 #define DNP3_SRC_ADDR_MAX 0xfff0
77
78 #define DNP3_OBJ_TIME_SIZE 6 /* AKA UINT48. */
79 #define DNP3_OBJ_G12_V1_SIZE 11
80 #define DNP3_OBJ_G12_V2_SIZE 11
81 #define DNP3_OBJ_G12_V3_SIZE 1
82
83 /* Extract the prefix code from the object qualifier. */
84 #define DNP3_OBJ_PREFIX(x) ((x >> 4) & 0x7)
85
86 /* Extract the range code from the object qualifier. */
87 #define DNP3_OBJ_RANGE(x) (x & 0xf)
88
89 /* Decoder event map. */
90 SCEnumCharMap dnp3_decoder_event_table[] = {
91 {"FLOODED", DNP3_DECODER_EVENT_FLOODED},
92 {"LEN_TOO_SMALL", DNP3_DECODER_EVENT_LEN_TOO_SMALL},
93 {"BAD_LINK_CRC", DNP3_DECODER_EVENT_BAD_LINK_CRC},
94 {"BAD_TRANSPORT_CRC", DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC},
95 {"MALFORMED", DNP3_DECODER_EVENT_MALFORMED},
96 {"UNKNOWN_OBJECT", DNP3_DECODER_EVENT_UNKNOWN_OBJECT},
97 {NULL, -1},
98 };
99
100 /* Calculate the next transport sequence number. */
101 #define NEXT_TH_SEQNO(current) ((current + 1) % DNP3_MAX_TRAN_SEQNO)
102
103 /* Calculate the next application sequence number. */
104 #define NEXT_APP_SEQNO(current) ((current + 1) % DNP3_MAX_APP_SEQNO)
105
106 /* CRC table generated by pycrc - http://github.com/tpircher/pycrc.
107 * - Polynomial: 0x3d65. */
108 static const uint16_t crc_table[256] = {
109 0x0000, 0x365e, 0x6cbc, 0x5ae2, 0xd978, 0xef26, 0xb5c4, 0x839a,
110 0xff89, 0xc9d7, 0x9335, 0xa56b, 0x26f1, 0x10af, 0x4a4d, 0x7c13,
111 0xb26b, 0x8435, 0xded7, 0xe889, 0x6b13, 0x5d4d, 0x07af, 0x31f1,
112 0x4de2, 0x7bbc, 0x215e, 0x1700, 0x949a, 0xa2c4, 0xf826, 0xce78,
113 0x29af, 0x1ff1, 0x4513, 0x734d, 0xf0d7, 0xc689, 0x9c6b, 0xaa35,
114 0xd626, 0xe078, 0xba9a, 0x8cc4, 0x0f5e, 0x3900, 0x63e2, 0x55bc,
115 0x9bc4, 0xad9a, 0xf778, 0xc126, 0x42bc, 0x74e2, 0x2e00, 0x185e,
116 0x644d, 0x5213, 0x08f1, 0x3eaf, 0xbd35, 0x8b6b, 0xd189, 0xe7d7,
117 0x535e, 0x6500, 0x3fe2, 0x09bc, 0x8a26, 0xbc78, 0xe69a, 0xd0c4,
118 0xacd7, 0x9a89, 0xc06b, 0xf635, 0x75af, 0x43f1, 0x1913, 0x2f4d,
119 0xe135, 0xd76b, 0x8d89, 0xbbd7, 0x384d, 0x0e13, 0x54f1, 0x62af,
120 0x1ebc, 0x28e2, 0x7200, 0x445e, 0xc7c4, 0xf19a, 0xab78, 0x9d26,
121 0x7af1, 0x4caf, 0x164d, 0x2013, 0xa389, 0x95d7, 0xcf35, 0xf96b,
122 0x8578, 0xb326, 0xe9c4, 0xdf9a, 0x5c00, 0x6a5e, 0x30bc, 0x06e2,
123 0xc89a, 0xfec4, 0xa426, 0x9278, 0x11e2, 0x27bc, 0x7d5e, 0x4b00,
124 0x3713, 0x014d, 0x5baf, 0x6df1, 0xee6b, 0xd835, 0x82d7, 0xb489,
125 0xa6bc, 0x90e2, 0xca00, 0xfc5e, 0x7fc4, 0x499a, 0x1378, 0x2526,
126 0x5935, 0x6f6b, 0x3589, 0x03d7, 0x804d, 0xb613, 0xecf1, 0xdaaf,
127 0x14d7, 0x2289, 0x786b, 0x4e35, 0xcdaf, 0xfbf1, 0xa113, 0x974d,
128 0xeb5e, 0xdd00, 0x87e2, 0xb1bc, 0x3226, 0x0478, 0x5e9a, 0x68c4,
129 0x8f13, 0xb94d, 0xe3af, 0xd5f1, 0x566b, 0x6035, 0x3ad7, 0x0c89,
130 0x709a, 0x46c4, 0x1c26, 0x2a78, 0xa9e2, 0x9fbc, 0xc55e, 0xf300,
131 0x3d78, 0x0b26, 0x51c4, 0x679a, 0xe400, 0xd25e, 0x88bc, 0xbee2,
132 0xc2f1, 0xf4af, 0xae4d, 0x9813, 0x1b89, 0x2dd7, 0x7735, 0x416b,
133 0xf5e2, 0xc3bc, 0x995e, 0xaf00, 0x2c9a, 0x1ac4, 0x4026, 0x7678,
134 0x0a6b, 0x3c35, 0x66d7, 0x5089, 0xd313, 0xe54d, 0xbfaf, 0x89f1,
135 0x4789, 0x71d7, 0x2b35, 0x1d6b, 0x9ef1, 0xa8af, 0xf24d, 0xc413,
136 0xb800, 0x8e5e, 0xd4bc, 0xe2e2, 0x6178, 0x5726, 0x0dc4, 0x3b9a,
137 0xdc4d, 0xea13, 0xb0f1, 0x86af, 0x0535, 0x336b, 0x6989, 0x5fd7,
138 0x23c4, 0x159a, 0x4f78, 0x7926, 0xfabc, 0xcce2, 0x9600, 0xa05e,
139 0x6e26, 0x5878, 0x029a, 0x34c4, 0xb75e, 0x8100, 0xdbe2, 0xedbc,
140 0x91af, 0xa7f1, 0xfd13, 0xcb4d, 0x48d7, 0x7e89, 0x246b, 0x1235
141 };
142
143 /**
144 * \brief Compute the CRC for a buffer.
145 *
146 * \param buf Buffer to create CRC from.
147 * \param len Length of buffer (number of bytes to use for CRC).
148
149 */
150 static uint16_t DNP3ComputeCRC(const uint8_t *buf, uint32_t len)
151 {
152 const uint8_t *byte = buf;
153 uint16_t crc = 0;
154 int idx;
155
156 while (len--) {
157 idx = (crc ^ *byte) & 0xff;
158 crc = (crc_table[idx] ^ (crc >> 8)) & 0xffff;
159 byte++;
160 }
161
162 return ~crc & 0xffff;
163 }
164
165 /**
166 * \brief Check the CRC of a block.
167 *
168 * \param block The block of data with CRC to be checked.
169 * \param len The size of the data block.
170 *
171 * \retval 1 if CRC is OK, otherwise 0.
172 */
173 static int DNP3CheckCRC(const uint8_t *block, uint32_t len)
174 {
175 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
176 return 1;
177 #endif
178 uint32_t crc_offset;
179 uint16_t crc;
180
181 /* Need at least one byte plus the CRC. */
182 if (len < DNP3_CRC_LEN + 1) {
183 return 0;
184 }
185
186 crc_offset = len - DNP3_CRC_LEN;
187 crc = DNP3ComputeCRC(block, len - DNP3_CRC_LEN);
188 if (((crc & 0xff) == block[crc_offset]) &&
189 ((crc >> 8) == block[crc_offset + 1])) {
190 return 1;
191 }
192
193 return 0;
194 }
195
196 /**
197 * \brief Check the CRC of the link header.
198 *
199 * \param header Point to the link header.
200 *
201 * \retval 1 if header CRC is OK, otherwise 0.
202 */
203 static int DNP3CheckLinkHeaderCRC(const DNP3LinkHeader *header)
204 {
205 return DNP3CheckCRC((uint8_t *)header, sizeof(DNP3LinkHeader));
206 }
207
208 /**
209 * \brief Check user data CRCs.
210 *
211 * \param data Pointer to user data.
212 * \param len Length of user data.
213 *
214 * \retval 1 if CRCs are OK, otherwise 0.
215 */
216 static int DNP3CheckUserDataCRCs(const uint8_t *data, uint32_t len)
217 {
218 uint32_t offset = 0;
219 uint32_t block_size;
220
221 while (offset < len) {
222 if (len - offset >= DNP3_BLOCK_SIZE + DNP3_CRC_LEN) {
223 block_size = DNP3_BLOCK_SIZE + DNP3_CRC_LEN;
224 }
225 else {
226 block_size = len - offset;
227 }
228
229 if (!DNP3CheckCRC(data + offset, block_size)) {
230 /* Once failed, may as well return immediately. */
231 return 0;
232 }
233
234 offset += block_size;
235 }
236
237 return 1;
238 }
239
240 /**
241 * \brief Check the DNP3 frame start bytes.
242 *
243 * \retval 1 if valid, 0 if not.
244 */
245 static int DNP3CheckStartBytes(const DNP3LinkHeader *header)
246 {
247 return header->start_byte0 == DNP3_START_BYTE0 &&
248 header->start_byte1 == DNP3_START_BYTE1;
249 }
250
251 /* Some DNP3 servers start with a banner. */
252 #define DNP3_BANNER "DNP3"
253
254 /**
255 * \brief Check if a frame contains a banner.
256 *
257 * Some servers (outstations) appear to send back a banner that fails
258 * the normal frame checks. So first check for a banner.
259 *
260 * \retval 1 if a banner is found, 0 if not.
261 */
262 static int DNP3ContainsBanner(const uint8_t *input, uint32_t len)
263 {
264 return BasicSearch(input, len, (uint8_t *)DNP3_BANNER, strlen(DNP3_BANNER)) != NULL;
265 }
266
267 /**
268 * \brief DNP3 probing parser.
269 */
270 static uint16_t DNP3ProbingParser(Flow *f, uint8_t direction,
271 const uint8_t *input, uint32_t len,
272 uint8_t *rdir)
273 {
274 const DNP3LinkHeader *const hdr = (const DNP3LinkHeader *)input;
275 const bool toserver = (direction & STREAM_TOSERVER) != 0;
276
277 /* May be a banner. */
278 if (DNP3ContainsBanner(input, len)) {
279 SCLogDebug("Packet contains a DNP3 banner.");
280 bool is_banner = true;
281 // magic 0x100 = 256 seems good enough
282 for (uint32_t i = 0; i < len && i < 0x100; i++) {
283 if (!isprint(input[i])) {
284 is_banner = false;
285 break;
286 }
287 }
288 if (is_banner) {
289 if (toserver) {
290 *rdir = STREAM_TOCLIENT;
291 }
292 return ALPROTO_DNP3;
293 }
294 }
295
296 /* Check that we have the minimum amount of bytes. */
297 if (len < sizeof(DNP3LinkHeader)) {
298 SCLogDebug("Length too small to be a DNP3 header.");
299 return ALPROTO_UNKNOWN;
300 }
301
302 /* Verify start value (from AN2013-004b). */
303 if (!DNP3CheckStartBytes(hdr)) {
304 SCLogDebug("Invalid start bytes.");
305 return ALPROTO_FAILED;
306 }
307
308 /* Verify minimum length. */
309 if (hdr->len < DNP3_MIN_LEN) {
310 SCLogDebug("Packet too small to be a valid DNP3 fragment.");
311 return ALPROTO_FAILED;
312 }
313
314 // Test compatibility between direction and dnp3.ctl.direction
315 if ((DNP3_LINK_DIR(hdr->control) != 0) != toserver) {
316 *rdir = toserver ? STREAM_TOCLIENT : STREAM_TOSERVER;
317 }
318 SCLogDebug("Detected DNP3.");
319 return ALPROTO_DNP3;
320 }
321
322 /**
323 * \brief Caculate the length of the transport layer with CRCs removed.
324 *
325 * \param input_len The length of the transport layer buffer.
326 *
327 * \retval The length of the buffer after CRCs are removed.
328 */
329 static int DNP3CalculateTransportLengthWithoutCRCs(uint32_t input_len)
330 {
331 /* Too small. */
332 if (input_len < DNP3_CRC_LEN) {
333 return -1;
334 }
335
336 /* Get the number of complete blocks. */
337 int blocks = input_len / (DNP3_BLOCK_SIZE + DNP3_CRC_LEN);
338
339 /* And the number of bytes in the last block. */
340 int rem = input_len - (blocks * (DNP3_BLOCK_SIZE + DNP3_CRC_LEN));
341
342 if (rem) {
343 if (rem < DNP3_CRC_LEN) {
344 return -1;
345 }
346 return (blocks * DNP3_BLOCK_SIZE) + (rem - DNP3_CRC_LEN);
347 }
348 else {
349 return (blocks * DNP3_BLOCK_SIZE);
350 }
351 }
352
353 /**
354 * \brief Reassemble the application layer by stripping the CRCs.
355 *
356 * Remove the CRCs from the user data blocks. The output is the user
357 * data with the CRCs removed as well as the transport header removed,
358 * but the input data still needs to include the transport header as
359 * its part of the first user data block.
360 *
361 * If the output length passed in is non-null, the new input data will
362 * be appended, and the output length pointer incremented as needed.
363 *
364 * \param input Input buffer starting at the transport header (which
365 * will be removed from the output).
366 * \param input_len Length of the input buffer.
367 * \param output Pointer to output buffer (may be realloc'd).
368 * \param output_len Pointer to output length.
369 *
370 * \retval 1 if reassembly was successful, otherwise 0.
371 */
372 static int DNP3ReassembleApplicationLayer(const uint8_t *input,
373 uint32_t input_len, uint8_t **output, uint32_t *output_len)
374 {
375 int len = DNP3CalculateTransportLengthWithoutCRCs(input_len);
376
377 if (len <= 0) {
378 return 0;
379 }
380
381 /* Remove one byte for the transport header and make sure we have
382 * at least one byte of user data. */
383 if (--len < 1) {
384 return 0;
385 }
386
387 if (*output == NULL) {
388 *output = SCCalloc(1, len);
389 if (unlikely(*output == NULL)) {
390 return 0;
391 }
392 }
393 else {
394 uint8_t *ptr = SCRealloc(*output, (size_t)(*output_len + len));
395 if (unlikely(ptr == NULL)) {
396 return 0;
397 }
398 *output = ptr;
399 }
400
401 int offset = 0, block_size;
402 while ((uint32_t)offset < input_len) {
403 if (input_len - offset > DNP3_BLOCK_SIZE + DNP3_CRC_LEN) {
404 block_size = DNP3_BLOCK_SIZE + DNP3_CRC_LEN;
405 }
406 else {
407 block_size = input_len - offset;
408 }
409
410 /* If handling the first block (offset is 0), trim off the
411 * first byte which is the transport header, and not part of
412 * the application data. */
413 if (offset == 0) {
414 offset++;
415 block_size--;
416 }
417
418 /* Need at least 3 bytes to continue. One for application
419 * data, and 2 for the CRC. If not, return failure for
420 * malformed frame. */
421 if (block_size < DNP3_CRC_LEN + 1) {
422 SCLogDebug("Not enough data to continue.");
423 return 0;
424 }
425
426 /* Make sure there is enough space to write into. */
427 if (block_size - DNP3_CRC_LEN > len) {
428 SCLogDebug("Not enough data to continue.");
429 return 0;
430 }
431
432 memcpy(*output + *output_len, input + offset,
433 block_size - DNP3_CRC_LEN);
434 *output_len += block_size - DNP3_CRC_LEN;
435 offset += block_size;
436 len -= block_size - DNP3_CRC_LEN;
437 }
438
439 return 1;
440 }
441
442 /**
443 * \brief Allocate a DNP3 state object.
444 *
445 * The DNP3 state object represents a single DNP3 TCP session.
446 */
447 static void *DNP3StateAlloc(void *orig_state, AppProto proto_orig)
448 {
449 SCEnter();
450 DNP3State *dnp3;
451
452 dnp3 = (DNP3State *)SCCalloc(1, sizeof(DNP3State));
453 if (unlikely(dnp3 == NULL)) {
454 return NULL;
455 }
456 TAILQ_INIT(&dnp3->tx_list);
457
458 SCReturnPtr(dnp3, "void");
459 }
460
461 /**
462 * \brief Set a DNP3 application layer event.
463 *
464 * Sets an event on the current transaction object.
465 */
466 static void DNP3SetEvent(DNP3State *dnp3, uint8_t event)
467 {
468 if (dnp3 && dnp3->curr) {
469 AppLayerDecoderEventsSetEventRaw(&dnp3->curr->tx_data.events, event);
470 dnp3->events++;
471 }
472 else {
473 SCLogWarning(SC_ERR_ALPARSER, "Failed to set event, state or tx pointer was NULL.");
474 }
475 }
476
477 /**
478 * \brief Set a DNP3 application layer event on a transaction.
479 */
480 static void DNP3SetEventTx(DNP3Transaction *tx, uint8_t event)
481 {
482 AppLayerDecoderEventsSetEventRaw(&tx->tx_data.events, event);
483 tx->dnp3->events++;
484 }
485
486 /**
487 * \brief Allocation a DNP3 transaction.
488 */
489 static DNP3Transaction *DNP3TxAlloc(DNP3State *dnp3)
490 {
491 DNP3Transaction *tx = SCCalloc(1, sizeof(DNP3Transaction));
492 if (unlikely(tx == NULL)) {
493 return NULL;
494 }
495 dnp3->transaction_max++;
496 dnp3->unreplied++;
497 dnp3->curr = tx;
498 tx->dnp3 = dnp3;
499 tx->tx_num = dnp3->transaction_max;
500 TAILQ_INIT(&tx->request_objects);
501 TAILQ_INIT(&tx->response_objects);
502 TAILQ_INSERT_TAIL(&dnp3->tx_list, tx, next);
503
504 /* Check for flood state. */
505 if (dnp3->unreplied > DNP3_DEFAULT_REQ_FLOOD_COUNT) {
506 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_FLOODED);
507 dnp3->flooded = 1;
508 }
509
510 return tx;
511 }
512
513 /**
514 * \brief Calculate the length of a link frame with CRCs.
515 *
516 * This is required as the length parameter in the DNP3 header does not
517 * include the added CRCs.
518 *
519 * \param length The length from the DNP3 link header.
520 *
521 * \retval The length of the frame with CRCs included or 0 if the length isn't
522 * long enough to be a valid DNP3 frame.
523 */
524 static uint32_t DNP3CalculateLinkLength(uint8_t length)
525 {
526 uint32_t frame_len = 0;
527 int rem;
528
529 /* Fail early if the length is less than the minimum size. */
530 if (length < DNP3_LINK_HDR_LEN) {
531 return 0;
532 }
533
534 /* Subtract the 5 bytes of the header that are included in the
535 * length. */
536 length -= DNP3_LINK_HDR_LEN;
537
538 rem = length % DNP3_BLOCK_SIZE;
539 frame_len = (length / DNP3_BLOCK_SIZE) * (DNP3_BLOCK_SIZE + DNP3_CRC_LEN);
540 if (rem) {
541 frame_len += rem + DNP3_CRC_LEN;
542 }
543
544 return frame_len + sizeof(DNP3LinkHeader);
545 }
546
547 /**
548 * \brief Check if the link function code specifies user data.
549 *
550 * \param header Point to link header.
551 *
552 * \retval 1 if frame contains user data, otherwise 0.
553 */
554 static int DNP3IsUserData(const DNP3LinkHeader *header)
555 {
556 switch (DNP3_LINK_FC(header->control)) {
557 case DNP3_LINK_FC_CONFIRMED_USER_DATA:
558 case DNP3_LINK_FC_UNCONFIRMED_USER_DATA:
559 return 1;
560 default:
561 return 0;
562 }
563 }
564
565 /**
566 * \brief Check if the frame has user data.
567 *
568 * Check if the DNP3 frame actually has user data by checking if data
569 * exists after the headers.
570 *
571 * \retval 1 if user data exists, otherwise 0.
572 */
573 static int DNP3HasUserData(const DNP3LinkHeader *header, uint8_t direction)
574 {
575 if (direction == STREAM_TOSERVER) {
576 return header->len >= DNP3_LINK_HDR_LEN + sizeof(DNP3TransportHeader) +
577 sizeof(DNP3ApplicationHeader);
578 }
579 else {
580 return header->len >= DNP3_LINK_HDR_LEN + sizeof(DNP3TransportHeader) +
581 sizeof(DNP3ApplicationHeader) + sizeof(DNP3InternalInd);
582 }
583 }
584
585 /**
586 * \brief Reset a DNP3Buffer.
587 */
588 static void DNP3BufferReset(DNP3Buffer *buffer)
589 {
590 buffer->offset = 0;
591 buffer->len = 0;
592 }
593
594 /**
595 * \brief Add data to a DNP3 buffer, enlarging the buffer if required.
596 *
597 * \param buffer Buffer to add data data.
598 * \param data Data to be added to buffer.
599 * \param len Size of data to be added to buffer.
600 *
601 * \param 1 if data was added successful, otherwise 0.
602 */
603 static int DNP3BufferAdd(DNP3Buffer *buffer, const uint8_t *data, uint32_t len)
604 {
605 if (buffer->size == 0) {
606 buffer->buffer = SCCalloc(1, len);
607 if (unlikely(buffer->buffer == NULL)) {
608 return 0;
609 }
610 buffer->size = len;
611 }
612 else if (buffer->len + len > buffer->size) {
613 uint8_t *tmp = SCRealloc(buffer->buffer, buffer->len + len);
614 if (unlikely(tmp == NULL)) {
615 return 0;
616 }
617 buffer->buffer = tmp;
618 buffer->size = buffer->len + len;
619 }
620 memcpy(buffer->buffer + buffer->len, data, len);
621 buffer->len += len;
622
623 return 1;
624 }
625
626 /**
627 * \brief Trim a DNP3 buffer.
628 *
629 * Trimming a buffer moves the data in the buffer up to the front of
630 * the buffer freeing up room at the end for more incoming data.
631 *
632 * \param buffer The buffer to trim.
633 */
634 static void DNP3BufferTrim(DNP3Buffer *buffer)
635 {
636 if (buffer->offset == buffer->len) {
637 DNP3BufferReset(buffer);
638 }
639 else if (buffer->offset > 0) {
640 memmove(buffer->buffer, buffer->buffer + buffer->offset,
641 buffer->len - buffer->offset);
642 buffer->len = buffer->len - buffer->offset;
643 buffer->offset = 0;
644 }
645 }
646
647 /**
648 * \brief Free a DNP3 object.
649 */
650 static void DNP3ObjectFree(DNP3Object *object)
651 {
652 if (object->points != NULL) {
653 DNP3FreeObjectPointList(object->group, object->variation,
654 object->points);
655 }
656 SCFree(object);
657 }
658
659 /**
660 * \breif Allocate a DNP3 object.
661 */
662 static DNP3Object *DNP3ObjectAlloc(void)
663 {
664 DNP3Object *object = SCCalloc(1, sizeof(*object));
665 if (unlikely(object == NULL)) {
666 return NULL;
667 }
668 object->points = DNP3PointListAlloc();
669 if (object->points == NULL) {
670 DNP3ObjectFree(object);
671 return NULL;
672 }
673 return object;
674 }
675
676 /**
677 * \brief Decode DNP3 application objects.
678 *
679 * This function decoded known DNP3 application objects. As the
680 * protocol isn't self describing, we can only decode the buffer while
681 * the application objects are known. As soon as an unknown
682 * group/variation is hit, we must stop processing.
683 *
684 * \param buf the input buffer
685 * \param len length of the input buffer
686 * \param objects pointer to list where decoded objects will be stored.
687 *
688 * \retval 1 if all objects decoded, 0 if all objects could not be decoded (
689 * unknown group/variations)
690 */
691 static int DNP3DecodeApplicationObjects(DNP3Transaction *tx, const uint8_t *buf,
692 uint32_t len, DNP3ObjectList *objects)
693 {
694 int retval = 0;
695
696 if (buf == NULL || len == 0) {
697 return 1;
698 }
699
700 while (len) {
701 uint32_t offset = 0;
702
703 if (len < sizeof(DNP3ObjHeader)) {
704 goto done;
705 }
706 DNP3ObjHeader *header = (DNP3ObjHeader *)buf;
707 offset += sizeof(DNP3ObjHeader);
708
709 DNP3Object *object = DNP3ObjectAlloc();
710 if (unlikely(object == NULL)) {
711 goto done;
712 }
713 TAILQ_INSERT_TAIL(objects, object, next);
714
715 object->group = header->group;
716 object->variation = header->variation;
717 object->qualifier = header->qualifier;
718 object->prefix_code = DNP3_OBJ_PREFIX(header->qualifier);
719 object->range_code = DNP3_OBJ_RANGE(header->qualifier);
720
721 /* IEEE 1815-2012, Table 4-5. */
722 switch (object->range_code) {
723 case 0x00:
724 case 0x03: {
725 /* 1 octet start and stop indexes OR 1 octet start and
726 * stop virtual addresses. */
727 if (offset + (sizeof(uint8_t) * 2) > len) {
728 /* Not enough data. */
729 SCLogDebug("Not enough data.");
730 goto not_enough_data;
731 }
732 object->start = buf[offset++];
733 object->stop = buf[offset++];
734 object->count = object->stop - object->start + 1;
735 break;
736 }
737 case 0x01:
738 case 0x04: {
739 /* 2 octet start and stop indexes OR 2 octect start
740 * and stop virtual addresses. */
741 if (offset + (sizeof(uint16_t) * 2) > len) {
742 /* Not enough data. */
743 SCLogDebug("Not enough data.");
744 goto not_enough_data;
745 }
746 object->start = DNP3_SWAP16(*(uint16_t *)(buf + offset));
747 offset += sizeof(uint16_t);
748 object->stop = DNP3_SWAP16(*(uint16_t *)(buf + offset));
749 offset += sizeof(uint16_t);
750 object->count = object->stop - object->start + 1;
751 break;
752 }
753 case 0x02:
754 case 0x05: {
755 /* 4 octet start and stop indexes OR 4 octect start
756 * and stop virtual addresses. */
757 if (offset + (sizeof(uint32_t) * 2) > len) {
758 /* Not enough data. */
759 SCLogDebug("Not enough data.");
760 goto not_enough_data;
761 }
762 object->start = DNP3_SWAP32(*(uint32_t *)(buf + offset));
763 offset += sizeof(uint32_t);
764 object->stop = DNP3_SWAP32(*(uint32_t *)(buf + offset));
765 offset += sizeof(uint32_t);
766 object->count = object->stop - object->start + 1;
767 break;
768 }
769 case 0x06:
770 /* No range field. */
771 object->count = 0;
772 break;
773 case 0x07:
774 /* 1 octet count of objects. */
775 if (offset + sizeof(uint8_t) > len) {
776 SCLogDebug("Not enough data.");
777 goto not_enough_data;
778 }
779 object->count = buf[offset];
780 offset += sizeof(uint8_t);
781 break;
782 case 0x08: {
783 /* 2 octet count of objects. */
784 if (offset + sizeof(uint16_t) > len) {
785 SCLogDebug("Not enough data.");
786 goto not_enough_data;
787 }
788 object->count = DNP3_SWAP16(*(uint16_t *)(buf + offset));
789 offset += sizeof(uint16_t);
790 break;
791 }
792 case 0x09: {
793 /* 4 octet count of objects. */
794 if (offset + sizeof(uint32_t) > len) {
795 SCLogDebug("Not enough data.");
796 goto not_enough_data;
797 }
798 object->count = DNP3_SWAP32(*(uint32_t *)(buf + offset));
799 offset += sizeof(uint32_t);
800 break;
801 }
802 case 0x0b: {
803 if (offset + sizeof(uint8_t) > len) {
804 /* Not enough data. */
805 SCLogDebug("Not enough data.");
806 goto not_enough_data;
807 }
808 object->count = *(uint8_t *)(buf + offset);
809 offset += sizeof(uint8_t);
810 break;
811 }
812 default:
813 SCLogDebug("Range code 0x%02x is reserved.",
814 object->range_code);
815 goto done;
816 }
817
818 buf += offset;
819 len -= offset;
820
821 if (object->variation == 0 || object->count == 0) {
822 goto next;
823 }
824
825 int event = DNP3DecodeObject(header->group, header->variation, &buf,
826 &len, object->prefix_code, object->start, object->count,
827 object->points);
828 if (event) {
829 DNP3SetEventTx(tx, DNP3_DECODER_EVENT_UNKNOWN_OBJECT);
830 goto done;
831 }
832
833 next:
834 continue;
835 }
836
837 /* All objects were decoded. */
838 retval = 1;
839
840 not_enough_data:
841 done:
842 return retval;
843 }
844
845 /**
846 * \brief Handle DNP3 request user data.
847 *
848 * \param dnp3 the current DNP3State
849 * \param input pointer to the DNP3 frame (starting with link header)
850 * \param input_len length of the input frame
851 */
852 static void DNP3HandleUserDataRequest(DNP3State *dnp3, const uint8_t *input,
853 uint32_t input_len)
854 {
855 DNP3LinkHeader *lh;
856 DNP3TransportHeader th;
857 DNP3ApplicationHeader *ah;
858 DNP3Transaction *tx = NULL, *ttx;
859
860 lh = (DNP3LinkHeader *)input;
861
862 if (!DNP3CheckUserDataCRCs(input + sizeof(DNP3LinkHeader),
863 input_len - sizeof(DNP3LinkHeader))) {
864 return;
865 }
866
867 th = input[sizeof(DNP3LinkHeader)];
868
869 if (!DNP3_TH_FIR(th)) {
870 TAILQ_FOREACH(ttx, &dnp3->tx_list, next) {
871 if (ttx->request_lh.src == lh->src &&
872 ttx->request_lh.dst == lh->dst &&
873 ttx->has_request &&
874 !ttx->request_done &&
875 NEXT_TH_SEQNO(DNP3_TH_SEQ(ttx->request_th)) == DNP3_TH_SEQ(th))
876 {
877 tx = ttx;
878 break;
879 }
880 }
881
882 if (tx == NULL) {
883 return;
884 }
885
886 /* Update the saved transport header so subsequent segments
887 * will be matched to this sequence number. */
888 tx->response_th = th;
889 }
890 else {
891 ah = (DNP3ApplicationHeader *)(input + sizeof(DNP3LinkHeader) +
892 sizeof(DNP3TransportHeader));
893
894 /* Ignore confirms - for now. */
895 if (ah->function_code == DNP3_APP_FC_CONFIRM) {
896 return;
897 }
898
899 /* Create a transaction. */
900 tx = DNP3TxAlloc(dnp3);
901 if (unlikely(tx == NULL)) {
902 return;
903 }
904 tx->request_lh = *lh;
905 tx->request_th = th;
906 tx->request_ah = *ah;
907 tx->has_request = 1;
908
909 }
910
911 if (!DNP3ReassembleApplicationLayer(input + sizeof(DNP3LinkHeader),
912 input_len - sizeof(DNP3LinkHeader),
913 &tx->request_buffer, &tx->request_buffer_len)) {
914
915 /* Malformed, set event and mark as done. */
916 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_MALFORMED);
917 tx->request_done = 1;
918 return;
919 }
920
921 /* If this is not the final segment, just return. */
922 if (!DNP3_TH_FIN(th)) {
923 return;
924 }
925
926 tx->request_done = 1;
927
928 /* Some function codes do not expect a reply. */
929 switch (tx->request_ah.function_code) {
930 case DNP3_APP_FC_CONFIRM:
931 case DNP3_APP_FC_DIR_OPERATE_NR:
932 case DNP3_APP_FC_FREEZE_NR:
933 case DNP3_APP_FC_FREEZE_CLEAR_NR:
934 case DNP3_APP_FC_FREEZE_AT_TIME_NR:
935 case DNP3_APP_FC_AUTH_REQ_NR:
936 tx->response_done = 1;
937 default:
938 break;
939 }
940
941 if (DNP3DecodeApplicationObjects(
942 tx, tx->request_buffer + sizeof(DNP3ApplicationHeader),
943 tx->request_buffer_len - sizeof(DNP3ApplicationHeader),
944 &tx->request_objects)) {
945 tx->request_complete = 1;
946 }
947 }
948
949 static void DNP3HandleUserDataResponse(DNP3State *dnp3, const uint8_t *input,
950 uint32_t input_len)
951 {
952 DNP3LinkHeader *lh;
953 DNP3TransportHeader th;
954 DNP3ApplicationHeader *ah;
955 DNP3InternalInd *iin;
956 DNP3Transaction *tx = NULL, *ttx;
957 uint32_t offset = 0;
958
959 lh = (DNP3LinkHeader *)input;
960 offset += sizeof(DNP3LinkHeader);
961
962 if (!DNP3CheckUserDataCRCs(input + offset, input_len - offset)) {
963 return;
964 }
965
966 th = input[offset++];
967
968 if (!DNP3_TH_FIR(th)) {
969 TAILQ_FOREACH(ttx, &dnp3->tx_list, next) {
970 if (ttx->response_lh.src == lh->src &&
971 ttx->response_lh.dst == lh->dst &&
972 ttx->has_response && !ttx->response_done &&
973 NEXT_TH_SEQNO(DNP3_TH_SEQ(ttx->response_th)) == DNP3_TH_SEQ(th))
974 {
975 tx = ttx;
976 break;
977 }
978 }
979
980 if (tx == NULL) {
981 return;
982 }
983
984 /* Replace the transport header in the transaction with this
985 * one in case there are more frames. */
986 tx->response_th = th;
987 }
988 else {
989 ah = (DNP3ApplicationHeader *)(input + offset);
990 offset += sizeof(DNP3ApplicationHeader);
991 iin = (DNP3InternalInd *)(input + offset);
992
993 if (ah->function_code == DNP3_APP_FC_UNSOLICITED_RESP) {
994 tx = DNP3TxAlloc(dnp3);
995 if (unlikely(tx == NULL)) {
996 return;
997 }
998
999 /* There is no request associated with an unsolicited
1000 * response, so mark the request done as far as
1001 * transaction state handling is concerned. */
1002 tx->request_done = 1;
1003 }
1004 else {
1005 /* Find transaction. */
1006 TAILQ_FOREACH(ttx, &dnp3->tx_list, next) {
1007 if (ttx->has_request &&
1008 ttx->request_done &&
1009 ttx->request_lh.src == lh->dst &&
1010 ttx->request_lh.dst == lh->src &&
1011 !ttx->has_response &&
1012 !ttx->response_done &&
1013 DNP3_APP_SEQ(ttx->request_ah.control) == DNP3_APP_SEQ(ah->control)) {
1014 tx = ttx;
1015 break;
1016 }
1017 }
1018 if (tx == NULL) {
1019 return;
1020 }
1021 }
1022
1023 tx->has_response = 1;
1024 tx->response_lh = *lh;
1025 tx->response_th = th;
1026 tx->response_ah = *ah;
1027 tx->response_iin = *iin;
1028 }
1029
1030 if (!DNP3ReassembleApplicationLayer(input + sizeof(DNP3LinkHeader),
1031 input_len - sizeof(DNP3LinkHeader),
1032 &tx->response_buffer, &tx->response_buffer_len)) {
1033 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_MALFORMED);
1034 return;
1035 }
1036
1037 if (!DNP3_TH_FIN(th)) {
1038 return;
1039 }
1040
1041 tx->response_done = 1;
1042
1043 offset = sizeof(DNP3ApplicationHeader) + sizeof(DNP3InternalInd);
1044 if (DNP3DecodeApplicationObjects(tx, tx->response_buffer + offset,
1045 tx->response_buffer_len - offset,
1046 &tx->response_objects)) {
1047 tx->response_complete = 1;
1048 }
1049 }
1050
1051 /**
1052 * \brief Decode the DNP3 request link layer.
1053 *
1054 * \retval number of bytes processed or -1 if the data stream does not look
1055 * like DNP3.
1056 */
1057 static int DNP3HandleRequestLinkLayer(DNP3State *dnp3, const uint8_t *input,
1058 uint32_t input_len)
1059 {
1060 SCEnter();
1061 uint32_t processed = 0;
1062
1063 while (input_len) {
1064
1065 /* Need at least enough bytes for a DNP3 header. */
1066 if (input_len < sizeof(DNP3LinkHeader)) {
1067 break;
1068 }
1069
1070 DNP3LinkHeader *header = (DNP3LinkHeader *)input;
1071
1072 if (!DNP3CheckStartBytes(header)) {
1073 goto error;
1074 }
1075
1076 if (!DNP3CheckLinkHeaderCRC(header)) {
1077 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_BAD_LINK_CRC);
1078 goto error;
1079 }
1080
1081 uint32_t frame_len = DNP3CalculateLinkLength(header->len);
1082 if (frame_len == 0) {
1083 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_LEN_TOO_SMALL);
1084 goto error;
1085 }
1086 if (input_len < frame_len) {
1087 /* Insufficient data, just break - will wait for more data. */
1088 break;
1089 }
1090
1091 /* Ignore non-user data for now. */
1092 if (!DNP3IsUserData(header)) {
1093 goto next;
1094 }
1095
1096 /* Make sure the header length is large enough for transport and
1097 * application headers. */
1098 if (!DNP3HasUserData(header, STREAM_TOSERVER)) {
1099 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_LEN_TOO_SMALL);
1100 goto next;
1101 }
1102
1103 if (!DNP3CheckUserDataCRCs(input + sizeof(DNP3LinkHeader),
1104 frame_len - sizeof(DNP3LinkHeader))) {
1105 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC);
1106 goto next;
1107 }
1108
1109 DNP3HandleUserDataRequest(dnp3, input, frame_len);
1110
1111 next:
1112 /* Advance the input buffer. */
1113 input += frame_len;
1114 input_len -= frame_len;
1115 processed += frame_len;
1116 }
1117
1118 SCReturnInt(processed);
1119 error:
1120 /* Error out. Should only happen if this doesn't look like a DNP3
1121 * frame. */
1122 SCReturnInt(-1);
1123 }
1124
1125 /**
1126 * \brief Handle incoming request data.
1127 *
1128 * The actual request PDU parsing is done in
1129 * DNP3HandleRequestLinkLayer. This function takes care of buffering TCP
1130 * date if a segment does not contain a complete frame (or contains
1131 * multiple frames, but not the complete final frame).
1132 */
1133 static AppLayerResult DNP3ParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
1134 const uint8_t *input, uint32_t input_len, void *local_data,
1135 const uint8_t flags)
1136 {
1137 SCEnter();
1138 DNP3State *dnp3 = (DNP3State *)state;
1139 DNP3Buffer *buffer = &dnp3->request_buffer;
1140 int processed = 0;
1141
1142 if (input_len == 0) {
1143 SCReturnStruct(APP_LAYER_OK);
1144 }
1145
1146 if (buffer->len) {
1147 if (!DNP3BufferAdd(buffer, input, input_len)) {
1148 SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory to buffer "
1149 "DNP3 request data");
1150 goto error;
1151 }
1152 processed = DNP3HandleRequestLinkLayer(dnp3,
1153 buffer->buffer + buffer->offset,
1154 buffer->len - buffer->offset);
1155 if (processed < 0) {
1156 goto error;
1157 }
1158 buffer->offset += processed;
1159 DNP3BufferTrim(buffer);
1160 }
1161 else {
1162 processed = DNP3HandleRequestLinkLayer(dnp3, input, input_len);
1163 if (processed < 0) {
1164 SCLogDebug("Failed to process request link layer.");
1165 goto error;
1166 }
1167
1168 input += processed;
1169 input_len -= processed;
1170
1171 /* Not all data was processed, buffer it. */
1172 if (input_len) {
1173 if (!DNP3BufferAdd(buffer, input, input_len)) {
1174 SCLogError(SC_ERR_MEM_ALLOC,
1175 "Failed to allocate memory to buffer DNP3 request data");
1176 goto error;
1177 }
1178 }
1179 }
1180
1181 SCReturnStruct(APP_LAYER_OK);
1182
1183 error:
1184 /* Reset the buffer. */
1185 DNP3BufferReset(buffer);
1186 SCReturnStruct(APP_LAYER_ERROR);
1187 }
1188
1189 /**
1190 * \brief Decode the DNP3 response link layer.
1191 *
1192 * \retval number of bytes processed or -1 if the data stream does not
1193 * like look DNP3.
1194 */
1195 static int DNP3HandleResponseLinkLayer(DNP3State *dnp3, const uint8_t *input,
1196 uint32_t input_len)
1197 {
1198 SCEnter();
1199 uint32_t processed = 0;
1200
1201 while (input_len) {
1202
1203 /* Need at least enough bytes for a DNP3 header. */
1204 if (input_len < sizeof(DNP3LinkHeader)) {
1205 break;
1206 }
1207
1208 DNP3LinkHeader *header = (DNP3LinkHeader *)input;
1209
1210 if (!DNP3CheckStartBytes(header)) {
1211 goto error;
1212 }
1213
1214 if (!DNP3CheckLinkHeaderCRC(header)) {
1215 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_BAD_LINK_CRC);
1216 goto error;
1217 }
1218
1219 /* Calculate the number of bytes needed to for this frame. */
1220 uint32_t frame_len = DNP3CalculateLinkLength(header->len);
1221 if (frame_len == 0) {
1222 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_LEN_TOO_SMALL);
1223 goto error;
1224 }
1225 if (input_len < frame_len) {
1226 /* Insufficient data, just break - will wait for more data. */
1227 break;
1228 }
1229
1230 /* Only handle user data frames for now. */
1231 if (!DNP3IsUserData(header)) {
1232 goto next;
1233 }
1234
1235 /* Make sure the header length is large enough for transport and
1236 * application headers. */
1237 if (!DNP3HasUserData(header, STREAM_TOCLIENT)) {
1238 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_LEN_TOO_SMALL);
1239 goto error;
1240 }
1241
1242 if (!DNP3CheckUserDataCRCs(input + sizeof(DNP3LinkHeader),
1243 frame_len - sizeof(DNP3LinkHeader))) {
1244 DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC);
1245 goto next;
1246 }
1247
1248 DNP3HandleUserDataResponse(dnp3, input, frame_len);
1249
1250 next:
1251 /* Advance the input buffer. */
1252 input += frame_len;
1253 input_len -= frame_len;
1254 processed += frame_len;
1255 }
1256
1257 SCReturnInt(processed);
1258 error:
1259 /* Error out. Should only happen if the data stream no longer
1260 * looks like DNP3. */
1261 SCReturnInt(-1);
1262 }
1263
1264 /**
1265 * \brief Parse incoming data.
1266 *
1267 * This is the entry function for DNP3 application layer data. Its
1268 * main responsibility is buffering incoming data that cannot be
1269 * processed.
1270 *
1271 * See DNP3ParseResponsePDUs for DNP3 frame handling.
1272 */
1273 static AppLayerResult DNP3ParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
1274 const uint8_t *input, uint32_t input_len, void *local_data,
1275 const uint8_t flags)
1276 {
1277 SCEnter();
1278
1279 DNP3State *dnp3 = (DNP3State *)state;
1280 DNP3Buffer *buffer = &dnp3->response_buffer;
1281 int processed;
1282
1283 if (buffer->len) {
1284 if (!DNP3BufferAdd(buffer, input, input_len)) {
1285 SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory to buffer "
1286 "DNP3 response data");
1287 goto error;
1288 }
1289 processed = DNP3HandleResponseLinkLayer(dnp3,
1290 buffer->buffer + buffer->offset,
1291 buffer->len - buffer->offset);
1292 if (processed < 0) {
1293 goto error;
1294 }
1295 buffer->offset += processed;
1296 DNP3BufferTrim(buffer);
1297 }
1298 else {
1299
1300 /* Check if this is a banner, ignore if it is. */
1301 if (DNP3ContainsBanner(input, input_len)) {
1302 goto done;
1303 }
1304
1305 processed = DNP3HandleResponseLinkLayer(dnp3, input, input_len);
1306 if (processed < 0) {
1307 goto error;
1308 }
1309 input += processed;
1310 input_len -= processed;
1311
1312 /* Not all data was processed, buffer it. */
1313 if (input_len) {
1314 if (!DNP3BufferAdd(buffer, input, input_len)) {
1315 SCLogError(SC_ERR_MEM_ALLOC,
1316 "Failed to allocate memory to buffer DNP3 response data");
1317 goto error;
1318 }
1319 }
1320 }
1321
1322 done:
1323 SCReturnStruct(APP_LAYER_OK);
1324
1325 error:
1326 /* An error occurred while processing DNP3 frames. Dump the
1327 * buffer as we can't be assured that they are valid anymore. */
1328 DNP3BufferReset(buffer);
1329 SCReturnStruct(APP_LAYER_ERROR);
1330 }
1331
1332 static void *DNP3GetTx(void *alstate, uint64_t tx_id)
1333 {
1334 SCEnter();
1335 DNP3State *dnp3 = (DNP3State *)alstate;
1336 DNP3Transaction *tx = NULL;
1337 uint64_t tx_num = tx_id + 1;
1338
1339 if (dnp3->curr && dnp3->curr->tx_num == (tx_num)) {
1340 SCReturnPtr(dnp3->curr, "void");
1341 }
1342
1343 TAILQ_FOREACH(tx, &dnp3->tx_list, next) {
1344 if (tx_num != tx->tx_num) {
1345 continue;
1346 }
1347 SCReturnPtr(tx, "void");
1348 }
1349
1350 SCReturnPtr(NULL, "void");
1351 }
1352
1353 static uint64_t DNP3GetTxCnt(void *state)
1354 {
1355 SCEnter();
1356 uint64_t count = ((uint64_t)((DNP3State *)state)->transaction_max);
1357 SCReturnUInt(count);
1358 }
1359
1360 /**
1361 * \brief Free all the objects in a DNP3ObjectList.
1362 */
1363 static void DNP3TxFreeObjectList(DNP3ObjectList *objects)
1364 {
1365 DNP3Object *object;
1366
1367 while ((object = TAILQ_FIRST(objects)) != NULL) {
1368 TAILQ_REMOVE(objects, object, next);
1369 DNP3ObjectFree(object);
1370 }
1371 }
1372
1373 /**
1374 * \brief Free a DNP3 transaction.
1375 */
1376 static void DNP3TxFree(DNP3Transaction *tx)
1377 {
1378 SCEnter();
1379
1380 if (tx->request_buffer != NULL) {
1381 SCFree(tx->request_buffer);
1382 }
1383
1384 if (tx->response_buffer != NULL) {
1385 SCFree(tx->response_buffer);
1386 }
1387
1388 AppLayerDecoderEventsFreeEvents(&tx->tx_data.events);
1389
1390 if (tx->tx_data.de_state != NULL) {
1391 DetectEngineStateFree(tx->tx_data.de_state);
1392 }
1393
1394 DNP3TxFreeObjectList(&tx->request_objects);
1395 DNP3TxFreeObjectList(&tx->response_objects);
1396
1397 SCFree(tx);
1398 SCReturn;
1399 }
1400
1401 /**
1402 * \brief Free a transaction by ID on a specific DNP3 state.
1403 *
1404 * This function is called by the app-layer to free a transaction on a
1405 * specific DNP3 state object.
1406 */
1407 static void DNP3StateTxFree(void *state, uint64_t tx_id)
1408 {
1409 SCEnter();
1410 DNP3State *dnp3 = state;
1411 DNP3Transaction *tx = NULL, *ttx;
1412 uint64_t tx_num = tx_id + 1;
1413
1414 TAILQ_FOREACH_SAFE(tx, &dnp3->tx_list, next, ttx) {
1415
1416 if (tx->tx_num != tx_num) {
1417 continue;
1418 }
1419
1420 if (tx == dnp3->curr) {
1421 dnp3->curr = NULL;
1422 }
1423
1424 if (tx->tx_data.events != NULL) {
1425 if (tx->tx_data.events->cnt <= dnp3->events) {
1426 dnp3->events -= tx->tx_data.events->cnt;
1427 } else {
1428 dnp3->events = 0;
1429 }
1430 }
1431 dnp3->unreplied--;
1432
1433 /* Check flood state. */
1434 if (dnp3->flooded && dnp3->unreplied < DNP3_DEFAULT_REQ_FLOOD_COUNT) {
1435 dnp3->flooded = 0;
1436 }
1437
1438 TAILQ_REMOVE(&dnp3->tx_list, tx, next);
1439 DNP3TxFree(tx);
1440 break;
1441 }
1442
1443 SCReturn;
1444 }
1445
1446 /**
1447 * \brief Free a DNP3 state.
1448 */
1449 static void DNP3StateFree(void *state)
1450 {
1451 SCEnter();
1452 DNP3State *dnp3 = state;
1453 DNP3Transaction *tx;
1454 if (state != NULL) {
1455 while ((tx = TAILQ_FIRST(&dnp3->tx_list)) != NULL) {
1456 TAILQ_REMOVE(&dnp3->tx_list, tx, next);
1457 DNP3TxFree(tx);
1458 }
1459 if (dnp3->request_buffer.buffer != NULL) {
1460 SCFree(dnp3->request_buffer.buffer);
1461 }
1462 if (dnp3->response_buffer.buffer != NULL) {
1463 SCFree(dnp3->response_buffer.buffer);
1464 }
1465 SCFree(dnp3);
1466 }
1467 SCReturn;
1468 }
1469
1470 /**
1471 * \brief Called by the app-layer to get the state progress.
1472 */
1473 static int DNP3GetAlstateProgress(void *tx, uint8_t direction)
1474 {
1475 DNP3Transaction *dnp3tx = (DNP3Transaction *)tx;
1476 DNP3State *dnp3 = dnp3tx->dnp3;
1477 int retval = 0;
1478
1479 /* If flooded, "ack" old transactions. */
1480 if (dnp3->flooded && (dnp3->transaction_max -
1481 dnp3tx->tx_num >= DNP3_DEFAULT_REQ_FLOOD_COUNT)) {
1482 SCLogDebug("flooded: returning tx as done.");
1483 SCReturnInt(1);
1484 }
1485
1486 if (direction & STREAM_TOCLIENT && dnp3tx->response_done) {
1487 retval = 1;
1488 }
1489 else if (direction & STREAM_TOSERVER && dnp3tx->request_done) {
1490 retval = 1;
1491 }
1492
1493 SCReturnInt(retval);
1494 }
1495
1496 /**
1497 * \brief App-layer support.
1498 */
1499 static int DNP3StateGetEventInfo(const char *event_name, int *event_id,
1500 AppLayerEventType *event_type)
1501 {
1502 *event_id = SCMapEnumNameToValue(event_name, dnp3_decoder_event_table);
1503 if (*event_id == -1) {
1504 SCLogError(SC_ERR_INVALID_ENUM_MAP, "Event \"%s\" not present in "
1505 "the DNP3 enum event map table.", event_name);
1506 return -1;
1507 }
1508
1509 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
1510
1511 return 0;
1512 }
1513
1514 /**
1515 * \brief App-layer support.
1516 */
1517 static int DNP3StateGetEventInfoById(int event_id, const char **event_name,
1518 AppLayerEventType *event_type)
1519 {
1520 *event_name = SCMapEnumValueToName(event_id, dnp3_decoder_event_table);
1521 if (*event_name == NULL) {
1522 SCLogError(SC_ERR_INVALID_ENUM_MAP, "Event \"%d\" not present in "
1523 "the DNP3 enum event map table.", event_id);
1524 return -1;
1525 }
1526
1527 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
1528
1529 return 0;
1530 }
1531
1532 static AppLayerTxData *DNP3GetTxData(void *vtx)
1533 {
1534 DNP3Transaction *tx = (DNP3Transaction *)vtx;
1535 return &tx->tx_data;
1536 }
1537
1538 /**
1539 * \brief Check if the prefix code is a size prefix.
1540 *
1541 * \retval 1 if the prefix_code specifies a size prefix, 0 if not.
1542 */
1543 int DNP3PrefixIsSize(uint8_t prefix_code)
1544 {
1545 switch (prefix_code) {
1546 case 0x04:
1547 case 0x05:
1548 case 0x06:
1549 return 1;
1550 break;
1551 default:
1552 return 0;
1553 }
1554 }
1555
1556 /**
1557 * \brief Register the DNP3 application protocol parser.
1558 */
1559 void RegisterDNP3Parsers(void)
1560 {
1561 SCEnter();
1562
1563 const char *proto_name = "dnp3";
1564
1565 if (AppLayerProtoDetectConfProtoDetectionEnabledDefault("tcp", proto_name, false)) {
1566 AppLayerProtoDetectRegisterProtocol(ALPROTO_DNP3, proto_name);
1567
1568 if (RunmodeIsUnittests()) {
1569 AppLayerProtoDetectPPRegister(IPPROTO_TCP, DNP3_DEFAULT_PORT,
1570 ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader), STREAM_TOSERVER,
1571 DNP3ProbingParser, DNP3ProbingParser);
1572 }
1573 else {
1574 if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
1575 proto_name, ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader),
1576 DNP3ProbingParser, DNP3ProbingParser)) {
1577 return;
1578 }
1579 }
1580
1581 } else {
1582 SCLogConfig("Protocol detection and parser disabled for DNP3.");
1583 SCReturn;
1584 }
1585
1586 if (AppLayerParserConfParserEnabled("tcp", proto_name))
1587 {
1588 SCLogConfig("Registering DNP3/tcp parsers.");
1589
1590 AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DNP3, STREAM_TOSERVER,
1591 DNP3ParseRequest);
1592 AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DNP3, STREAM_TOCLIENT,
1593 DNP3ParseResponse);
1594
1595 AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DNP3,
1596 DNP3StateAlloc, DNP3StateFree);
1597
1598 AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTx);
1599 AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxCnt);
1600 AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_DNP3,
1601 DNP3StateTxFree);
1602
1603 AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_DNP3,
1604 DNP3GetAlstateProgress);
1605 AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_DNP3, 1, 1);
1606
1607 AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_DNP3,
1608 DNP3StateGetEventInfo);
1609 AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_DNP3,
1610 DNP3StateGetEventInfoById);
1611
1612 AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_DNP3,
1613 DNP3GetTxData);
1614 }
1615 else {
1616 SCLogConfig("Parser disabled for protocol %s. "
1617 "Protocol detection still on.", proto_name);
1618 }
1619
1620 #ifdef UNITTESTS
1621 AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_DNP3,
1622 DNP3ParserRegisterTests);
1623 #endif
1624
1625 SCReturn;
1626 }
1627
1628 #ifdef UNITTESTS
1629
1630 #include "flow-util.h"
1631 #include "stream-tcp.h"
1632
1633 /**
1634 * \brief Utility function to fix CRCs when mangling a frame.
1635 */
1636 static void DNP3FixCrc(uint8_t *data, uint32_t len)
1637 {
1638 uint32_t block_size;
1639
1640 while (len) {
1641 if (len >= DNP3_BLOCK_SIZE + DNP3_CRC_LEN) {
1642 block_size = DNP3_BLOCK_SIZE;
1643 } else {
1644 block_size = len - DNP3_CRC_LEN;
1645 }
1646 uint16_t crc = DNP3ComputeCRC(data, block_size);
1647 data[block_size + 1] = (crc >> 8) & 0xff;
1648 data[block_size] = crc & 0xff;
1649 data += block_size + DNP3_CRC_LEN;
1650 len -= block_size + DNP3_CRC_LEN;
1651 }
1652 }
1653
1654 /**
1655 * \test Test CRC checking on partial and full blocks.
1656 */
1657 static int DNP3ParserTestCheckCRC(void)
1658 {
1659 uint8_t request[] = {
1660 /* DNP3 start. */
1661 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
1662 0xa5, 0xe9,
1663
1664 /* Transport header. */
1665 0xff,
1666
1667 /* Application layer - segment 1. */
1668 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
1669 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
1670 0xef,
1671
1672 /* Application layer - segment 2. */
1673 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
1674 };
1675
1676 /* Check link header CRC. */
1677 FAIL_IF(!DNP3CheckCRC(request, sizeof(DNP3LinkHeader)));
1678
1679 /* Check first application layer segment. */
1680 FAIL_IF(!DNP3CheckCRC(request + sizeof(DNP3LinkHeader),
1681 DNP3_BLOCK_SIZE + DNP3_CRC_LEN));
1682
1683 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1684 /* Change a byte in link header, should fail now. */
1685 request[2]++;
1686 FAIL_IF(DNP3CheckCRC(request, sizeof(DNP3LinkHeader)));
1687
1688 /* Change a byte in the first application segment, should fail
1689 * now. */
1690 request[sizeof(DNP3LinkHeader) + 3]++;
1691 FAIL_IF(DNP3CheckCRC(request + sizeof(DNP3LinkHeader),
1692 DNP3_BLOCK_SIZE + DNP3_CRC_LEN));
1693 #endif
1694
1695 PASS;
1696 }
1697
1698 /**
1699 * \test Test validation of all CRCs in user data.
1700 */
1701 static int DNP3CheckUserDataCRCsTest(void)
1702 {
1703 /* Multi-block data with valid CRCs. */
1704 uint8_t data_valid[] = {
1705 0xff, 0xc9, 0x05, 0x0c,
1706 0x01, 0x28, 0x01, 0x00,
1707 0x00, 0x00, 0x01, 0x01,
1708 0x01, 0x00, 0x00, 0x00,
1709 0x72, 0xef, /* CRC. */
1710
1711 0xff, 0xc9, 0x05, 0x0c,
1712 0x01, 0x28, 0x01, 0x00,
1713 0x00, 0x00, 0x01, 0x01,
1714 0x01, 0x00, 0x00, 0x00,
1715 0x72, 0xef, /* CRC. */
1716
1717 0xff, 0xc9, 0x05, 0x0c,
1718 0x01, 0x28, 0x01, 0x00,
1719 0x00, 0x00, 0x01, 0x01,
1720 0x01, 0x00, 0x00, 0x00,
1721 0x72, 0xef, /* CRC. */
1722
1723 0x00, 0x00, 0x00, 0x00,
1724 0x00,
1725 0xff, 0xff, /* CRC. */
1726 };
1727 FAIL_IF(!DNP3CheckUserDataCRCs(data_valid, sizeof(data_valid)));
1728
1729 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1730 /* Multi-block data with one non-crc byte altered. */
1731 uint8_t data_invalid[] = {
1732 0xff, 0xc9, 0x05, 0x0c,
1733 0x01, 0x28, 0x01, 0x00,
1734 0x00, 0x00, 0x01, 0x01,
1735 0x01, 0x00, 0x00, 0x00,
1736 0x72, 0xef, /* CRC. */
1737
1738 0xff, 0xc9, 0x05, 0x0c,
1739 0x01, 0x28, 0x01, 0x00,
1740 0x00, 0x00, 0x01, 0x01,
1741 0x01, 0x00, 0x00, 0x00,
1742 0x72, 0xef, /* CRC. */
1743
1744 0xff, 0xc9, 0x05, 0x0c,
1745 0x01, 0x28, 0x01, 0x00,
1746 0x00, 0x00, 0x01, 0x01,
1747 0x01, 0x00, 0x00, 0x00,
1748 0x72, 0xef, /* CRC. */
1749
1750 0x00, 0x00, 0x00, 0x00,
1751 0x01, /* Invalid byte. */
1752 0xff, 0xff, /* CRC. */
1753 };
1754 FAIL_IF(DNP3CheckUserDataCRCs(data_invalid, sizeof(data_invalid)));
1755
1756 /* 1 byte - need at least 3. */
1757 uint8_t one_byte_nocrc[] = { 0x01 };
1758 FAIL_IF(DNP3CheckUserDataCRCs(one_byte_nocrc, sizeof(one_byte_nocrc)));
1759
1760 /* 2 bytes - need at least 3. */
1761 uint8_t two_byte_nocrc[] = { 0x01, 0x02 };
1762 FAIL_IF(DNP3CheckUserDataCRCs(two_byte_nocrc, sizeof(two_byte_nocrc)));
1763 #endif
1764
1765 /* 3 bytes, valid CRC. */
1766 uint8_t three_bytes_good_crc[] = { 0x00, 0x00, 0x00 };
1767 *(uint16_t *)(three_bytes_good_crc + 1) = DNP3ComputeCRC(
1768 three_bytes_good_crc, 1);
1769 FAIL_IF(!DNP3CheckUserDataCRCs(three_bytes_good_crc,
1770 sizeof(three_bytes_good_crc)));
1771
1772 PASS;
1773 }
1774
1775 /**
1776 * \test Test the link layer length calculation.
1777 *
1778 * Test the calculation that converts the link provided in the DNP3
1779 * header to the actual length of the frame. That is the length with
1780 * CRCs as the length in the header does not include CRCs.
1781 */
1782 static int DNP3CalculateLinkLengthTest(void)
1783 {
1784 /* These are invalid. */
1785 FAIL_IF(DNP3CalculateLinkLength(0) != 0);
1786 FAIL_IF(DNP3CalculateLinkLength(1) != 0);
1787 FAIL_IF(DNP3CalculateLinkLength(2) != 0);
1788 FAIL_IF(DNP3CalculateLinkLength(3) != 0);
1789 FAIL_IF(DNP3CalculateLinkLength(4) != 0);
1790
1791 /* This is the minimum size. */
1792 FAIL_IF(DNP3CalculateLinkLength(5) != 10);
1793
1794 /* 1 full user data blocks of data. */
1795 FAIL_IF(DNP3CalculateLinkLength(21) != 28);
1796
1797 /* 2 full user data blocks of data. */
1798 FAIL_IF(DNP3CalculateLinkLength(37) != 46);
1799
1800 /* 2 full user data blocks, plus one more byte. */
1801 /* 2 full user data blocks of data. */
1802 FAIL_IF(DNP3CalculateLinkLength(38) != 49);
1803
1804 /* The maximum size. */
1805 FAIL_IF(DNP3CalculateLinkLength(255) != 292);
1806
1807 PASS;
1808 }
1809
1810 /**
1811 * \test The conversion of length with CRCs to the length without
1812 * CRCs.
1813 */
1814 static int DNP3CalculateTransportLengthWithoutCRCsTest(void)
1815 {
1816 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(0) != -1);
1817 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(1) != -1);
1818 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(2) != 0);
1819 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(3) != 1);
1820 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(16) != 14);
1821 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(17) != 15);
1822 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(18) != 16);
1823
1824 /* 19 bytes is not enough for a second block. */
1825 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(19) != -1);
1826
1827 /* 20 bytes really isn't enough either, but is large enough to
1828 * satisfy the CRC on the second block. */
1829 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(20) != 16);
1830
1831 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(21) != 17);
1832
1833 PASS;
1834 }
1835
1836 /**
1837 * \test Test the validation of the link header CRC.
1838 */
1839 static int DNP3ParserCheckLinkHeaderCRC(void)
1840 {
1841 /* DNP3 frame with valid headers and CRCs. */
1842 uint8_t request[] = {
1843 /* DNP3 start. */
1844 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
1845 0xa5, 0xe9,
1846
1847 /* Transport header. */
1848 0xff,
1849
1850 /* Application layer. */
1851 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
1852 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
1853 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
1854 };
1855
1856 DNP3LinkHeader *header = (DNP3LinkHeader *)request;
1857 FAIL_IF(!DNP3CheckLinkHeaderCRC(header));
1858
1859 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1860 /* Alter a byte in the header. */
1861 request[4] = 0;
1862 FAIL_IF(DNP3CheckLinkHeaderCRC(header));
1863 #endif
1864
1865 PASS;
1866 }
1867
1868 /**
1869 * \test Test removal of CRCs from user data.
1870 */
1871 static int DNP3ReassembleApplicationLayerTest01(void)
1872 {
1873 uint32_t reassembled_len = 0;
1874 uint8_t *output = NULL;
1875
1876 uint8_t payload[] = {
1877
1878 0xff, 0xc9, 0x05, 0x0c,
1879 0x01, 0x28, 0x01, 0x00,
1880 0x00, 0x00, 0x01, 0x01,
1881 0x01, 0x00, 0x00, 0x00,
1882 0x72, 0xef, /* CRC. */
1883
1884 0xff, 0xc9, 0x05, 0x0c,
1885 0x01, 0x28, 0x01, 0x00,
1886 0x00, 0x00, 0x01, 0x01,
1887 0x01, 0x00, 0x00, 0x00,
1888 0x72, 0xef, /* CRC. */
1889
1890 0xff, 0xc9, 0x05, 0x0c,
1891 0x01, 0x28, 0x01, 0x00,
1892 0x00, 0x00, 0x01, 0x01,
1893 0x01, 0x00, 0x00, 0x00,
1894 0x72, 0xef, /* CRC. */
1895
1896 0x00, 0x00, 0x00, 0x00,
1897 0x00,
1898 0xff, 0xff, /* CRC. */
1899 };
1900
1901 uint8_t expected[] = {
1902 0xc9, 0x05, 0x0c,
1903 0x01, 0x28, 0x01, 0x00,
1904 0x00, 0x00, 0x01, 0x01,
1905 0x01, 0x00, 0x00, 0x00,
1906 /* CRC removed. */
1907 0xff, 0xc9, 0x05, 0x0c,
1908 0x01, 0x28, 0x01, 0x00,
1909 0x00, 0x00, 0x01, 0x01,
1910 0x01, 0x00, 0x00, 0x00,
1911 /* CRC removed. */
1912 0xff, 0xc9, 0x05, 0x0c,
1913 0x01, 0x28, 0x01, 0x00,
1914 0x00, 0x00, 0x01, 0x01,
1915 0x01, 0x00, 0x00, 0x00,
1916 /* CRC removed. */
1917 0x00, 0x00, 0x00, 0x00,
1918 0x00
1919 /* CRC removed. */
1920 };
1921
1922 /* Valid frame. */
1923 FAIL_IF(!DNP3ReassembleApplicationLayer(payload,
1924 sizeof(payload), &output, &reassembled_len));
1925 FAIL_IF(output == NULL);
1926 FAIL_IF(reassembled_len != sizeof(expected));
1927 FAIL_IF(memcmp(expected, output, reassembled_len));
1928 SCFree(output);
1929
1930 /* 1 byte, invalid. */
1931 reassembled_len = 0;
1932 output = NULL;
1933 FAIL_IF(DNP3ReassembleApplicationLayer(payload, 1, &output,
1934 &reassembled_len));
1935 FAIL_IF(output != NULL);
1936 FAIL_IF(reassembled_len != 0);
1937
1938 /* 2 bytes, invalid. */
1939 reassembled_len = 0;
1940 output = NULL;
1941 FAIL_IF(DNP3ReassembleApplicationLayer(payload, 2, &output,
1942 &reassembled_len));
1943 FAIL_IF(output != NULL);
1944 FAIL_IF(reassembled_len != 0);
1945
1946 /* 3 bytes, minimum - but that would only be the transport header
1947 * which isn't included in the output. */
1948 reassembled_len = 0;
1949 output = NULL;
1950 FAIL_IF(DNP3ReassembleApplicationLayer(payload, 3, &output,
1951 &reassembled_len));
1952 FAIL_IF(output != NULL);
1953 FAIL_IF(reassembled_len != 0);
1954
1955 /* 4 bytes is the minimum to get any reassembled data. */
1956 reassembled_len = 0;
1957 output = NULL;
1958 FAIL_IF(!DNP3ReassembleApplicationLayer(payload, 4, &output,
1959 &reassembled_len));
1960 FAIL_IF(output == NULL);
1961 FAIL_IF(reassembled_len != 1);
1962
1963 /* Last block too short (by 1 byte) for data + CRC. */
1964 uint8_t short_payload1[] = {
1965
1966 0xff, 0xc9, 0x05, 0x0c,
1967 0x01, 0x28, 0x01, 0x00,
1968 0x00, 0x00, 0x01, 0x01,
1969 0x01, 0x00, 0x00, 0x00,
1970 0x72, 0xef, /* CRC. */
1971
1972 0xff, 0xc9, 0x05, 0x0c,
1973 0x01, 0x28, 0x01, 0x00,
1974 0x00, 0x00, 0x01, 0x01,
1975 0x01, 0x00, 0x00, 0x00,
1976 0x72, 0xef, /* CRC. */
1977
1978 0xff, 0xc9, 0x05, 0x0c,
1979 0x01, 0x28, 0x01, 0x00,
1980 0x00, 0x00, 0x01, 0x01,
1981 0x01, 0x00, 0x00, 0x00,
1982 0x72, 0xef, /* CRC. */
1983
1984 0x00, 0x00
1985 };
1986 reassembled_len = 0;
1987 FAIL_IF(DNP3ReassembleApplicationLayer(short_payload1,
1988 sizeof(short_payload1), &output, &reassembled_len));
1989
1990 /* Last block too short (by 2 bytes) for data + CRC. */
1991 uint8_t short_payload2[] = {
1992
1993 0xff, 0xc9, 0x05, 0x0c,
1994 0x01, 0x28, 0x01, 0x00,
1995 0x00, 0x00, 0x01, 0x01,
1996 0x01, 0x00, 0x00, 0x00,
1997 0x72, 0xef, /* CRC. */
1998
1999 0xff, 0xc9, 0x05, 0x0c,
2000 0x01, 0x28, 0x01, 0x00,
2001 0x00, 0x00, 0x01, 0x01,
2002 0x01, 0x00, 0x00, 0x00,
2003 0x72, 0xef, /* CRC. */
2004
2005 0xff, 0xc9, 0x05, 0x0c,
2006 0x01, 0x28, 0x01, 0x00,
2007 0x00, 0x00, 0x01, 0x01,
2008 0x01, 0x00, 0x00, 0x00,
2009 0x72, 0xef, /* CRC. */
2010
2011 0x00,
2012 };
2013 reassembled_len = 0;
2014 FAIL_IF(DNP3ReassembleApplicationLayer(short_payload2,
2015 sizeof(short_payload2), &output, &reassembled_len));
2016
2017 PASS;
2018 }
2019
2020 /**
2021 * \test Test the probing parser.
2022 */
2023 static int DNP3ProbingParserTest(void)
2024 {
2025 uint8_t pkt[] = {
2026 0x05, 0x64, 0x05, 0xc9, 0x03, 0x00, 0x04, 0x00,
2027 0xbd, 0x71
2028 };
2029 uint8_t rdir = 0;
2030
2031 /* Valid frame. */
2032 FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(pkt), &rdir) != ALPROTO_DNP3);
2033
2034 /* Send too little bytes. */
2035 FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(DNP3LinkHeader) - 1, &rdir) != ALPROTO_UNKNOWN);
2036
2037 /* Bad start bytes. */
2038 pkt[0] = 0x06;
2039 FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(pkt), &rdir) != ALPROTO_FAILED);
2040
2041 /* Restore start byte. */
2042 pkt[0] = 0x05;
2043
2044 /* Set the length to a value less than the minimum length of 5. */
2045 pkt[2] = 0x03;
2046 FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(pkt), &rdir) != ALPROTO_FAILED);
2047
2048 /* Send a banner. */
2049 char mybanner[] = "Welcome to DNP3 SCADA.";
2050 FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, (uint8_t *)mybanner, sizeof(mybanner) - 1,
2051 &rdir) != ALPROTO_DNP3);
2052 FAIL_IF(rdir != STREAM_TOCLIENT);
2053
2054 PASS;
2055 }
2056
2057 /**
2058 * \test Test a basic request/response.
2059 */
2060 static int DNP3ParserTestRequestResponse(void)
2061 {
2062 DNP3State *state = NULL;
2063
2064 uint8_t request[] = {
2065 /* DNP3 start. */
2066 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2067 0xa5, 0xe9,
2068
2069 /* Transport header. */
2070 0xff,
2071
2072 /* Application layer. */
2073 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
2074 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
2075 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
2076 };
2077
2078 uint8_t response[] = {
2079 /* DNP3 start. */
2080 0x05, 0x64, 0x1c, 0x44, 0x01, 0x00, 0x02, 0x00,
2081 0xe2, 0x59,
2082
2083 /* Transport header. */
2084 0xc3,
2085
2086 /* Application layer. */
2087 0xc9, 0x81, 0x00, 0x00, 0x0c, 0x01, 0x28, 0x01,
2088 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x7a,
2089 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090 0xff, 0xff
2091 };
2092
2093 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2094 Flow flow;
2095 TcpSession ssn;
2096
2097 memset(&flow, 0, sizeof(flow));
2098 memset(&ssn, 0, sizeof(ssn));
2099
2100 flow.protoctx = (void *)&ssn;
2101 flow.proto = IPPROTO_TCP;
2102 flow.alproto = ALPROTO_DNP3;
2103
2104 StreamTcpInitConfig(true);
2105
2106 SCMutexLock(&flow.m);
2107 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2108 STREAM_TOSERVER, request, sizeof(request)));
2109 SCMutexUnlock(&flow.m);
2110
2111 state = flow.alstate;
2112 FAIL_IF(state == NULL);
2113
2114 DNP3Transaction *tx = DNP3GetTx(state, 0);
2115 FAIL_IF(tx == NULL);
2116 FAIL_IF(tx->tx_num != 1);
2117 FAIL_IF(tx != state->curr);
2118 FAIL_IF(tx->request_buffer == NULL);
2119 FAIL_IF(tx->request_buffer_len != 20);
2120 FAIL_IF(tx->request_ah.function_code != DNP3_APP_FC_DIR_OPERATE);
2121
2122 SCMutexLock(&flow.m);
2123 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2124 STREAM_TOCLIENT, response, sizeof(response)));
2125 SCMutexUnlock(&flow.m);
2126 FAIL_IF(DNP3GetTx(state, 0) != tx);
2127 FAIL_IF(!tx->response_done);
2128 FAIL_IF(tx->response_buffer == NULL);
2129
2130 AppLayerParserThreadCtxFree(alp_tctx);
2131 StreamTcpFreeConfig(true);
2132 FLOW_DESTROY(&flow);
2133 PASS;
2134 }
2135
2136 /**
2137 * \test Test an unsolicited response from an outstation.
2138 *
2139 * This is kind of like a request initiated from the "server".
2140 */
2141 static int DNP3ParserTestUnsolicitedResponseConfirm(void)
2142 {
2143 DNP3State *state = NULL;
2144
2145 /* Unsolicited response with confirm bit set. */
2146 uint8_t response[] = {
2147 0x05, 0x64, 0x16, 0x44, 0x01, 0x00, 0x02, 0x00,
2148 0x89, 0xe5, 0xc4, 0xfa, 0x82, 0x00, 0x00, 0x02,
2149 0x02, 0x17, 0x01, 0x01, 0x81, 0xa7, 0x75, 0xd8,
2150 0x32, 0x4c, 0x81, 0x3e, 0x01, 0xa1, 0xc9
2151 };
2152
2153 /* Confirm. */
2154 uint8_t confirm[] = {
2155 0x05, 0x64, 0x08, 0xc4, 0x02, 0x00,
2156 0x01, 0x00, 0xd3, 0xb7, 0xc0, 0xda, 0x00, 0x6a,
2157 0x3d
2158 };
2159
2160 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2161 Flow flow;
2162 TcpSession ssn;
2163
2164 memset(&flow, 0, sizeof(flow));
2165 memset(&ssn, 0, sizeof(ssn));
2166
2167 flow.protoctx = (void *)&ssn;
2168 flow.proto = IPPROTO_TCP;
2169 flow.alproto = ALPROTO_DNP3;
2170
2171 StreamTcpInitConfig(true);
2172
2173 SCMutexLock(&flow.m);
2174 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2175 STREAM_TOCLIENT, response, sizeof(response)));
2176 SCMutexUnlock(&flow.m);
2177
2178 state = flow.alstate;
2179 FAIL_IF(state == NULL);
2180
2181 DNP3Transaction *tx = DNP3GetTx(state, 0);
2182 FAIL_IF(tx == NULL);
2183 FAIL_IF(tx->tx_num != 1);
2184 FAIL_IF(tx != state->curr);
2185 FAIL_IF(tx->request_buffer != NULL);
2186 FAIL_IF(tx->response_buffer == NULL);
2187 FAIL_IF(!tx->response_done);
2188 FAIL_IF(tx->response_ah.function_code != DNP3_APP_FC_UNSOLICITED_RESP);
2189
2190 SCMutexLock(&flow.m);
2191 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2192 STREAM_TOSERVER, confirm, sizeof(confirm)));
2193 SCMutexUnlock(&flow.m);
2194 FAIL_IF(DNP3GetTx(state, 0) != tx);
2195 FAIL_IF(!tx->response_done);
2196 FAIL_IF(tx->response_buffer == NULL);
2197 /* FAIL_IF(tx->iin1 != 0 || tx->iin2 != 0); */
2198
2199 AppLayerParserThreadCtxFree(alp_tctx);
2200 StreamTcpFreeConfig(true);
2201 FLOW_DESTROY(&flow);
2202 PASS;
2203 }
2204
2205 /**
2206 * \test Test flood state.
2207 */
2208 static int DNP3ParserTestFlooded(void)
2209 {
2210 DNP3State *state = NULL;
2211
2212 uint8_t request[] = {
2213 /* DNP3 start. */
2214 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2215 0xa5, 0xe9,
2216
2217 /* Transport header. */
2218 0xff,
2219
2220 /* Application layer. */
2221 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
2222 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
2223 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
2224 };
2225
2226 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2227 Flow flow;
2228 TcpSession ssn;
2229
2230 memset(&flow, 0, sizeof(flow));
2231 memset(&ssn, 0, sizeof(ssn));
2232
2233 flow.protoctx = (void *)&ssn;
2234 flow.proto = IPPROTO_TCP;
2235 flow.alproto = ALPROTO_DNP3;
2236
2237 StreamTcpInitConfig(true);
2238
2239 SCMutexLock(&flow.m);
2240 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2241 STREAM_TOSERVER, request, sizeof(request)));
2242 SCMutexUnlock(&flow.m);
2243
2244 state = flow.alstate;
2245 FAIL_IF(state == NULL);
2246
2247 DNP3Transaction *tx = DNP3GetTx(state, 0);
2248 FAIL_IF(tx == NULL);
2249 FAIL_IF(tx->tx_num != 1);
2250 FAIL_IF(tx != state->curr);
2251 FAIL_IF(tx->request_buffer == NULL);
2252 FAIL_IF(tx->request_buffer_len != 20);
2253 /* FAIL_IF(tx->app_function_code != DNP3_APP_FC_DIR_OPERATE); */
2254 FAIL_IF(tx->response_done);
2255
2256 for (int i = 0; i < DNP3_DEFAULT_REQ_FLOOD_COUNT - 1; i++) {
2257 SCMutexLock(&flow.m);
2258 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2259 STREAM_TOSERVER, request, sizeof(request)));
2260 SCMutexUnlock(&flow.m);
2261 }
2262 FAIL_IF(state->flooded);
2263 FAIL_IF(DNP3GetAlstateProgress(tx, 0));
2264
2265 /* One more request should trip us into flooded state. */
2266 SCMutexLock(&flow.m);
2267 FAIL_IF(AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2268 STREAM_TOSERVER, request, sizeof(request)));
2269 SCMutexUnlock(&flow.m);
2270 FAIL_IF(!state->flooded);
2271
2272 /* Progress for the oldest tx should return 1. */
2273 FAIL_IF(!DNP3GetAlstateProgress(tx, 0));
2274
2275 /* But progress for the current state should still return 0. */
2276 FAIL_IF(DNP3GetAlstateProgress(state->curr, 0));
2277
2278 AppLayerParserThreadCtxFree(alp_tctx);
2279 StreamTcpFreeConfig(true);
2280 FLOW_DESTROY(&flow);
2281 PASS;
2282 }
2283
2284 /**
2285 * \test Test parsing of partial frames.
2286 *
2287 * As DNP3 operates over TCP, it is possible that a partial DNP3 frame
2288 * is received. Test that the partial frame will be buffered until the
2289 * remainder is seen.
2290 */
2291 static int DNP3ParserTestPartialFrame(void)
2292 {
2293 DNP3State *state = NULL;
2294 DNP3Transaction *tx;
2295 int r;
2296
2297 uint8_t request_partial1[] = {
2298 /* DNP3 start. */
2299 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2300 0xa5, 0xe9,
2301
2302 /* Transport header. */
2303 0xff,
2304
2305 /* Application layer. */
2306 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
2307 };
2308
2309 uint8_t request_partial2[] = {
2310 /* Remainder of application layer. */
2311 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
2312 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
2313 };
2314
2315 uint8_t response_partial1[] = {
2316 /* DNP3 start. */
2317 0x05, 0x64, 0x1c, 0x44, 0x01, 0x00, 0x02, 0x00,
2318 0xe2, 0x59,
2319
2320 /* Transport header. */
2321 0xc3,
2322
2323 /* Application layer. */
2324 0xc9, 0x81, 0x00, 0x00, 0x0c, 0x01, 0x28, 0x01,
2325 };
2326
2327 uint8_t response_partial2[] = {
2328 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x7a,
2329 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330 0xff, 0xff
2331 };
2332
2333 /* Boiler plate for app layer setup. */
2334 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2335 Flow flow;
2336 TcpSession ssn;
2337 memset(&flow, 0, sizeof(flow));
2338 memset(&ssn, 0, sizeof(ssn));
2339 flow.protoctx = (void *)&ssn;
2340 flow.proto = IPPROTO_TCP;
2341 flow.alproto = ALPROTO_DNP3;
2342 StreamTcpInitConfig(true);
2343
2344 /* Pass in the first partial frame. */
2345
2346 SCMutexLock(&flow.m);
2347 r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2348 STREAM_TOSERVER, request_partial1, sizeof(request_partial1));
2349 SCMutexUnlock(&flow.m);
2350 FAIL_IF(r != 0);
2351
2352 /* Frame should just be buffered, but not yet processed. */
2353 state = flow.alstate;
2354 FAIL_IF(state == NULL);
2355 FAIL_IF(state->request_buffer.len != sizeof(request_partial1));
2356 FAIL_IF(state->request_buffer.offset != 0);
2357 FAIL_IF(memcmp(state->request_buffer.buffer, request_partial1,
2358 sizeof(request_partial1)));
2359
2360 /* There should not be a transaction yet. */
2361 FAIL_IF(state->transaction_max != 0);
2362 FAIL_IF(DNP3GetTx(state, 0) != NULL);
2363
2364 /* Send the second partial. */
2365 SCMutexLock(&flow.m);
2366 r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2367 STREAM_TOSERVER, request_partial2, sizeof(request_partial2));
2368 SCMutexUnlock(&flow.m);
2369 FAIL_IF(r != 0);
2370
2371 /* The second partial completed the frame, the buffer should now
2372 * be clear. */
2373 FAIL_IF(state->request_buffer.len != 0);
2374 FAIL_IF(state->request_buffer.offset != 0);
2375
2376 /* Should now have a complete transaction. */
2377 tx = DNP3GetTx(state, 0);
2378 FAIL_IF(tx == NULL);
2379 FAIL_IF(tx->tx_num != 1);
2380 FAIL_IF(tx != state->curr);
2381 FAIL_IF(tx->request_buffer == NULL);
2382 FAIL_IF(tx->request_buffer_len != 20);
2383 FAIL_IF(tx->request_ah.function_code != DNP3_APP_FC_DIR_OPERATE);
2384
2385 /* Send partial response. */
2386 SCMutexLock(&flow.m);
2387 r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2388 STREAM_TOCLIENT, response_partial1, sizeof(response_partial1));
2389 SCMutexUnlock(&flow.m);
2390 FAIL_IF(r != 0);
2391 FAIL_IF(state->response_buffer.len != sizeof(response_partial1));
2392 FAIL_IF(state->response_buffer.offset != 0);
2393 FAIL_IF(tx->response_done);
2394
2395 /* Send rest of response. */
2396 SCMutexLock(&flow.m);
2397 r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2398 STREAM_TOCLIENT, response_partial2, sizeof(response_partial2));
2399 SCMutexUnlock(&flow.m);
2400 FAIL_IF(r != 0);
2401
2402 /* Buffer should now be empty. */
2403 FAIL_IF(state->response_buffer.len != 0);
2404 FAIL_IF(state->response_buffer.offset != 0);
2405
2406 /* Transaction should be replied to now. */
2407 FAIL_IF(!tx->response_done);
2408 FAIL_IF(tx->response_buffer == NULL);
2409 FAIL_IF(tx->response_buffer_len == 0);
2410
2411 AppLayerParserThreadCtxFree(alp_tctx);
2412 StreamTcpFreeConfig(true);
2413 FLOW_DESTROY(&flow);
2414 PASS;
2415 }
2416
2417 /**
2418 * \test Test multiple DNP3 frames in one TCP read.
2419 */
2420 static int DNP3ParserTestMultiFrame(void)
2421 {
2422 DNP3State *state = NULL;
2423
2424 /* Unsolicited response 1. */
2425 uint8_t unsol_response1[] = {
2426 0x05, 0x64, 0x16, 0x44, 0x01, 0x00, 0x02, 0x00,
2427 0x89, 0xe5, 0xc4, 0xfa, 0x82, 0x00, 0x00, 0x02,
2428 0x02, 0x17, 0x01, 0x01, 0x81, 0xa7, 0x75, 0xd8,
2429 0x32, 0x4c, 0x81, 0x3e, 0x01, 0xa1, 0xc9,
2430 };
2431
2432 /* Unsolicited response 2. */
2433 uint8_t unsol_response2[] = {
2434 0x05, 0x64, 0x16, 0x44, 0x01, 0x00, 0x02, 0x00,
2435 0x89, 0xe5, 0xc5, 0xfb, 0x82, 0x00, 0x00, 0x02,
2436 0x02, 0x17, 0x01, 0x0c, 0x01, 0xd8, 0x75, 0xd8,
2437 0x32, 0x4c, 0xc9, 0x3c, 0x01, 0xa1, 0xc9,
2438 };
2439
2440 uint8_t combined[sizeof(unsol_response1) + sizeof(unsol_response2)];
2441 memcpy(combined, unsol_response1, sizeof(unsol_response1));
2442 memcpy(combined + sizeof(unsol_response1), unsol_response2,
2443 sizeof(unsol_response2));
2444
2445 /* Setup. */
2446 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2447 Flow flow;
2448 TcpSession ssn;
2449 int r;
2450 memset(&flow, 0, sizeof(flow));
2451 memset(&ssn, 0, sizeof(ssn));
2452 flow.protoctx = (void *)&ssn;
2453 flow.proto = IPPROTO_TCP;
2454 flow.alproto = ALPROTO_DNP3;
2455 StreamTcpInitConfig(true);
2456
2457 SCMutexLock(&flow.m);
2458 r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2459 STREAM_TOCLIENT, combined, sizeof(combined));
2460 SCMutexUnlock(&flow.m);
2461 FAIL_IF(r != 0);
2462
2463 state = flow.alstate;
2464 FAIL_IF(state == NULL);
2465 FAIL_IF(state->transaction_max != 2);
2466
2467 AppLayerParserThreadCtxFree(alp_tctx);
2468 StreamTcpFreeConfig(true);
2469 FLOW_DESTROY(&flow);
2470 PASS;
2471 }
2472
2473 /**
2474 * \test Test the parsing of a request PDU.
2475 *
2476 * The PDU under test contains a single read request object:
2477 * - Group: 1
2478 * - Variation: 0
2479 * - Count: 0
2480 */
2481 static int DNP3ParserTestParsePDU01(void)
2482 {
2483 /* Frame to be tested. This frame is a DNP3 request with one read
2484 * request data object, group 1, variation 0. */
2485 const uint8_t pkt[] = {
2486 0x05, 0x64,
2487 0x0b, 0xc4, 0x17, 0x00, 0xef, 0xff, 0xc4, 0x8f,
2488 0xe1, 0xc8, 0x01, 0x01, 0x00, 0x06, 0x77, 0x6e
2489 };
2490
2491 DNP3State *dnp3state = DNP3StateAlloc(NULL, ALPROTO_UNKNOWN);
2492 int pdus = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
2493 FAIL_IF(pdus < 1);
2494 DNP3Transaction *dnp3tx = DNP3GetTx(dnp3state, 0);
2495 FAIL_IF_NULL(dnp3tx);
2496 FAIL_IF(!dnp3tx->has_request);
2497 FAIL_IF(TAILQ_EMPTY(&dnp3tx->request_objects));
2498 DNP3Object *object = TAILQ_FIRST(&dnp3tx->request_objects);
2499 FAIL_IF(object->group != 1 || object->variation != 0);
2500 FAIL_IF(object->count != 0);
2501
2502 DNP3StateFree(dnp3state);
2503 PASS;
2504 }
2505
2506 /**
2507 * \test Test the decode of a DNP3 fragment with a single 70:3 object.
2508 */
2509 static int DNP3ParserDecodeG70V3Test(void)
2510 {
2511 const uint8_t pkt[] = {
2512 0x05, 0x64,
2513 0x63, 0xc4, 0x04, 0x00, 0x03, 0x00, 0xc7, 0xee,
2514 0xc7, 0xc9, 0x1b, 0x46, 0x03, 0x5b, 0x01, 0x55,
2515 0x00, 0x1a, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00,
2516 0x9e, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2518 0x00, 0x00, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x43,
2519 0x3a, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x2f, 0x44,
2520 0x4e, 0x50, 0x44, 0x65, 0x67, 0x7d, 0x76, 0x69,
2521 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
2522 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x93, 0x0c,
2523 0x6e, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65,
2524 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x52, 0x65, 0x6d,
2525 0x35, 0x20, 0x6f, 0x74, 0x65, 0x20, 0x44, 0x65,
2526 0x76, 0x69, 0x63, 0x65, 0x2e, 0x78, 0x6d, 0x6c,
2527 0xc4, 0x8b
2528 };
2529
2530 DNP3State *dnp3state = DNP3StateAlloc(NULL, ALPROTO_UNKNOWN);
2531 FAIL_IF_NULL(dnp3state);
2532 int bytes = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
2533 FAIL_IF(bytes != sizeof(pkt));
2534 DNP3Transaction *tx = DNP3GetTx(dnp3state, 0);
2535 FAIL_IF_NULL(tx);
2536 FAIL_IF_NOT(tx->has_request);
2537 DNP3Object *obj = TAILQ_FIRST(&tx->request_objects);
2538 FAIL_IF_NULL(obj);
2539 FAIL_IF_NOT(obj->group == 70);
2540 FAIL_IF_NOT(obj->variation == 3);
2541 FAIL_IF_NOT(obj->prefix_code == 0x5);
2542 FAIL_IF_NOT(obj->range_code == 0xb);
2543 FAIL_IF_NOT(obj->count == 1);
2544 DNP3Point *point = TAILQ_FIRST(obj->points);
2545 FAIL_IF_NULL(point);
2546 FAIL_IF_NOT(point->prefix == 85);
2547 FAIL_IF_NOT(point->size == 85);
2548 FAIL_IF_NULL(point->data);
2549 DNP3ObjectG70V3 *data = point->data;
2550 FAIL_IF_NOT(strcmp(
2551 data->filename,
2552 "C:/temp/DNPDeviceConfiguration written to Remote Device.xml") == 0);
2553 DNP3StateFree(dnp3state);
2554 PASS;
2555 }
2556
2557 /**
2558 * \brief Test that an alert is raised on an unknown object.
2559 */
2560 static int DNP3ParserUnknownEventAlertTest(void)
2561 {
2562 /* Valid DNP3 frame with 70:3 object. */
2563 uint8_t pkt[] = {
2564 0x05, 0x64, 0x63, 0xc4, 0x04, 0x00, 0x03, 0x00,
2565 0xc7, 0xee,
2566
2567 0xc7, 0xc9, 0x1b,
2568
2569 /* Object and variation. Originally 70:3, now 70:99, an
2570 * unknown object. */
2571 0x46, 0x63,
2572
2573 0x5b, 0x01, 0x55,
2574 0x00, 0x1a, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00,
2575 0x9e, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2577 0x00, 0x00, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x43,
2578 0x3a, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x2f, 0x44,
2579 0x4e, 0x50, 0x44, 0x65, 0x67, 0x7d, 0x76, 0x69,
2580 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
2581 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x93, 0x0c,
2582 0x6e, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65,
2583 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x52, 0x65, 0x6d,
2584 0x35, 0x20, 0x6f, 0x74, 0x65, 0x20, 0x44, 0x65,
2585 0x76, 0x69, 0x63, 0x65, 0x2e, 0x78, 0x6d, 0x6c,
2586 0xc4, 0x8b
2587 };
2588
2589 DNP3FixCrc(pkt + 10, sizeof(pkt) - 10);
2590
2591 DNP3State *dnp3state = DNP3StateAlloc(NULL, ALPROTO_UNKNOWN);
2592 FAIL_IF_NULL(dnp3state);
2593 int bytes = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
2594 FAIL_IF(bytes != sizeof(pkt));
2595
2596 DNP3StateFree(dnp3state);
2597 PASS;
2598 }
2599
2600 /**
2601 * \brief Test that an alert is raised on incorrect data.
2602 */
2603 static int DNP3ParserIncorrectUserData(void)
2604 {
2605 uint8_t packet_bytes[] = {
2606 0x05, 0x64, 0x08, 0xc4, 0x03, 0x00, 0x04, 0x00,
2607 0xbf, 0xe9, 0xc1, 0xc1, 0x82, 0xc5, 0xee
2608 };
2609
2610 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2611 Flow flow;
2612 TcpSession ssn;
2613 memset(&flow, 0, sizeof(flow));
2614 memset(&ssn, 0, sizeof(ssn));
2615 flow.protoctx = (void *)&ssn;
2616 flow.proto = IPPROTO_TCP;
2617 flow.alproto = ALPROTO_DNP3;
2618 StreamTcpInitConfig(true);
2619
2620 int r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2621 STREAM_TOCLIENT, packet_bytes, sizeof(packet_bytes));
2622
2623 FAIL_IF(r == 0);
2624
2625 AppLayerParserThreadCtxFree(alp_tctx);
2626 StreamTcpFreeConfig(true);
2627 FLOW_DESTROY(&flow);
2628 PASS;
2629 }
2630
2631 #endif
2632
2633 void DNP3ParserRegisterTests(void)
2634 {
2635 #ifdef UNITTESTS
2636 UtRegisterTest("DNP3ParserTestCheckCRC", DNP3ParserTestCheckCRC);
2637 UtRegisterTest("DNP3ParserCheckLinkHeaderCRC",
2638 DNP3ParserCheckLinkHeaderCRC);
2639 UtRegisterTest("DNP3CheckUserDataCRCsTest", DNP3CheckUserDataCRCsTest);
2640 UtRegisterTest("DNP3CalculateLinkLengthTest", DNP3CalculateLinkLengthTest);
2641 UtRegisterTest("DNP3CalculateTransportLengthWithoutCRCsTest",
2642 DNP3CalculateTransportLengthWithoutCRCsTest);
2643 UtRegisterTest("DNP3ReassembleApplicationLayerTest01",
2644 DNP3ReassembleApplicationLayerTest01);
2645 UtRegisterTest("DNP3ProbingParserTest", DNP3ProbingParserTest);
2646 UtRegisterTest("DNP3ParserTestRequestResponse",
2647 DNP3ParserTestRequestResponse);
2648 UtRegisterTest("DNP3ParserTestUnsolicitedResponseConfirm",
2649 DNP3ParserTestUnsolicitedResponseConfirm);
2650 UtRegisterTest("DNP3ParserTestPartialFrame", DNP3ParserTestPartialFrame);
2651 UtRegisterTest("DNP3ParserTestMultiFrame", DNP3ParserTestMultiFrame);
2652 UtRegisterTest("DNP3ParserTestFlooded", DNP3ParserTestFlooded);
2653 UtRegisterTest("DNP3ParserTestParsePDU01", DNP3ParserTestParsePDU01);
2654 UtRegisterTest("DNP3ParserDecodeG70V3Test", DNP3ParserDecodeG70V3Test);
2655 UtRegisterTest("DNP3ParserUnknownEventAlertTest",
2656 DNP3ParserUnknownEventAlertTest);
2657 UtRegisterTest("DNP3ParserIncorrectUserData", DNP3ParserIncorrectUserData);
2658 #endif
2659 }