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