1 /* Copyright (C) 2015 Open Information Security Foundation
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
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.
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
18 #include "suricata-common.h"
20 #include "util-byte.h"
21 #include "util-unittest.h"
22 #include "util-hashlist.h"
24 #include "util-print.h"
26 #include "app-layer-protos.h"
27 #include "app-layer-parser.h"
28 #include "app-layer-detect-proto.h"
30 #include "app-layer-dnp3.h"
31 #include "app-layer-dnp3-objects.h"
34 #include "app-layer-dcerpc-common.h"
36 /* Default number of unreplied requests to be considered a flood. */
37 #define DNP3_DEFAULT_REQ_FLOOD_COUNT 500
39 #define DNP3_DEFAULT_PORT "20000"
41 /* Expected values for the start bytes. */
42 #define DNP3_START_BYTE0 0x05
43 #define DNP3_START_BYTE1 0x64
45 /* Minimum length for a DNP3 frame. */
46 #define DNP3_MIN_LEN 5
48 /* Length of each CRC. */
49 #define DNP3_CRC_LEN 2
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
55 /* Maximum transport layer sequence number. */
56 #define DNP3_MAX_TRAN_SEQNO 64
58 /* Maximum application layer sequence number. */
59 #define DNP3_MAX_APP_SEQNO 16
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
65 /* Link function codes. */
67 DNP3_LINK_FC_CONFIRMED_USER_DATA
= 3,
68 DNP3_LINK_FC_UNCONFIRMED_USER_DATA
71 /* Reserved addresses. */
72 #define DNP3_RESERVED_ADDR_MIN 0xfff0
73 #define DNP3_RESERVED_ADDR_MAX 0xfffb
75 /* Source addresses must be < 0xfff0. */
76 #define DNP3_SRC_ADDR_MAX 0xfff0
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
83 /* Extract the prefix code from the object qualifier. */
84 #define DNP3_OBJ_PREFIX(x) ((x >> 4) & 0x7)
86 /* Extract the range code from the object qualifier. */
87 #define DNP3_OBJ_RANGE(x) (x & 0xf)
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
},
100 /* Calculate the next transport sequence number. */
101 #define NEXT_TH_SEQNO(current) ((current + 1) % DNP3_MAX_TRAN_SEQNO)
103 /* Calculate the next application sequence number. */
104 #define NEXT_APP_SEQNO(current) ((current + 1) % DNP3_MAX_APP_SEQNO)
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
144 * \brief Compute the CRC for a buffer.
146 * \param buf Buffer to create CRC from.
147 * \param len Length of buffer (number of bytes to use for CRC).
150 static uint16_t DNP3ComputeCRC(const uint8_t *buf
, uint32_t len
)
152 const uint8_t *byte
= buf
;
157 idx
= (crc
^ *byte
) & 0xff;
158 crc
= (crc_table
[idx
] ^ (crc
>> 8)) & 0xffff;
162 return ~crc
& 0xffff;
166 * \brief Check the CRC of a block.
168 * \param block The block of data with CRC to be checked.
169 * \param len The size of the data block.
171 * \retval 1 if CRC is OK, otherwise 0.
173 static int DNP3CheckCRC(const uint8_t *block
, uint32_t len
)
175 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
181 /* Need at least one byte plus the CRC. */
182 if (len
< DNP3_CRC_LEN
+ 1) {
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])) {
197 * \brief Check the CRC of the link header.
199 * \param header Point to the link header.
201 * \retval 1 if header CRC is OK, otherwise 0.
203 static int DNP3CheckLinkHeaderCRC(const DNP3LinkHeader
*header
)
205 return DNP3CheckCRC((uint8_t *)header
, sizeof(DNP3LinkHeader
));
209 * \brief Check user data CRCs.
211 * \param data Pointer to user data.
212 * \param len Length of user data.
214 * \retval 1 if CRCs are OK, otherwise 0.
216 static int DNP3CheckUserDataCRCs(const uint8_t *data
, uint32_t len
)
221 while (offset
< len
) {
222 if (len
- offset
>= DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
) {
223 block_size
= DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
;
226 block_size
= len
- offset
;
229 if (!DNP3CheckCRC(data
+ offset
, block_size
)) {
230 /* Once failed, may as well return immediately. */
234 offset
+= block_size
;
241 * \brief Check the DNP3 frame start bytes.
243 * \retval 1 if valid, 0 if not.
245 static int DNP3CheckStartBytes(const DNP3LinkHeader
*header
)
247 return header
->start_byte0
== DNP3_START_BYTE0
&&
248 header
->start_byte1
== DNP3_START_BYTE1
;
251 /* Some DNP3 servers start with a banner. */
252 #define DNP3_BANNER "DNP3"
255 * \brief Check if a frame contains a banner.
257 * Some servers (outstations) appear to send back a banner that fails
258 * the normal frame checks. So first check for a banner.
260 * \retval 1 if a banner is found, 0 if not.
262 static int DNP3ContainsBanner(const uint8_t *input
, uint32_t len
)
264 return BasicSearch(input
, len
, (uint8_t *)DNP3_BANNER
, strlen(DNP3_BANNER
)) != NULL
;
268 * \brief DNP3 probing parser.
270 static uint16_t DNP3ProbingParser(Flow
*f
, uint8_t direction
,
271 const uint8_t *input
, uint32_t len
,
274 const DNP3LinkHeader
*const hdr
= (const DNP3LinkHeader
*)input
;
275 const bool toserver
= (direction
& STREAM_TOSERVER
) != 0;
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
])) {
290 *rdir
= STREAM_TOCLIENT
;
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
;
302 /* Verify start value (from AN2013-004b). */
303 if (!DNP3CheckStartBytes(hdr
)) {
304 SCLogDebug("Invalid start bytes.");
305 return ALPROTO_FAILED
;
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
;
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
;
318 SCLogDebug("Detected DNP3.");
323 * \brief Caculate the length of the transport layer with CRCs removed.
325 * \param input_len The length of the transport layer buffer.
327 * \retval The length of the buffer after CRCs are removed.
329 static int DNP3CalculateTransportLengthWithoutCRCs(uint32_t input_len
)
332 if (input_len
< DNP3_CRC_LEN
) {
336 /* Get the number of complete blocks. */
337 int blocks
= input_len
/ (DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
);
339 /* And the number of bytes in the last block. */
340 int rem
= input_len
- (blocks
* (DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
));
343 if (rem
< DNP3_CRC_LEN
) {
346 return (blocks
* DNP3_BLOCK_SIZE
) + (rem
- DNP3_CRC_LEN
);
349 return (blocks
* DNP3_BLOCK_SIZE
);
354 * \brief Reassemble the application layer by stripping the CRCs.
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.
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.
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.
370 * \retval 1 if reassembly was successful, otherwise 0.
372 static int DNP3ReassembleApplicationLayer(const uint8_t *input
,
373 uint32_t input_len
, uint8_t **output
, uint32_t *output_len
)
375 int len
= DNP3CalculateTransportLengthWithoutCRCs(input_len
);
381 /* Remove one byte for the transport header and make sure we have
382 * at least one byte of user data. */
387 if (*output
== NULL
) {
388 *output
= SCCalloc(1, len
);
389 if (unlikely(*output
== NULL
)) {
394 uint8_t *ptr
= SCRealloc(*output
, (size_t)(*output_len
+ len
));
395 if (unlikely(ptr
== NULL
)) {
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
;
407 block_size
= input_len
- offset
;
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. */
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.");
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.");
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
;
443 * \brief Allocate a DNP3 state object.
445 * The DNP3 state object represents a single DNP3 TCP session.
447 static void *DNP3StateAlloc(void *orig_state
, AppProto proto_orig
)
452 dnp3
= (DNP3State
*)SCCalloc(1, sizeof(DNP3State
));
453 if (unlikely(dnp3
== NULL
)) {
456 TAILQ_INIT(&dnp3
->tx_list
);
458 SCReturnPtr(dnp3
, "void");
462 * \brief Set a DNP3 application layer event.
464 * Sets an event on the current transaction object.
466 static void DNP3SetEvent(DNP3State
*dnp3
, uint8_t event
)
468 if (dnp3
&& dnp3
->curr
) {
469 AppLayerDecoderEventsSetEventRaw(&dnp3
->curr
->tx_data
.events
, event
);
473 SCLogWarning(SC_ERR_ALPARSER
, "Failed to set event, state or tx pointer was NULL.");
478 * \brief Set a DNP3 application layer event on a transaction.
480 static void DNP3SetEventTx(DNP3Transaction
*tx
, uint8_t event
)
482 AppLayerDecoderEventsSetEventRaw(&tx
->tx_data
.events
, event
);
487 * \brief Allocation a DNP3 transaction.
489 static DNP3Transaction
*DNP3TxAlloc(DNP3State
*dnp3
)
491 DNP3Transaction
*tx
= SCCalloc(1, sizeof(DNP3Transaction
));
492 if (unlikely(tx
== NULL
)) {
495 dnp3
->transaction_max
++;
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
);
504 /* Check for flood state. */
505 if (dnp3
->unreplied
> DNP3_DEFAULT_REQ_FLOOD_COUNT
) {
506 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_FLOODED
);
514 * \brief Calculate the length of a link frame with CRCs.
516 * This is required as the length parameter in the DNP3 header does not
517 * include the added CRCs.
519 * \param length The length from the DNP3 link header.
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.
524 static uint32_t DNP3CalculateLinkLength(uint8_t length
)
526 uint32_t frame_len
= 0;
529 /* Fail early if the length is less than the minimum size. */
530 if (length
< DNP3_LINK_HDR_LEN
) {
534 /* Subtract the 5 bytes of the header that are included in the
536 length
-= DNP3_LINK_HDR_LEN
;
538 rem
= length
% DNP3_BLOCK_SIZE
;
539 frame_len
= (length
/ DNP3_BLOCK_SIZE
) * (DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
);
541 frame_len
+= rem
+ DNP3_CRC_LEN
;
544 return frame_len
+ sizeof(DNP3LinkHeader
);
548 * \brief Check if the link function code specifies user data.
550 * \param header Point to link header.
552 * \retval 1 if frame contains user data, otherwise 0.
554 static int DNP3IsUserData(const DNP3LinkHeader
*header
)
556 switch (DNP3_LINK_FC(header
->control
)) {
557 case DNP3_LINK_FC_CONFIRMED_USER_DATA
:
558 case DNP3_LINK_FC_UNCONFIRMED_USER_DATA
:
566 * \brief Check if the frame has user data.
568 * Check if the DNP3 frame actually has user data by checking if data
569 * exists after the headers.
571 * \retval 1 if user data exists, otherwise 0.
573 static int DNP3HasUserData(const DNP3LinkHeader
*header
, uint8_t direction
)
575 if (direction
== STREAM_TOSERVER
) {
576 return header
->len
>= DNP3_LINK_HDR_LEN
+ sizeof(DNP3TransportHeader
) +
577 sizeof(DNP3ApplicationHeader
);
580 return header
->len
>= DNP3_LINK_HDR_LEN
+ sizeof(DNP3TransportHeader
) +
581 sizeof(DNP3ApplicationHeader
) + sizeof(DNP3InternalInd
);
586 * \brief Reset a DNP3Buffer.
588 static void DNP3BufferReset(DNP3Buffer
*buffer
)
595 * \brief Add data to a DNP3 buffer, enlarging the buffer if required.
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.
601 * \param 1 if data was added successful, otherwise 0.
603 static int DNP3BufferAdd(DNP3Buffer
*buffer
, const uint8_t *data
, uint32_t len
)
605 if (buffer
->size
== 0) {
606 buffer
->buffer
= SCCalloc(1, len
);
607 if (unlikely(buffer
->buffer
== NULL
)) {
612 else if (buffer
->len
+ len
> buffer
->size
) {
613 uint8_t *tmp
= SCRealloc(buffer
->buffer
, buffer
->len
+ len
);
614 if (unlikely(tmp
== NULL
)) {
617 buffer
->buffer
= tmp
;
618 buffer
->size
= buffer
->len
+ len
;
620 memcpy(buffer
->buffer
+ buffer
->len
, data
, len
);
627 * \brief Trim a DNP3 buffer.
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.
632 * \param buffer The buffer to trim.
634 static void DNP3BufferTrim(DNP3Buffer
*buffer
)
636 if (buffer
->offset
== buffer
->len
) {
637 DNP3BufferReset(buffer
);
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
;
648 * \brief Free a DNP3 object.
650 static void DNP3ObjectFree(DNP3Object
*object
)
652 if (object
->points
!= NULL
) {
653 DNP3FreeObjectPointList(object
->group
, object
->variation
,
660 * \breif Allocate a DNP3 object.
662 static DNP3Object
*DNP3ObjectAlloc(void)
664 DNP3Object
*object
= SCCalloc(1, sizeof(*object
));
665 if (unlikely(object
== NULL
)) {
668 object
->points
= DNP3PointListAlloc();
669 if (object
->points
== NULL
) {
670 DNP3ObjectFree(object
);
677 * \brief Decode DNP3 application objects.
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.
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.
688 * \retval 1 if all objects decoded, 0 if all objects could not be decoded (
689 * unknown group/variations)
691 static int DNP3DecodeApplicationObjects(DNP3Transaction
*tx
, const uint8_t *buf
,
692 uint32_t len
, DNP3ObjectList
*objects
)
696 if (buf
== NULL
|| len
== 0) {
703 if (len
< sizeof(DNP3ObjHeader
)) {
706 DNP3ObjHeader
*header
= (DNP3ObjHeader
*)buf
;
707 offset
+= sizeof(DNP3ObjHeader
);
709 DNP3Object
*object
= DNP3ObjectAlloc();
710 if (unlikely(object
== NULL
)) {
713 TAILQ_INSERT_TAIL(objects
, object
, next
);
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
);
721 /* IEEE 1815-2012, Table 4-5. */
722 switch (object
->range_code
) {
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
;
732 object
->start
= buf
[offset
++];
733 object
->stop
= buf
[offset
++];
734 object
->count
= object
->stop
- object
->start
+ 1;
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
;
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;
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
;
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;
770 /* No range field. */
774 /* 1 octet count of objects. */
775 if (offset
+ sizeof(uint8_t) > len
) {
776 SCLogDebug("Not enough data.");
777 goto not_enough_data
;
779 object
->count
= buf
[offset
];
780 offset
+= sizeof(uint8_t);
783 /* 2 octet count of objects. */
784 if (offset
+ sizeof(uint16_t) > len
) {
785 SCLogDebug("Not enough data.");
786 goto not_enough_data
;
788 object
->count
= DNP3_SWAP16(*(uint16_t *)(buf
+ offset
));
789 offset
+= sizeof(uint16_t);
793 /* 4 octet count of objects. */
794 if (offset
+ sizeof(uint32_t) > len
) {
795 SCLogDebug("Not enough data.");
796 goto not_enough_data
;
798 object
->count
= DNP3_SWAP32(*(uint32_t *)(buf
+ offset
));
799 offset
+= sizeof(uint32_t);
803 if (offset
+ sizeof(uint8_t) > len
) {
804 /* Not enough data. */
805 SCLogDebug("Not enough data.");
806 goto not_enough_data
;
808 object
->count
= *(uint8_t *)(buf
+ offset
);
809 offset
+= sizeof(uint8_t);
813 SCLogDebug("Range code 0x%02x is reserved.",
821 if (object
->variation
== 0 || object
->count
== 0) {
825 int event
= DNP3DecodeObject(header
->group
, header
->variation
, &buf
,
826 &len
, object
->prefix_code
, object
->start
, object
->count
,
829 DNP3SetEventTx(tx
, DNP3_DECODER_EVENT_UNKNOWN_OBJECT
);
837 /* All objects were decoded. */
846 * \brief Handle DNP3 request user data.
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
852 static void DNP3HandleUserDataRequest(DNP3State
*dnp3
, const uint8_t *input
,
856 DNP3TransportHeader th
;
857 DNP3ApplicationHeader
*ah
;
858 DNP3Transaction
*tx
= NULL
, *ttx
;
860 lh
= (DNP3LinkHeader
*)input
;
862 if (!DNP3CheckUserDataCRCs(input
+ sizeof(DNP3LinkHeader
),
863 input_len
- sizeof(DNP3LinkHeader
))) {
867 th
= input
[sizeof(DNP3LinkHeader
)];
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
&&
874 !ttx
->request_done
&&
875 NEXT_TH_SEQNO(DNP3_TH_SEQ(ttx
->request_th
)) == DNP3_TH_SEQ(th
))
886 /* Update the saved transport header so subsequent segments
887 * will be matched to this sequence number. */
888 tx
->response_th
= th
;
891 ah
= (DNP3ApplicationHeader
*)(input
+ sizeof(DNP3LinkHeader
) +
892 sizeof(DNP3TransportHeader
));
894 /* Ignore confirms - for now. */
895 if (ah
->function_code
== DNP3_APP_FC_CONFIRM
) {
899 /* Create a transaction. */
900 tx
= DNP3TxAlloc(dnp3
);
901 if (unlikely(tx
== NULL
)) {
904 tx
->request_lh
= *lh
;
906 tx
->request_ah
= *ah
;
911 if (!DNP3ReassembleApplicationLayer(input
+ sizeof(DNP3LinkHeader
),
912 input_len
- sizeof(DNP3LinkHeader
),
913 &tx
->request_buffer
, &tx
->request_buffer_len
)) {
915 /* Malformed, set event and mark as done. */
916 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_MALFORMED
);
917 tx
->request_done
= 1;
921 /* If this is not the final segment, just return. */
922 if (!DNP3_TH_FIN(th
)) {
926 tx
->request_done
= 1;
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;
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;
949 static void DNP3HandleUserDataResponse(DNP3State
*dnp3
, const uint8_t *input
,
953 DNP3TransportHeader th
;
954 DNP3ApplicationHeader
*ah
;
955 DNP3InternalInd
*iin
;
956 DNP3Transaction
*tx
= NULL
, *ttx
;
959 lh
= (DNP3LinkHeader
*)input
;
960 offset
+= sizeof(DNP3LinkHeader
);
962 if (!DNP3CheckUserDataCRCs(input
+ offset
, input_len
- offset
)) {
966 th
= input
[offset
++];
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
))
984 /* Replace the transport header in the transaction with this
985 * one in case there are more frames. */
986 tx
->response_th
= th
;
989 ah
= (DNP3ApplicationHeader
*)(input
+ offset
);
990 offset
+= sizeof(DNP3ApplicationHeader
);
991 iin
= (DNP3InternalInd
*)(input
+ offset
);
993 if (ah
->function_code
== DNP3_APP_FC_UNSOLICITED_RESP
) {
994 tx
= DNP3TxAlloc(dnp3
);
995 if (unlikely(tx
== NULL
)) {
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;
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
)) {
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
;
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
);
1037 if (!DNP3_TH_FIN(th
)) {
1041 tx
->response_done
= 1;
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;
1052 * \brief Decode the DNP3 request link layer.
1054 * \retval number of bytes processed or -1 if the data stream does not look
1057 static int DNP3HandleRequestLinkLayer(DNP3State
*dnp3
, const uint8_t *input
,
1061 uint32_t processed
= 0;
1065 /* Need at least enough bytes for a DNP3 header. */
1066 if (input_len
< sizeof(DNP3LinkHeader
)) {
1070 DNP3LinkHeader
*header
= (DNP3LinkHeader
*)input
;
1072 if (!DNP3CheckStartBytes(header
)) {
1076 if (!DNP3CheckLinkHeaderCRC(header
)) {
1077 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_BAD_LINK_CRC
);
1081 uint32_t frame_len
= DNP3CalculateLinkLength(header
->len
);
1082 if (frame_len
== 0) {
1083 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_LEN_TOO_SMALL
);
1086 if (input_len
< frame_len
) {
1087 /* Insufficient data, just break - will wait for more data. */
1091 /* Ignore non-user data for now. */
1092 if (!DNP3IsUserData(header
)) {
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
);
1103 if (!DNP3CheckUserDataCRCs(input
+ sizeof(DNP3LinkHeader
),
1104 frame_len
- sizeof(DNP3LinkHeader
))) {
1105 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC
);
1109 DNP3HandleUserDataRequest(dnp3
, input
, frame_len
);
1112 /* Advance the input buffer. */
1114 input_len
-= frame_len
;
1115 processed
+= frame_len
;
1118 SCReturnInt(processed
);
1120 /* Error out. Should only happen if this doesn't look like a DNP3
1126 * \brief Handle incoming request data.
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).
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
)
1138 DNP3State
*dnp3
= (DNP3State
*)state
;
1139 DNP3Buffer
*buffer
= &dnp3
->request_buffer
;
1142 if (input_len
== 0) {
1143 SCReturnStruct(APP_LAYER_OK
);
1147 if (!DNP3BufferAdd(buffer
, input
, input_len
)) {
1148 SCLogError(SC_ERR_MEM_ALLOC
, "Failed to allocate memory to buffer "
1149 "DNP3 request data");
1152 processed
= DNP3HandleRequestLinkLayer(dnp3
,
1153 buffer
->buffer
+ buffer
->offset
,
1154 buffer
->len
- buffer
->offset
);
1155 if (processed
< 0) {
1158 buffer
->offset
+= processed
;
1159 DNP3BufferTrim(buffer
);
1162 processed
= DNP3HandleRequestLinkLayer(dnp3
, input
, input_len
);
1163 if (processed
< 0) {
1164 SCLogDebug("Failed to process request link layer.");
1169 input_len
-= processed
;
1171 /* Not all data was processed, buffer it. */
1173 if (!DNP3BufferAdd(buffer
, input
, input_len
)) {
1174 SCLogError(SC_ERR_MEM_ALLOC
,
1175 "Failed to allocate memory to buffer DNP3 request data");
1181 SCReturnStruct(APP_LAYER_OK
);
1184 /* Reset the buffer. */
1185 DNP3BufferReset(buffer
);
1186 SCReturnStruct(APP_LAYER_ERROR
);
1190 * \brief Decode the DNP3 response link layer.
1192 * \retval number of bytes processed or -1 if the data stream does not
1195 static int DNP3HandleResponseLinkLayer(DNP3State
*dnp3
, const uint8_t *input
,
1199 uint32_t processed
= 0;
1203 /* Need at least enough bytes for a DNP3 header. */
1204 if (input_len
< sizeof(DNP3LinkHeader
)) {
1208 DNP3LinkHeader
*header
= (DNP3LinkHeader
*)input
;
1210 if (!DNP3CheckStartBytes(header
)) {
1214 if (!DNP3CheckLinkHeaderCRC(header
)) {
1215 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_BAD_LINK_CRC
);
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
);
1225 if (input_len
< frame_len
) {
1226 /* Insufficient data, just break - will wait for more data. */
1230 /* Only handle user data frames for now. */
1231 if (!DNP3IsUserData(header
)) {
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
);
1242 if (!DNP3CheckUserDataCRCs(input
+ sizeof(DNP3LinkHeader
),
1243 frame_len
- sizeof(DNP3LinkHeader
))) {
1244 DNP3SetEvent(dnp3
, DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC
);
1248 DNP3HandleUserDataResponse(dnp3
, input
, frame_len
);
1251 /* Advance the input buffer. */
1253 input_len
-= frame_len
;
1254 processed
+= frame_len
;
1257 SCReturnInt(processed
);
1259 /* Error out. Should only happen if the data stream no longer
1260 * looks like DNP3. */
1265 * \brief Parse incoming data.
1267 * This is the entry function for DNP3 application layer data. Its
1268 * main responsibility is buffering incoming data that cannot be
1271 * See DNP3ParseResponsePDUs for DNP3 frame handling.
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
)
1279 DNP3State
*dnp3
= (DNP3State
*)state
;
1280 DNP3Buffer
*buffer
= &dnp3
->response_buffer
;
1284 if (!DNP3BufferAdd(buffer
, input
, input_len
)) {
1285 SCLogError(SC_ERR_MEM_ALLOC
, "Failed to allocate memory to buffer "
1286 "DNP3 response data");
1289 processed
= DNP3HandleResponseLinkLayer(dnp3
,
1290 buffer
->buffer
+ buffer
->offset
,
1291 buffer
->len
- buffer
->offset
);
1292 if (processed
< 0) {
1295 buffer
->offset
+= processed
;
1296 DNP3BufferTrim(buffer
);
1300 /* Check if this is a banner, ignore if it is. */
1301 if (DNP3ContainsBanner(input
, input_len
)) {
1305 processed
= DNP3HandleResponseLinkLayer(dnp3
, input
, input_len
);
1306 if (processed
< 0) {
1310 input_len
-= processed
;
1312 /* Not all data was processed, buffer it. */
1314 if (!DNP3BufferAdd(buffer
, input
, input_len
)) {
1315 SCLogError(SC_ERR_MEM_ALLOC
,
1316 "Failed to allocate memory to buffer DNP3 response data");
1323 SCReturnStruct(APP_LAYER_OK
);
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
);
1332 static void *DNP3GetTx(void *alstate
, uint64_t tx_id
)
1335 DNP3State
*dnp3
= (DNP3State
*)alstate
;
1336 DNP3Transaction
*tx
= NULL
;
1337 uint64_t tx_num
= tx_id
+ 1;
1339 if (dnp3
->curr
&& dnp3
->curr
->tx_num
== (tx_num
)) {
1340 SCReturnPtr(dnp3
->curr
, "void");
1343 TAILQ_FOREACH(tx
, &dnp3
->tx_list
, next
) {
1344 if (tx_num
!= tx
->tx_num
) {
1347 SCReturnPtr(tx
, "void");
1350 SCReturnPtr(NULL
, "void");
1353 static uint64_t DNP3GetTxCnt(void *state
)
1356 uint64_t count
= ((uint64_t)((DNP3State
*)state
)->transaction_max
);
1357 SCReturnUInt(count
);
1361 * \brief Free all the objects in a DNP3ObjectList.
1363 static void DNP3TxFreeObjectList(DNP3ObjectList
*objects
)
1367 while ((object
= TAILQ_FIRST(objects
)) != NULL
) {
1368 TAILQ_REMOVE(objects
, object
, next
);
1369 DNP3ObjectFree(object
);
1374 * \brief Free a DNP3 transaction.
1376 static void DNP3TxFree(DNP3Transaction
*tx
)
1380 if (tx
->request_buffer
!= NULL
) {
1381 SCFree(tx
->request_buffer
);
1384 if (tx
->response_buffer
!= NULL
) {
1385 SCFree(tx
->response_buffer
);
1388 AppLayerDecoderEventsFreeEvents(&tx
->tx_data
.events
);
1390 if (tx
->tx_data
.de_state
!= NULL
) {
1391 DetectEngineStateFree(tx
->tx_data
.de_state
);
1394 DNP3TxFreeObjectList(&tx
->request_objects
);
1395 DNP3TxFreeObjectList(&tx
->response_objects
);
1402 * \brief Free a transaction by ID on a specific DNP3 state.
1404 * This function is called by the app-layer to free a transaction on a
1405 * specific DNP3 state object.
1407 static void DNP3StateTxFree(void *state
, uint64_t tx_id
)
1410 DNP3State
*dnp3
= state
;
1411 DNP3Transaction
*tx
= NULL
, *ttx
;
1412 uint64_t tx_num
= tx_id
+ 1;
1414 TAILQ_FOREACH_SAFE(tx
, &dnp3
->tx_list
, next
, ttx
) {
1416 if (tx
->tx_num
!= tx_num
) {
1420 if (tx
== dnp3
->curr
) {
1424 if (tx
->tx_data
.events
!= NULL
) {
1425 if (tx
->tx_data
.events
->cnt
<= dnp3
->events
) {
1426 dnp3
->events
-= tx
->tx_data
.events
->cnt
;
1433 /* Check flood state. */
1434 if (dnp3
->flooded
&& dnp3
->unreplied
< DNP3_DEFAULT_REQ_FLOOD_COUNT
) {
1438 TAILQ_REMOVE(&dnp3
->tx_list
, tx
, next
);
1447 * \brief Free a DNP3 state.
1449 static void DNP3StateFree(void *state
)
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
);
1459 if (dnp3
->request_buffer
.buffer
!= NULL
) {
1460 SCFree(dnp3
->request_buffer
.buffer
);
1462 if (dnp3
->response_buffer
.buffer
!= NULL
) {
1463 SCFree(dnp3
->response_buffer
.buffer
);
1471 * \brief Called by the app-layer to get the state progress.
1473 static int DNP3GetAlstateProgress(void *tx
, uint8_t direction
)
1475 DNP3Transaction
*dnp3tx
= (DNP3Transaction
*)tx
;
1476 DNP3State
*dnp3
= dnp3tx
->dnp3
;
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.");
1486 if (direction
& STREAM_TOCLIENT
&& dnp3tx
->response_done
) {
1489 else if (direction
& STREAM_TOSERVER
&& dnp3tx
->request_done
) {
1493 SCReturnInt(retval
);
1497 * \brief App-layer support.
1499 static int DNP3StateGetEventInfo(const char *event_name
, int *event_id
,
1500 AppLayerEventType
*event_type
)
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
);
1509 *event_type
= APP_LAYER_EVENT_TYPE_TRANSACTION
;
1515 * \brief App-layer support.
1517 static int DNP3StateGetEventInfoById(int event_id
, const char **event_name
,
1518 AppLayerEventType
*event_type
)
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
);
1527 *event_type
= APP_LAYER_EVENT_TYPE_TRANSACTION
;
1532 static AppLayerTxData
*DNP3GetTxData(void *vtx
)
1534 DNP3Transaction
*tx
= (DNP3Transaction
*)vtx
;
1535 return &tx
->tx_data
;
1539 * \brief Check if the prefix code is a size prefix.
1541 * \retval 1 if the prefix_code specifies a size prefix, 0 if not.
1543 int DNP3PrefixIsSize(uint8_t prefix_code
)
1545 switch (prefix_code
) {
1557 * \brief Register the DNP3 application protocol parser.
1559 void RegisterDNP3Parsers(void)
1563 const char *proto_name
= "dnp3";
1565 if (AppLayerProtoDetectConfProtoDetectionEnabledDefault("tcp", proto_name
, false)) {
1566 AppLayerProtoDetectRegisterProtocol(ALPROTO_DNP3
, proto_name
);
1568 if (RunmodeIsUnittests()) {
1569 AppLayerProtoDetectPPRegister(IPPROTO_TCP
, DNP3_DEFAULT_PORT
,
1570 ALPROTO_DNP3
, 0, sizeof(DNP3LinkHeader
), STREAM_TOSERVER
,
1571 DNP3ProbingParser
, DNP3ProbingParser
);
1574 if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP
,
1575 proto_name
, ALPROTO_DNP3
, 0, sizeof(DNP3LinkHeader
),
1576 DNP3ProbingParser
, DNP3ProbingParser
)) {
1582 SCLogConfig("Protocol detection and parser disabled for DNP3.");
1586 if (AppLayerParserConfParserEnabled("tcp", proto_name
))
1588 SCLogConfig("Registering DNP3/tcp parsers.");
1590 AppLayerParserRegisterParser(IPPROTO_TCP
, ALPROTO_DNP3
, STREAM_TOSERVER
,
1592 AppLayerParserRegisterParser(IPPROTO_TCP
, ALPROTO_DNP3
, STREAM_TOCLIENT
,
1595 AppLayerParserRegisterStateFuncs(IPPROTO_TCP
, ALPROTO_DNP3
,
1596 DNP3StateAlloc
, DNP3StateFree
);
1598 AppLayerParserRegisterGetTx(IPPROTO_TCP
, ALPROTO_DNP3
, DNP3GetTx
);
1599 AppLayerParserRegisterGetTxCnt(IPPROTO_TCP
, ALPROTO_DNP3
, DNP3GetTxCnt
);
1600 AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP
, ALPROTO_DNP3
,
1603 AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP
, ALPROTO_DNP3
,
1604 DNP3GetAlstateProgress
);
1605 AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_DNP3
, 1, 1);
1607 AppLayerParserRegisterGetEventInfo(IPPROTO_TCP
, ALPROTO_DNP3
,
1608 DNP3StateGetEventInfo
);
1609 AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP
, ALPROTO_DNP3
,
1610 DNP3StateGetEventInfoById
);
1612 AppLayerParserRegisterTxDataFunc(IPPROTO_TCP
, ALPROTO_DNP3
,
1616 SCLogConfig("Parser disabled for protocol %s. "
1617 "Protocol detection still on.", proto_name
);
1621 AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP
, ALPROTO_DNP3
,
1622 DNP3ParserRegisterTests
);
1630 #include "flow-util.h"
1631 #include "stream-tcp.h"
1634 * \brief Utility function to fix CRCs when mangling a frame.
1636 static void DNP3FixCrc(uint8_t *data
, uint32_t len
)
1638 uint32_t block_size
;
1641 if (len
>= DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
) {
1642 block_size
= DNP3_BLOCK_SIZE
;
1644 block_size
= len
- DNP3_CRC_LEN
;
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
;
1655 * \test Test CRC checking on partial and full blocks.
1657 static int DNP3ParserTestCheckCRC(void)
1659 uint8_t request
[] = {
1661 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
1664 /* Transport header. */
1667 /* Application layer - segment 1. */
1668 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
1669 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
1672 /* Application layer - segment 2. */
1673 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
1676 /* Check link header CRC. */
1677 FAIL_IF(!DNP3CheckCRC(request
, sizeof(DNP3LinkHeader
)));
1679 /* Check first application layer segment. */
1680 FAIL_IF(!DNP3CheckCRC(request
+ sizeof(DNP3LinkHeader
),
1681 DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
));
1683 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1684 /* Change a byte in link header, should fail now. */
1686 FAIL_IF(DNP3CheckCRC(request
, sizeof(DNP3LinkHeader
)));
1688 /* Change a byte in the first application segment, should fail
1690 request
[sizeof(DNP3LinkHeader
) + 3]++;
1691 FAIL_IF(DNP3CheckCRC(request
+ sizeof(DNP3LinkHeader
),
1692 DNP3_BLOCK_SIZE
+ DNP3_CRC_LEN
));
1699 * \test Test validation of all CRCs in user data.
1701 static int DNP3CheckUserDataCRCsTest(void)
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. */
1711 0xff, 0xc9, 0x05, 0x0c,
1712 0x01, 0x28, 0x01, 0x00,
1713 0x00, 0x00, 0x01, 0x01,
1714 0x01, 0x00, 0x00, 0x00,
1715 0x72, 0xef, /* CRC. */
1717 0xff, 0xc9, 0x05, 0x0c,
1718 0x01, 0x28, 0x01, 0x00,
1719 0x00, 0x00, 0x01, 0x01,
1720 0x01, 0x00, 0x00, 0x00,
1721 0x72, 0xef, /* CRC. */
1723 0x00, 0x00, 0x00, 0x00,
1725 0xff, 0xff, /* CRC. */
1727 FAIL_IF(!DNP3CheckUserDataCRCs(data_valid
, sizeof(data_valid
)));
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. */
1738 0xff, 0xc9, 0x05, 0x0c,
1739 0x01, 0x28, 0x01, 0x00,
1740 0x00, 0x00, 0x01, 0x01,
1741 0x01, 0x00, 0x00, 0x00,
1742 0x72, 0xef, /* CRC. */
1744 0xff, 0xc9, 0x05, 0x0c,
1745 0x01, 0x28, 0x01, 0x00,
1746 0x00, 0x00, 0x01, 0x01,
1747 0x01, 0x00, 0x00, 0x00,
1748 0x72, 0xef, /* CRC. */
1750 0x00, 0x00, 0x00, 0x00,
1751 0x01, /* Invalid byte. */
1752 0xff, 0xff, /* CRC. */
1754 FAIL_IF(DNP3CheckUserDataCRCs(data_invalid
, sizeof(data_invalid
)));
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
)));
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
)));
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
)));
1776 * \test Test the link layer length calculation.
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.
1782 static int DNP3CalculateLinkLengthTest(void)
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);
1791 /* This is the minimum size. */
1792 FAIL_IF(DNP3CalculateLinkLength(5) != 10);
1794 /* 1 full user data blocks of data. */
1795 FAIL_IF(DNP3CalculateLinkLength(21) != 28);
1797 /* 2 full user data blocks of data. */
1798 FAIL_IF(DNP3CalculateLinkLength(37) != 46);
1800 /* 2 full user data blocks, plus one more byte. */
1801 /* 2 full user data blocks of data. */
1802 FAIL_IF(DNP3CalculateLinkLength(38) != 49);
1804 /* The maximum size. */
1805 FAIL_IF(DNP3CalculateLinkLength(255) != 292);
1811 * \test The conversion of length with CRCs to the length without
1814 static int DNP3CalculateTransportLengthWithoutCRCsTest(void)
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);
1824 /* 19 bytes is not enough for a second block. */
1825 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(19) != -1);
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);
1831 FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(21) != 17);
1837 * \test Test the validation of the link header CRC.
1839 static int DNP3ParserCheckLinkHeaderCRC(void)
1841 /* DNP3 frame with valid headers and CRCs. */
1842 uint8_t request
[] = {
1844 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
1847 /* Transport header. */
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
1856 DNP3LinkHeader
*header
= (DNP3LinkHeader
*)request
;
1857 FAIL_IF(!DNP3CheckLinkHeaderCRC(header
));
1859 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1860 /* Alter a byte in the header. */
1862 FAIL_IF(DNP3CheckLinkHeaderCRC(header
));
1869 * \test Test removal of CRCs from user data.
1871 static int DNP3ReassembleApplicationLayerTest01(void)
1873 uint32_t reassembled_len
= 0;
1874 uint8_t *output
= NULL
;
1876 uint8_t payload
[] = {
1878 0xff, 0xc9, 0x05, 0x0c,
1879 0x01, 0x28, 0x01, 0x00,
1880 0x00, 0x00, 0x01, 0x01,
1881 0x01, 0x00, 0x00, 0x00,
1882 0x72, 0xef, /* CRC. */
1884 0xff, 0xc9, 0x05, 0x0c,
1885 0x01, 0x28, 0x01, 0x00,
1886 0x00, 0x00, 0x01, 0x01,
1887 0x01, 0x00, 0x00, 0x00,
1888 0x72, 0xef, /* CRC. */
1890 0xff, 0xc9, 0x05, 0x0c,
1891 0x01, 0x28, 0x01, 0x00,
1892 0x00, 0x00, 0x01, 0x01,
1893 0x01, 0x00, 0x00, 0x00,
1894 0x72, 0xef, /* CRC. */
1896 0x00, 0x00, 0x00, 0x00,
1898 0xff, 0xff, /* CRC. */
1901 uint8_t expected
[] = {
1903 0x01, 0x28, 0x01, 0x00,
1904 0x00, 0x00, 0x01, 0x01,
1905 0x01, 0x00, 0x00, 0x00,
1907 0xff, 0xc9, 0x05, 0x0c,
1908 0x01, 0x28, 0x01, 0x00,
1909 0x00, 0x00, 0x01, 0x01,
1910 0x01, 0x00, 0x00, 0x00,
1912 0xff, 0xc9, 0x05, 0x0c,
1913 0x01, 0x28, 0x01, 0x00,
1914 0x00, 0x00, 0x01, 0x01,
1915 0x01, 0x00, 0x00, 0x00,
1917 0x00, 0x00, 0x00, 0x00,
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
));
1930 /* 1 byte, invalid. */
1931 reassembled_len
= 0;
1933 FAIL_IF(DNP3ReassembleApplicationLayer(payload
, 1, &output
,
1935 FAIL_IF(output
!= NULL
);
1936 FAIL_IF(reassembled_len
!= 0);
1938 /* 2 bytes, invalid. */
1939 reassembled_len
= 0;
1941 FAIL_IF(DNP3ReassembleApplicationLayer(payload
, 2, &output
,
1943 FAIL_IF(output
!= NULL
);
1944 FAIL_IF(reassembled_len
!= 0);
1946 /* 3 bytes, minimum - but that would only be the transport header
1947 * which isn't included in the output. */
1948 reassembled_len
= 0;
1950 FAIL_IF(DNP3ReassembleApplicationLayer(payload
, 3, &output
,
1952 FAIL_IF(output
!= NULL
);
1953 FAIL_IF(reassembled_len
!= 0);
1955 /* 4 bytes is the minimum to get any reassembled data. */
1956 reassembled_len
= 0;
1958 FAIL_IF(!DNP3ReassembleApplicationLayer(payload
, 4, &output
,
1960 FAIL_IF(output
== NULL
);
1961 FAIL_IF(reassembled_len
!= 1);
1963 /* Last block too short (by 1 byte) for data + CRC. */
1964 uint8_t short_payload1
[] = {
1966 0xff, 0xc9, 0x05, 0x0c,
1967 0x01, 0x28, 0x01, 0x00,
1968 0x00, 0x00, 0x01, 0x01,
1969 0x01, 0x00, 0x00, 0x00,
1970 0x72, 0xef, /* CRC. */
1972 0xff, 0xc9, 0x05, 0x0c,
1973 0x01, 0x28, 0x01, 0x00,
1974 0x00, 0x00, 0x01, 0x01,
1975 0x01, 0x00, 0x00, 0x00,
1976 0x72, 0xef, /* CRC. */
1978 0xff, 0xc9, 0x05, 0x0c,
1979 0x01, 0x28, 0x01, 0x00,
1980 0x00, 0x00, 0x01, 0x01,
1981 0x01, 0x00, 0x00, 0x00,
1982 0x72, 0xef, /* CRC. */
1986 reassembled_len
= 0;
1987 FAIL_IF(DNP3ReassembleApplicationLayer(short_payload1
,
1988 sizeof(short_payload1
), &output
, &reassembled_len
));
1990 /* Last block too short (by 2 bytes) for data + CRC. */
1991 uint8_t short_payload2
[] = {
1993 0xff, 0xc9, 0x05, 0x0c,
1994 0x01, 0x28, 0x01, 0x00,
1995 0x00, 0x00, 0x01, 0x01,
1996 0x01, 0x00, 0x00, 0x00,
1997 0x72, 0xef, /* CRC. */
1999 0xff, 0xc9, 0x05, 0x0c,
2000 0x01, 0x28, 0x01, 0x00,
2001 0x00, 0x00, 0x01, 0x01,
2002 0x01, 0x00, 0x00, 0x00,
2003 0x72, 0xef, /* CRC. */
2005 0xff, 0xc9, 0x05, 0x0c,
2006 0x01, 0x28, 0x01, 0x00,
2007 0x00, 0x00, 0x01, 0x01,
2008 0x01, 0x00, 0x00, 0x00,
2009 0x72, 0xef, /* CRC. */
2013 reassembled_len
= 0;
2014 FAIL_IF(DNP3ReassembleApplicationLayer(short_payload2
,
2015 sizeof(short_payload2
), &output
, &reassembled_len
));
2021 * \test Test the probing parser.
2023 static int DNP3ProbingParserTest(void)
2026 0x05, 0x64, 0x05, 0xc9, 0x03, 0x00, 0x04, 0x00,
2032 FAIL_IF(DNP3ProbingParser(NULL
, STREAM_TOSERVER
, pkt
, sizeof(pkt
), &rdir
) != ALPROTO_DNP3
);
2034 /* Send too little bytes. */
2035 FAIL_IF(DNP3ProbingParser(NULL
, STREAM_TOSERVER
, pkt
, sizeof(DNP3LinkHeader
) - 1, &rdir
) != ALPROTO_UNKNOWN
);
2037 /* Bad start bytes. */
2039 FAIL_IF(DNP3ProbingParser(NULL
, STREAM_TOSERVER
, pkt
, sizeof(pkt
), &rdir
) != ALPROTO_FAILED
);
2041 /* Restore start byte. */
2044 /* Set the length to a value less than the minimum length of 5. */
2046 FAIL_IF(DNP3ProbingParser(NULL
, STREAM_TOSERVER
, pkt
, sizeof(pkt
), &rdir
) != ALPROTO_FAILED
);
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
);
2058 * \test Test a basic request/response.
2060 static int DNP3ParserTestRequestResponse(void)
2062 DNP3State
*state
= NULL
;
2064 uint8_t request
[] = {
2066 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2069 /* Transport header. */
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
2078 uint8_t response
[] = {
2080 0x05, 0x64, 0x1c, 0x44, 0x01, 0x00, 0x02, 0x00,
2083 /* Transport header. */
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,
2093 AppLayerParserThreadCtx
*alp_tctx
= AppLayerParserThreadCtxAlloc();
2097 memset(&flow
, 0, sizeof(flow
));
2098 memset(&ssn
, 0, sizeof(ssn
));
2100 flow
.protoctx
= (void *)&ssn
;
2101 flow
.proto
= IPPROTO_TCP
;
2102 flow
.alproto
= ALPROTO_DNP3
;
2104 StreamTcpInitConfig(true);
2106 SCMutexLock(&flow
.m
);
2107 FAIL_IF(AppLayerParserParse(NULL
, alp_tctx
, &flow
, ALPROTO_DNP3
,
2108 STREAM_TOSERVER
, request
, sizeof(request
)));
2109 SCMutexUnlock(&flow
.m
);
2111 state
= flow
.alstate
;
2112 FAIL_IF(state
== NULL
);
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
);
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
);
2130 AppLayerParserThreadCtxFree(alp_tctx
);
2131 StreamTcpFreeConfig(true);
2132 FLOW_DESTROY(&flow
);
2137 * \test Test an unsolicited response from an outstation.
2139 * This is kind of like a request initiated from the "server".
2141 static int DNP3ParserTestUnsolicitedResponseConfirm(void)
2143 DNP3State
*state
= NULL
;
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
2154 uint8_t confirm
[] = {
2155 0x05, 0x64, 0x08, 0xc4, 0x02, 0x00,
2156 0x01, 0x00, 0xd3, 0xb7, 0xc0, 0xda, 0x00, 0x6a,
2160 AppLayerParserThreadCtx
*alp_tctx
= AppLayerParserThreadCtxAlloc();
2164 memset(&flow
, 0, sizeof(flow
));
2165 memset(&ssn
, 0, sizeof(ssn
));
2167 flow
.protoctx
= (void *)&ssn
;
2168 flow
.proto
= IPPROTO_TCP
;
2169 flow
.alproto
= ALPROTO_DNP3
;
2171 StreamTcpInitConfig(true);
2173 SCMutexLock(&flow
.m
);
2174 FAIL_IF(AppLayerParserParse(NULL
, alp_tctx
, &flow
, ALPROTO_DNP3
,
2175 STREAM_TOCLIENT
, response
, sizeof(response
)));
2176 SCMutexUnlock(&flow
.m
);
2178 state
= flow
.alstate
;
2179 FAIL_IF(state
== NULL
);
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
);
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); */
2199 AppLayerParserThreadCtxFree(alp_tctx
);
2200 StreamTcpFreeConfig(true);
2201 FLOW_DESTROY(&flow
);
2206 * \test Test flood state.
2208 static int DNP3ParserTestFlooded(void)
2210 DNP3State
*state
= NULL
;
2212 uint8_t request
[] = {
2214 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2217 /* Transport header. */
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
2226 AppLayerParserThreadCtx
*alp_tctx
= AppLayerParserThreadCtxAlloc();
2230 memset(&flow
, 0, sizeof(flow
));
2231 memset(&ssn
, 0, sizeof(ssn
));
2233 flow
.protoctx
= (void *)&ssn
;
2234 flow
.proto
= IPPROTO_TCP
;
2235 flow
.alproto
= ALPROTO_DNP3
;
2237 StreamTcpInitConfig(true);
2239 SCMutexLock(&flow
.m
);
2240 FAIL_IF(AppLayerParserParse(NULL
, alp_tctx
, &flow
, ALPROTO_DNP3
,
2241 STREAM_TOSERVER
, request
, sizeof(request
)));
2242 SCMutexUnlock(&flow
.m
);
2244 state
= flow
.alstate
;
2245 FAIL_IF(state
== NULL
);
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
);
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
);
2262 FAIL_IF(state
->flooded
);
2263 FAIL_IF(DNP3GetAlstateProgress(tx
, 0));
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
);
2272 /* Progress for the oldest tx should return 1. */
2273 FAIL_IF(!DNP3GetAlstateProgress(tx
, 0));
2275 /* But progress for the current state should still return 0. */
2276 FAIL_IF(DNP3GetAlstateProgress(state
->curr
, 0));
2278 AppLayerParserThreadCtxFree(alp_tctx
);
2279 StreamTcpFreeConfig(true);
2280 FLOW_DESTROY(&flow
);
2285 * \test Test parsing of partial frames.
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.
2291 static int DNP3ParserTestPartialFrame(void)
2293 DNP3State
*state
= NULL
;
2294 DNP3Transaction
*tx
;
2297 uint8_t request_partial1
[] = {
2299 0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2302 /* Transport header. */
2305 /* Application layer. */
2306 0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
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
2315 uint8_t response_partial1
[] = {
2317 0x05, 0x64, 0x1c, 0x44, 0x01, 0x00, 0x02, 0x00,
2320 /* Transport header. */
2323 /* Application layer. */
2324 0xc9, 0x81, 0x00, 0x00, 0x0c, 0x01, 0x28, 0x01,
2327 uint8_t response_partial2
[] = {
2328 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x7a,
2329 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2333 /* Boiler plate for app layer setup. */
2334 AppLayerParserThreadCtx
*alp_tctx
= AppLayerParserThreadCtxAlloc();
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);
2344 /* Pass in the first partial frame. */
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
);
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
)));
2360 /* There should not be a transaction yet. */
2361 FAIL_IF(state
->transaction_max
!= 0);
2362 FAIL_IF(DNP3GetTx(state
, 0) != NULL
);
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
);
2371 /* The second partial completed the frame, the buffer should now
2373 FAIL_IF(state
->request_buffer
.len
!= 0);
2374 FAIL_IF(state
->request_buffer
.offset
!= 0);
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
);
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
);
2391 FAIL_IF(state
->response_buffer
.len
!= sizeof(response_partial1
));
2392 FAIL_IF(state
->response_buffer
.offset
!= 0);
2393 FAIL_IF(tx
->response_done
);
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
);
2402 /* Buffer should now be empty. */
2403 FAIL_IF(state
->response_buffer
.len
!= 0);
2404 FAIL_IF(state
->response_buffer
.offset
!= 0);
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);
2411 AppLayerParserThreadCtxFree(alp_tctx
);
2412 StreamTcpFreeConfig(true);
2413 FLOW_DESTROY(&flow
);
2418 * \test Test multiple DNP3 frames in one TCP read.
2420 static int DNP3ParserTestMultiFrame(void)
2422 DNP3State
*state
= NULL
;
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,
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,
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
));
2446 AppLayerParserThreadCtx
*alp_tctx
= AppLayerParserThreadCtxAlloc();
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);
2457 SCMutexLock(&flow
.m
);
2458 r
= AppLayerParserParse(NULL
, alp_tctx
, &flow
, ALPROTO_DNP3
,
2459 STREAM_TOCLIENT
, combined
, sizeof(combined
));
2460 SCMutexUnlock(&flow
.m
);
2463 state
= flow
.alstate
;
2464 FAIL_IF(state
== NULL
);
2465 FAIL_IF(state
->transaction_max
!= 2);
2467 AppLayerParserThreadCtxFree(alp_tctx
);
2468 StreamTcpFreeConfig(true);
2469 FLOW_DESTROY(&flow
);
2474 * \test Test the parsing of a request PDU.
2476 * The PDU under test contains a single read request object:
2481 static int DNP3ParserTestParsePDU01(void)
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
[] = {
2487 0x0b, 0xc4, 0x17, 0x00, 0xef, 0xff, 0xc4, 0x8f,
2488 0xe1, 0xc8, 0x01, 0x01, 0x00, 0x06, 0x77, 0x6e
2491 DNP3State
*dnp3state
= DNP3StateAlloc(NULL
, ALPROTO_UNKNOWN
);
2492 int pdus
= DNP3HandleRequestLinkLayer(dnp3state
, pkt
, sizeof(pkt
));
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);
2502 DNP3StateFree(dnp3state
);
2507 * \test Test the decode of a DNP3 fragment with a single 70:3 object.
2509 static int DNP3ParserDecodeG70V3Test(void)
2511 const uint8_t pkt
[] = {
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,
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);
2536 FAIL_IF_NOT(tx
->has_request
);
2537 DNP3Object
*obj
= TAILQ_FIRST(&tx
->request_objects
);
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
;
2552 "C:/temp/DNPDeviceConfiguration written to Remote Device.xml") == 0);
2553 DNP3StateFree(dnp3state
);
2558 * \brief Test that an alert is raised on an unknown object.
2560 static int DNP3ParserUnknownEventAlertTest(void)
2562 /* Valid DNP3 frame with 70:3 object. */
2564 0x05, 0x64, 0x63, 0xc4, 0x04, 0x00, 0x03, 0x00,
2569 /* Object and variation. Originally 70:3, now 70:99, an
2570 * unknown object. */
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,
2589 DNP3FixCrc(pkt
+ 10, sizeof(pkt
) - 10);
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
));
2596 DNP3StateFree(dnp3state
);
2601 * \brief Test that an alert is raised on incorrect data.
2603 static int DNP3ParserIncorrectUserData(void)
2605 uint8_t packet_bytes
[] = {
2606 0x05, 0x64, 0x08, 0xc4, 0x03, 0x00, 0x04, 0x00,
2607 0xbf, 0xe9, 0xc1, 0xc1, 0x82, 0xc5, 0xee
2610 AppLayerParserThreadCtx
*alp_tctx
= AppLayerParserThreadCtxAlloc();
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);
2620 int r
= AppLayerParserParse(NULL
, alp_tctx
, &flow
, ALPROTO_DNP3
,
2621 STREAM_TOCLIENT
, packet_bytes
, sizeof(packet_bytes
));
2625 AppLayerParserThreadCtxFree(alp_tctx
);
2626 StreamTcpFreeConfig(true);
2627 FLOW_DESTROY(&flow
);
2633 void DNP3ParserRegisterTests(void)
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
);