Coverage Report

Created: 2026-06-30 07:20

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