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  const 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. */
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,
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 AppLayerResult DNP3ParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
1115  const 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) {
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 
1163 
1164 error:
1165  /* Reset the buffer. */
1166  DNP3BufferReset(buffer);
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 AppLayerResult DNP3ParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
1255  const 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:
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);
1310 }
1311 
1312 static AppLayerDecoderEvents *DNP3GetEvents(void *tx)
1313 {
1314  return ((DNP3Transaction *) tx)->decoder_events;
1315 }
1316 
1317 static void *DNP3GetTx(void *alstate, uint64_t tx_id)
1318 {
1319  SCEnter();
1320  DNP3State *dnp3 = (DNP3State *)alstate;
1321  DNP3Transaction *tx = NULL;
1322  uint64_t tx_num = tx_id + 1;
1323 
1324  if (dnp3->curr && dnp3->curr->tx_num == (tx_num)) {
1325  SCReturnPtr(dnp3->curr, "void");
1326  }
1327 
1328  TAILQ_FOREACH(tx, &dnp3->tx_list, next) {
1329  if (tx_num != tx->tx_num) {
1330  continue;
1331  }
1332  SCReturnPtr(tx, "void");
1333  }
1334 
1335  SCReturnPtr(NULL, "void");
1336 }
1337 
1338 static uint64_t DNP3GetTxCnt(void *state)
1339 {
1340  SCEnter();
1341  uint64_t count = ((uint64_t)((DNP3State *)state)->transaction_max);
1342  SCReturnUInt(count);
1343 }
1344 
1345 /**
1346  * \brief Free all the objects in a DNP3ObjectList.
1347  */
1348 static void DNP3TxFreeObjectList(DNP3ObjectList *objects)
1349 {
1350  DNP3Object *object;
1351 
1352  while ((object = TAILQ_FIRST(objects)) != NULL) {
1353  TAILQ_REMOVE(objects, object, next);
1354  DNP3ObjectFree(object);
1355  }
1356 }
1357 
1358 /**
1359  * \brief Free a DNP3 transaction.
1360  */
1361 static void DNP3TxFree(DNP3Transaction *tx)
1362 {
1363  SCEnter();
1364 
1365  if (tx->request_buffer != NULL) {
1366  SCFree(tx->request_buffer);
1367  }
1368 
1369  if (tx->response_buffer != NULL) {
1370  SCFree(tx->response_buffer);
1371  }
1372 
1374 
1375  if (tx->de_state != NULL) {
1377  }
1378 
1379  DNP3TxFreeObjectList(&tx->request_objects);
1380  DNP3TxFreeObjectList(&tx->response_objects);
1381 
1382  SCFree(tx);
1383  SCReturn;
1384 }
1385 
1386 /**
1387  * \brief Free a transaction by ID on a specific DNP3 state.
1388  *
1389  * This function is called by the app-layer to free a transaction on a
1390  * specific DNP3 state object.
1391  */
1392 static void DNP3StateTxFree(void *state, uint64_t tx_id)
1393 {
1394  SCEnter();
1395  DNP3State *dnp3 = state;
1396  DNP3Transaction *tx = NULL, *ttx;
1397  uint64_t tx_num = tx_id + 1;
1398 
1399  TAILQ_FOREACH_SAFE(tx, &dnp3->tx_list, next, ttx) {
1400 
1401  if (tx->tx_num != tx_num) {
1402  continue;
1403  }
1404 
1405  if (tx == dnp3->curr) {
1406  dnp3->curr = NULL;
1407  }
1408 
1409  if (tx->decoder_events != NULL) {
1410  if (tx->decoder_events->cnt <= dnp3->events) {
1411  dnp3->events -= tx->decoder_events->cnt;
1412  }
1413  else {
1414  dnp3->events = 0;
1415  }
1416  }
1417  dnp3->unreplied--;
1418 
1419  /* Check flood state. */
1420  if (dnp3->flooded && dnp3->unreplied < DNP3_DEFAULT_REQ_FLOOD_COUNT) {
1421  dnp3->flooded = 0;
1422  }
1423 
1424  TAILQ_REMOVE(&dnp3->tx_list, tx, next);
1425  DNP3TxFree(tx);
1426  break;
1427  }
1428 
1429  SCReturn;
1430 }
1431 
1432 /**
1433  * \brief Free a DNP3 state.
1434  */
1435 static void DNP3StateFree(void *state)
1436 {
1437  SCEnter();
1438  DNP3State *dnp3 = state;
1439  DNP3Transaction *tx;
1440  if (state != NULL) {
1441  while ((tx = TAILQ_FIRST(&dnp3->tx_list)) != NULL) {
1442  TAILQ_REMOVE(&dnp3->tx_list, tx, next);
1443  DNP3TxFree(tx);
1444  }
1445  if (dnp3->request_buffer.buffer != NULL) {
1446  SCFree(dnp3->request_buffer.buffer);
1447  }
1448  if (dnp3->response_buffer.buffer != NULL) {
1449  SCFree(dnp3->response_buffer.buffer);
1450  }
1451  SCFree(dnp3);
1452  }
1453  SCReturn;
1454 }
1455 
1456 /**
1457  * \brief Called by the app-layer to get the state progress.
1458  */
1459 static int DNP3GetAlstateProgress(void *tx, uint8_t direction)
1460 {
1461  DNP3Transaction *dnp3tx = (DNP3Transaction *)tx;
1462  DNP3State *dnp3 = dnp3tx->dnp3;
1463  int retval = 0;
1464 
1465  /* If flooded, "ack" old transactions. */
1466  if (dnp3->flooded && (dnp3->transaction_max -
1467  dnp3tx->tx_num >= DNP3_DEFAULT_REQ_FLOOD_COUNT)) {
1468  SCLogDebug("flooded: returning tx as done.");
1469  SCReturnInt(1);
1470  }
1471 
1472  if (direction & STREAM_TOCLIENT && dnp3tx->response_done) {
1473  retval = 1;
1474  }
1475  else if (direction & STREAM_TOSERVER && dnp3tx->request_done) {
1476  retval = 1;
1477  }
1478 
1479  SCReturnInt(retval);
1480 }
1481 
1482 /**
1483  * \brief App-layer support.
1484  */
1485 static int DNP3GetAlstateProgressCompletionStatus(uint8_t direction)
1486 {
1487  return 1;
1488 }
1489 
1490 /**
1491  * \brief App-layer support.
1492  */
1493 static int DNP3StateGetEventInfo(const char *event_name, int *event_id,
1494  AppLayerEventType *event_type)
1495 {
1496  *event_id = SCMapEnumNameToValue(event_name, dnp3_decoder_event_table);
1497  if (*event_id == -1) {
1498  SCLogError(SC_ERR_INVALID_ENUM_MAP, "Event \"%s\" not present in "
1499  "the DNP3 enum event map table.", event_name);
1500  return -1;
1501  }
1502 
1503  *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
1504 
1505  return 0;
1506 }
1507 
1508 /**
1509  * \brief App-layer support.
1510  */
1511 static int DNP3StateGetEventInfoById(int event_id, const char **event_name,
1512  AppLayerEventType *event_type)
1513 {
1514  *event_name = SCMapEnumValueToName(event_id, dnp3_decoder_event_table);
1515  if (*event_name == NULL) {
1516  SCLogError(SC_ERR_INVALID_ENUM_MAP, "Event \"%d\" not present in "
1517  "the DNP3 enum event map table.", event_id);
1518  return -1;
1519  }
1520 
1521  *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
1522 
1523  return 0;
1524 }
1525 
1526 /**
1527  * \brief App-layer support.
1528  */
1529 static DetectEngineState *DNP3GetTxDetectState(void *vtx)
1530 {
1531  DNP3Transaction *tx = vtx;
1532  return tx->de_state;
1533 }
1534 
1535 /**
1536  * \brief App-layer support.
1537  */
1538 static int DNP3SetTxDetectState(void *vtx, DetectEngineState *s)
1539 {
1540  DNP3Transaction *tx = vtx;
1541  tx->de_state = s;
1542  return 0;
1543 }
1544 
1545 static void DNP3SetTxLogged(void *alstate, void *vtx, LoggerId logged)
1546 {
1547  DNP3Transaction *tx = (DNP3Transaction *)vtx;
1548  tx->logged = logged;
1549 }
1550 
1551 static LoggerId DNP3GetTxLogged(void *alstate, void *vtx)
1552 {
1553  DNP3Transaction *tx = (DNP3Transaction *)vtx;
1554  return tx->logged;
1555 }
1556 
1557 /**
1558  * \brief Check if the prefix code is a size prefix.
1559  *
1560  * \retval 1 if the prefix_code specifies a size prefix, 0 if not.
1561  */
1562 int DNP3PrefixIsSize(uint8_t prefix_code)
1563 {
1564  switch (prefix_code) {
1565  case 0x04:
1566  case 0x05:
1567  case 0x06:
1568  return 1;
1569  break;
1570  default:
1571  return 0;
1572  }
1573 }
1574 
1575 static uint64_t DNP3GetTxDetectFlags(void *vtx, uint8_t dir)
1576 {
1577  DNP3Transaction *tx = (DNP3Transaction *)vtx;
1578  if (dir & STREAM_TOSERVER) {
1579  return tx->detect_flags_ts;
1580  } else {
1581  return tx->detect_flags_tc;
1582  }
1583 }
1584 
1585 static void DNP3SetTxDetectFlags(void *vtx, uint8_t dir, uint64_t detect_flags)
1586 {
1587  DNP3Transaction *tx = (DNP3Transaction *)vtx;
1588  if (dir & STREAM_TOSERVER) {
1589  tx->detect_flags_ts = detect_flags;
1590  } else {
1591  tx->detect_flags_tc = detect_flags;
1592  }
1593  return;
1594 }
1595 
1596 /**
1597  * \brief Register the DNP3 application protocol parser.
1598  */
1600 {
1601  SCEnter();
1602 
1603  const char *proto_name = "dnp3";
1604 
1605  if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name))
1606  {
1608 
1609  if (RunmodeIsUnittests()) {
1611  ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader), STREAM_TOSERVER,
1612  DNP3ProbingParser, DNP3ProbingParser);
1613  }
1614  else {
1615  if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
1616  proto_name, ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader),
1617  DNP3ProbingParser, DNP3ProbingParser)) {
1618  return;
1619  }
1620  }
1621 
1622  }
1623  else {
1624  SCLogConfig("Protocol detection and parser disabled for DNP3.");
1625  SCReturn;
1626  }
1627 
1628  if (AppLayerParserConfParserEnabled("tcp", proto_name))
1629  {
1630  SCLogConfig("Registering DNP3/tcp parsers.");
1631 
1633  DNP3ParseRequest);
1635  DNP3ParseResponse);
1636 
1638  DNP3StateAlloc, DNP3StateFree);
1639 
1641  DNP3GetEvents);
1643  DNP3GetTxDetectState, DNP3SetTxDetectState);
1645  DNP3GetTxDetectFlags, DNP3SetTxDetectFlags);
1646 
1647  AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTx);
1648  AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxCnt);
1650  DNP3StateTxFree);
1651 
1653  DNP3GetAlstateProgress);
1655  DNP3GetAlstateProgressCompletionStatus);
1656 
1658  DNP3StateGetEventInfo);
1660  DNP3StateGetEventInfoById);
1661 
1663  DNP3GetTxLogged, DNP3SetTxLogged);
1664  }
1665  else {
1666  SCLogConfig("Parser disabled for protocol %s. "
1667  "Protocol detection still on.", proto_name);
1668  }
1669 
1670 #ifdef UNITTESTS
1673 #endif
1674 
1675  SCReturn;
1676 }
1677 
1678 #ifdef UNITTESTS
1679 
1680 #include "flow-util.h"
1681 #include "stream-tcp.h"
1682 
1683 /**
1684  * \brief Utility function to fix CRCs when mangling a frame.
1685  */
1686 static void DNP3FixCrc(uint8_t *data, uint32_t len)
1687 {
1688  uint32_t block_size;
1689 
1690  while (len) {
1691  if (len >= DNP3_BLOCK_SIZE + DNP3_CRC_LEN) {
1692  block_size = DNP3_BLOCK_SIZE;
1693  } else {
1694  block_size = len - DNP3_CRC_LEN;
1695  }
1696  uint16_t crc = DNP3ComputeCRC(data, block_size);
1697  data[block_size + 1] = (crc >> 8) & 0xff;
1698  data[block_size] = crc & 0xff;
1699  data += block_size + DNP3_CRC_LEN;
1700  len -= block_size + DNP3_CRC_LEN;
1701  }
1702 }
1703 
1704 /**
1705  * \test Test CRC checking on partial and full blocks.
1706  */
1707 static int DNP3ParserTestCheckCRC(void)
1708 {
1709  uint8_t request[] = {
1710  /* DNP3 start. */
1711  0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
1712  0xa5, 0xe9,
1713 
1714  /* Transport header. */
1715  0xff,
1716 
1717  /* Application layer - segment 1. */
1718  0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
1719  0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
1720  0xef,
1721 
1722  /* Application layer - segment 2. */
1723  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
1724  };
1725 
1726  /* Check link header CRC. */
1727  FAIL_IF(!DNP3CheckCRC(request, sizeof(DNP3LinkHeader)));
1728 
1729  /* Check first application layer segment. */
1730  FAIL_IF(!DNP3CheckCRC(request + sizeof(DNP3LinkHeader),
1732 
1733  /* Change a byte in link header, should fail now. */
1734  request[2]++;
1735  FAIL_IF(DNP3CheckCRC(request, sizeof(DNP3LinkHeader)));
1736 
1737  /* Change a byte in the first application segment, should fail
1738  * now. */
1739  request[sizeof(DNP3LinkHeader) + 3]++;
1740  FAIL_IF(DNP3CheckCRC(request + sizeof(DNP3LinkHeader),
1742 
1743  PASS;
1744 }
1745 
1746 /**
1747  * \test Test validation of all CRCs in user data.
1748  */
1749 static int DNP3CheckUserDataCRCsTest(void)
1750 {
1751  /* Multi-block data with valid CRCs. */
1752  uint8_t data_valid[] = {
1753  0xff, 0xc9, 0x05, 0x0c,
1754  0x01, 0x28, 0x01, 0x00,
1755  0x00, 0x00, 0x01, 0x01,
1756  0x01, 0x00, 0x00, 0x00,
1757  0x72, 0xef, /* CRC. */
1758 
1759  0xff, 0xc9, 0x05, 0x0c,
1760  0x01, 0x28, 0x01, 0x00,
1761  0x00, 0x00, 0x01, 0x01,
1762  0x01, 0x00, 0x00, 0x00,
1763  0x72, 0xef, /* CRC. */
1764 
1765  0xff, 0xc9, 0x05, 0x0c,
1766  0x01, 0x28, 0x01, 0x00,
1767  0x00, 0x00, 0x01, 0x01,
1768  0x01, 0x00, 0x00, 0x00,
1769  0x72, 0xef, /* CRC. */
1770 
1771  0x00, 0x00, 0x00, 0x00,
1772  0x00,
1773  0xff, 0xff, /* CRC. */
1774  };
1775  FAIL_IF(!DNP3CheckUserDataCRCs(data_valid, sizeof(data_valid)));
1776 
1777  /* Multi-block data with one non-crc byte altered. */
1778  uint8_t data_invalid[] = {
1779  0xff, 0xc9, 0x05, 0x0c,
1780  0x01, 0x28, 0x01, 0x00,
1781  0x00, 0x00, 0x01, 0x01,
1782  0x01, 0x00, 0x00, 0x00,
1783  0x72, 0xef, /* CRC. */
1784 
1785  0xff, 0xc9, 0x05, 0x0c,
1786  0x01, 0x28, 0x01, 0x00,
1787  0x00, 0x00, 0x01, 0x01,
1788  0x01, 0x00, 0x00, 0x00,
1789  0x72, 0xef, /* CRC. */
1790 
1791  0xff, 0xc9, 0x05, 0x0c,
1792  0x01, 0x28, 0x01, 0x00,
1793  0x00, 0x00, 0x01, 0x01,
1794  0x01, 0x00, 0x00, 0x00,
1795  0x72, 0xef, /* CRC. */
1796 
1797  0x00, 0x00, 0x00, 0x00,
1798  0x01, /* Invalid byte. */
1799  0xff, 0xff, /* CRC. */
1800  };
1801  FAIL_IF(DNP3CheckUserDataCRCs(data_invalid, sizeof(data_invalid)));
1802 
1803  /* 1 byte - need at least 3. */
1804  uint8_t one_byte_nocrc[] = { 0x01 };
1805  FAIL_IF(DNP3CheckUserDataCRCs(one_byte_nocrc, sizeof(one_byte_nocrc)));
1806 
1807  /* 2 bytes - need at least 3. */
1808  uint8_t two_byte_nocrc[] = { 0x01, 0x02 };
1809  FAIL_IF(DNP3CheckUserDataCRCs(two_byte_nocrc, sizeof(two_byte_nocrc)));
1810 
1811  /* 3 bytes, valid CRC. */
1812  uint8_t three_bytes_good_crc[] = { 0x00, 0x00, 0x00 };
1813  *(uint16_t *)(three_bytes_good_crc + 1) = DNP3ComputeCRC(
1814  three_bytes_good_crc, 1);
1815  FAIL_IF(!DNP3CheckUserDataCRCs(three_bytes_good_crc,
1816  sizeof(three_bytes_good_crc)));
1817 
1818  PASS;
1819 }
1820 
1821 /**
1822  * \test Test the link layer length calculation.
1823  *
1824  * Test the calculation that converts the link provided in the DNP3
1825  * header to the actual length of the frame. That is the length with
1826  * CRCs as the length in the header does not include CRCs.
1827  */
1828 static int DNP3CalculateLinkLengthTest(void)
1829 {
1830  /* These are invalid. */
1831  FAIL_IF(DNP3CalculateLinkLength(0) != 0);
1832  FAIL_IF(DNP3CalculateLinkLength(1) != 0);
1833  FAIL_IF(DNP3CalculateLinkLength(2) != 0);
1834  FAIL_IF(DNP3CalculateLinkLength(3) != 0);
1835  FAIL_IF(DNP3CalculateLinkLength(4) != 0);
1836 
1837  /* This is the minimum size. */
1838  FAIL_IF(DNP3CalculateLinkLength(5) != 10);
1839 
1840  /* 1 full user data blocks of data. */
1841  FAIL_IF(DNP3CalculateLinkLength(21) != 28);
1842 
1843  /* 2 full user data blocks of data. */
1844  FAIL_IF(DNP3CalculateLinkLength(37) != 46);
1845 
1846  /* 2 full user data blocks, plus one more byte. */
1847  /* 2 full user data blocks of data. */
1848  FAIL_IF(DNP3CalculateLinkLength(38) != 49);
1849 
1850  /* The maximum size. */
1851  FAIL_IF(DNP3CalculateLinkLength(255) != 292);
1852 
1853  PASS;
1854 }
1855 
1856 /**
1857  * \test The conversion of length with CRCs to the length without
1858  * CRCs.
1859  */
1860 static int DNP3CalculateTransportLengthWithoutCRCsTest(void)
1861 {
1862  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(0) != -1);
1863  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(1) != -1);
1864  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(2) != 0);
1865  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(3) != 1);
1866  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(16) != 14);
1867  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(17) != 15);
1868  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(18) != 16);
1869 
1870  /* 19 bytes is not enough for a second block. */
1871  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(19) != -1);
1872 
1873  /* 20 bytes really isn't enough either, but is large enough to
1874  * satisfy the CRC on the second block. */
1875  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(20) != 16);
1876 
1877  FAIL_IF(DNP3CalculateTransportLengthWithoutCRCs(21) != 17);
1878 
1879  PASS;
1880 }
1881 
1882 /**
1883  * \test Test the validation of the link header CRC.
1884  */
1885 static int DNP3ParserCheckLinkHeaderCRC(void)
1886 {
1887  /* DNP3 frame with valid headers and CRCs. */
1888  uint8_t request[] = {
1889  /* DNP3 start. */
1890  0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
1891  0xa5, 0xe9,
1892 
1893  /* Transport header. */
1894  0xff,
1895 
1896  /* Application layer. */
1897  0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
1898  0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
1899  0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
1900  };
1901 
1902  DNP3LinkHeader *header = (DNP3LinkHeader *)request;
1903  FAIL_IF(!DNP3CheckLinkHeaderCRC(header));
1904 
1905  /* Alter a byte in the header. */
1906  request[4] = 0;
1907  FAIL_IF(DNP3CheckLinkHeaderCRC(header));
1908 
1909  PASS;
1910 }
1911 
1912 /**
1913  * \test Test removal of CRCs from user data.
1914  */
1915 static int DNP3ReassembleApplicationLayerTest01(void)
1916 {
1917  uint32_t reassembled_len = 0;
1918  uint8_t *output = NULL;
1919 
1920  uint8_t payload[] = {
1921 
1922  0xff, 0xc9, 0x05, 0x0c,
1923  0x01, 0x28, 0x01, 0x00,
1924  0x00, 0x00, 0x01, 0x01,
1925  0x01, 0x00, 0x00, 0x00,
1926  0x72, 0xef, /* CRC. */
1927 
1928  0xff, 0xc9, 0x05, 0x0c,
1929  0x01, 0x28, 0x01, 0x00,
1930  0x00, 0x00, 0x01, 0x01,
1931  0x01, 0x00, 0x00, 0x00,
1932  0x72, 0xef, /* CRC. */
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  0x00, 0x00, 0x00, 0x00,
1941  0x00,
1942  0xff, 0xff, /* CRC. */
1943  };
1944 
1945  uint8_t expected[] = {
1946  0xc9, 0x05, 0x0c,
1947  0x01, 0x28, 0x01, 0x00,
1948  0x00, 0x00, 0x01, 0x01,
1949  0x01, 0x00, 0x00, 0x00,
1950  /* CRC removed. */
1951  0xff, 0xc9, 0x05, 0x0c,
1952  0x01, 0x28, 0x01, 0x00,
1953  0x00, 0x00, 0x01, 0x01,
1954  0x01, 0x00, 0x00, 0x00,
1955  /* CRC removed. */
1956  0xff, 0xc9, 0x05, 0x0c,
1957  0x01, 0x28, 0x01, 0x00,
1958  0x00, 0x00, 0x01, 0x01,
1959  0x01, 0x00, 0x00, 0x00,
1960  /* CRC removed. */
1961  0x00, 0x00, 0x00, 0x00,
1962  0x00
1963  /* CRC removed. */
1964  };
1965 
1966  /* Valid frame. */
1967  FAIL_IF(!DNP3ReassembleApplicationLayer(payload,
1968  sizeof(payload), &output, &reassembled_len));
1969  FAIL_IF(output == NULL);
1970  FAIL_IF(reassembled_len != sizeof(expected));
1971  FAIL_IF(memcmp(expected, output, reassembled_len));
1972  SCFree(output);
1973 
1974  /* 1 byte, invalid. */
1975  reassembled_len = 0;
1976  output = NULL;
1977  FAIL_IF(DNP3ReassembleApplicationLayer(payload, 1, &output,
1978  &reassembled_len));
1979  FAIL_IF(output != NULL);
1980  FAIL_IF(reassembled_len != 0);
1981 
1982  /* 2 bytes, invalid. */
1983  reassembled_len = 0;
1984  output = NULL;
1985  FAIL_IF(DNP3ReassembleApplicationLayer(payload, 2, &output,
1986  &reassembled_len));
1987  FAIL_IF(output != NULL);
1988  FAIL_IF(reassembled_len != 0);
1989 
1990  /* 3 bytes, minimum - but that would only be the transport header
1991  * which isn't included in the output. */
1992  reassembled_len = 0;
1993  output = NULL;
1994  FAIL_IF(DNP3ReassembleApplicationLayer(payload, 3, &output,
1995  &reassembled_len));
1996  FAIL_IF(output != NULL);
1997  FAIL_IF(reassembled_len != 0);
1998 
1999  /* 4 bytes is the minimum to get any reassembled data. */
2000  reassembled_len = 0;
2001  output = NULL;
2002  FAIL_IF(!DNP3ReassembleApplicationLayer(payload, 4, &output,
2003  &reassembled_len));
2004  FAIL_IF(output == NULL);
2005  FAIL_IF(reassembled_len != 1);
2006 
2007  /* Last block too short (by 1 byte) for data + CRC. */
2008  uint8_t short_payload1[] = {
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, 0x00
2029  };
2030  reassembled_len = 0;
2031  FAIL_IF(DNP3ReassembleApplicationLayer(short_payload1,
2032  sizeof(short_payload1), &output, &reassembled_len));
2033 
2034  /* Last block too short (by 2 bytes) for data + CRC. */
2035  uint8_t short_payload2[] = {
2036 
2037  0xff, 0xc9, 0x05, 0x0c,
2038  0x01, 0x28, 0x01, 0x00,
2039  0x00, 0x00, 0x01, 0x01,
2040  0x01, 0x00, 0x00, 0x00,
2041  0x72, 0xef, /* CRC. */
2042 
2043  0xff, 0xc9, 0x05, 0x0c,
2044  0x01, 0x28, 0x01, 0x00,
2045  0x00, 0x00, 0x01, 0x01,
2046  0x01, 0x00, 0x00, 0x00,
2047  0x72, 0xef, /* CRC. */
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  0x00,
2056  };
2057  reassembled_len = 0;
2058  FAIL_IF(DNP3ReassembleApplicationLayer(short_payload2,
2059  sizeof(short_payload2), &output, &reassembled_len));
2060 
2061  PASS;
2062 }
2063 
2064 /**
2065  * \test Test the probing parser.
2066  */
2067 static int DNP3ProbingParserTest(void)
2068 {
2069  uint8_t pkt[] = {
2070  0x05, 0x64, 0x05, 0xc9, 0x03, 0x00, 0x04, 0x00,
2071  0xbd, 0x71
2072  };
2073  uint8_t rdir = 0;
2074 
2075  /* Valid frame. */
2076  FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(pkt), &rdir) != ALPROTO_DNP3);
2077 
2078  /* Send too little bytes. */
2079  FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(DNP3LinkHeader) - 1, &rdir) != ALPROTO_UNKNOWN);
2080 
2081  /* Bad start bytes. */
2082  pkt[0] = 0x06;
2083  FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(pkt), &rdir) != ALPROTO_FAILED);
2084 
2085  /* Restore start byte. */
2086  pkt[0] = 0x05;
2087 
2088  /* Set the length to a value less than the minimum length of 5. */
2089  pkt[2] = 0x03;
2090  FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, pkt, sizeof(pkt), &rdir) != ALPROTO_FAILED);
2091 
2092  /* Send a banner. */
2093  char mybanner[] = "Welcome to DNP3 SCADA.";
2094  FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, (uint8_t *)mybanner, sizeof(mybanner), &rdir) != ALPROTO_DNP3);
2095 
2096  PASS;
2097 }
2098 
2099 /**
2100  * \test Test a basic request/response.
2101  */
2102 static int DNP3ParserTestRequestResponse(void)
2103 {
2104  DNP3State *state = NULL;
2105 
2106  uint8_t request[] = {
2107  /* DNP3 start. */
2108  0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2109  0xa5, 0xe9,
2110 
2111  /* Transport header. */
2112  0xff,
2113 
2114  /* Application layer. */
2115  0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
2116  0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
2117  0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
2118  };
2119 
2120  uint8_t response[] = {
2121  /* DNP3 start. */
2122  0x05, 0x64, 0x1c, 0x44, 0x01, 0x00, 0x02, 0x00,
2123  0xe2, 0x59,
2124 
2125  /* Transport header. */
2126  0xc3,
2127 
2128  /* Application layer. */
2129  0xc9, 0x81, 0x00, 0x00, 0x0c, 0x01, 0x28, 0x01,
2130  0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x7a,
2131  0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2132  0xff, 0xff
2133  };
2134 
2136  Flow flow;
2137  TcpSession ssn;
2138 
2139  memset(&flow, 0, sizeof(flow));
2140  memset(&ssn, 0, sizeof(ssn));
2141 
2142  flow.protoctx = (void *)&ssn;
2143  flow.proto = IPPROTO_TCP;
2144  flow.alproto = ALPROTO_DNP3;
2145 
2147 
2148  SCMutexLock(&flow.m);
2150  STREAM_TOSERVER, request, sizeof(request)));
2151  SCMutexUnlock(&flow.m);
2152 
2153  state = flow.alstate;
2154  FAIL_IF(state == NULL);
2155 
2156  DNP3Transaction *tx = DNP3GetTx(state, 0);
2157  FAIL_IF(tx == NULL);
2158  FAIL_IF(tx->tx_num != 1);
2159  FAIL_IF(tx != state->curr);
2160  FAIL_IF(tx->request_buffer == NULL);
2161  FAIL_IF(tx->request_buffer_len != 20);
2162  FAIL_IF(tx->request_ah.function_code != DNP3_APP_FC_DIR_OPERATE);
2163 
2164  SCMutexLock(&flow.m);
2166  STREAM_TOCLIENT, response, sizeof(response)));
2167  SCMutexUnlock(&flow.m);
2168  FAIL_IF(DNP3GetTx(state, 0) != tx);
2169  FAIL_IF(!tx->response_done);
2170  FAIL_IF(tx->response_buffer == NULL);
2171 
2174  FLOW_DESTROY(&flow);
2175  PASS;
2176 }
2177 
2178 /**
2179  * \test Test an unsolicited response from an outstation.
2180  *
2181  * This is kind of like a request initiated from the "server".
2182  */
2183 static int DNP3ParserTestUnsolicitedResponseConfirm(void)
2184 {
2185  DNP3State *state = NULL;
2186 
2187  /* Unsolicited response with confirm bit set. */
2188  uint8_t response[] = {
2189  0x05, 0x64, 0x16, 0x44, 0x01, 0x00, 0x02, 0x00,
2190  0x89, 0xe5, 0xc4, 0xfa, 0x82, 0x00, 0x00, 0x02,
2191  0x02, 0x17, 0x01, 0x01, 0x81, 0xa7, 0x75, 0xd8,
2192  0x32, 0x4c, 0x81, 0x3e, 0x01, 0xa1, 0xc9
2193  };
2194 
2195  /* Confirm. */
2196  uint8_t confirm[] = {
2197  0x05, 0x64, 0x08, 0xc4, 0x02, 0x00,
2198  0x01, 0x00, 0xd3, 0xb7, 0xc0, 0xda, 0x00, 0x6a,
2199  0x3d
2200  };
2201 
2203  Flow flow;
2204  TcpSession ssn;
2205 
2206  memset(&flow, 0, sizeof(flow));
2207  memset(&ssn, 0, sizeof(ssn));
2208 
2209  flow.protoctx = (void *)&ssn;
2210  flow.proto = IPPROTO_TCP;
2211  flow.alproto = ALPROTO_DNP3;
2212 
2214 
2215  SCMutexLock(&flow.m);
2217  STREAM_TOCLIENT, response, sizeof(response)));
2218  SCMutexUnlock(&flow.m);
2219 
2220  state = flow.alstate;
2221  FAIL_IF(state == NULL);
2222 
2223  DNP3Transaction *tx = DNP3GetTx(state, 0);
2224  FAIL_IF(tx == NULL);
2225  FAIL_IF(tx->tx_num != 1);
2226  FAIL_IF(tx != state->curr);
2227  FAIL_IF(tx->request_buffer != NULL);
2228  FAIL_IF(tx->response_buffer == NULL);
2229  FAIL_IF(!tx->response_done);
2230  FAIL_IF(tx->response_ah.function_code != DNP3_APP_FC_UNSOLICITED_RESP);
2231 
2232  SCMutexLock(&flow.m);
2234  STREAM_TOSERVER, confirm, sizeof(confirm)));
2235  SCMutexUnlock(&flow.m);
2236  FAIL_IF(DNP3GetTx(state, 0) != tx);
2237  FAIL_IF(!tx->response_done);
2238  FAIL_IF(tx->response_buffer == NULL);
2239  /* FAIL_IF(tx->iin1 != 0 || tx->iin2 != 0); */
2240 
2243  FLOW_DESTROY(&flow);
2244  PASS;
2245 }
2246 
2247 /**
2248  * \test Test flood state.
2249  */
2250 static int DNP3ParserTestFlooded(void)
2251 {
2252  DNP3State *state = NULL;
2253 
2254  uint8_t request[] = {
2255  /* DNP3 start. */
2256  0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2257  0xa5, 0xe9,
2258 
2259  /* Transport header. */
2260  0xff,
2261 
2262  /* Application layer. */
2263  0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
2264  0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
2265  0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
2266  };
2267 
2269  Flow flow;
2270  TcpSession ssn;
2271 
2272  memset(&flow, 0, sizeof(flow));
2273  memset(&ssn, 0, sizeof(ssn));
2274 
2275  flow.protoctx = (void *)&ssn;
2276  flow.proto = IPPROTO_TCP;
2277  flow.alproto = ALPROTO_DNP3;
2278 
2280 
2281  SCMutexLock(&flow.m);
2283  STREAM_TOSERVER, request, sizeof(request)));
2284  SCMutexUnlock(&flow.m);
2285 
2286  state = flow.alstate;
2287  FAIL_IF(state == NULL);
2288 
2289  DNP3Transaction *tx = DNP3GetTx(state, 0);
2290  FAIL_IF(tx == NULL);
2291  FAIL_IF(tx->tx_num != 1);
2292  FAIL_IF(tx != state->curr);
2293  FAIL_IF(tx->request_buffer == NULL);
2294  FAIL_IF(tx->request_buffer_len != 20);
2295  /* FAIL_IF(tx->app_function_code != DNP3_APP_FC_DIR_OPERATE); */
2296  FAIL_IF(tx->response_done);
2297 
2298  for (int i = 0; i < DNP3_DEFAULT_REQ_FLOOD_COUNT - 1; i++) {
2299  SCMutexLock(&flow.m);
2301  STREAM_TOSERVER, request, sizeof(request)));
2302  SCMutexUnlock(&flow.m);
2303  }
2304  FAIL_IF(state->flooded);
2305  FAIL_IF(DNP3GetAlstateProgress(tx, 0));
2306 
2307  /* One more request should trip us into flooded state. */
2308  SCMutexLock(&flow.m);
2310  STREAM_TOSERVER, request, sizeof(request)));
2311  SCMutexUnlock(&flow.m);
2312  FAIL_IF(!state->flooded);
2313 
2314  /* Progress for the oldest tx should return 1. */
2315  FAIL_IF(!DNP3GetAlstateProgress(tx, 0));
2316 
2317  /* But progress for the current state should still return 0. */
2318  FAIL_IF(DNP3GetAlstateProgress(state->curr, 0));
2319 
2322  FLOW_DESTROY(&flow);
2323  PASS;
2324 }
2325 
2326 /**
2327  * \test Test parsing of partial frames.
2328  *
2329  * As DNP3 operates over TCP, it is possible that a partial DNP3 frame
2330  * is received. Test that the partial frame will be buffered until the
2331  * remainder is seen.
2332  */
2333 static int DNP3ParserTestPartialFrame(void)
2334 {
2335  DNP3State *state = NULL;
2336  DNP3Transaction *tx;
2337  int r;
2338 
2339  uint8_t request_partial1[] = {
2340  /* DNP3 start. */
2341  0x05, 0x64, 0x1a, 0xc4, 0x02, 0x00, 0x01, 0x00,
2342  0xa5, 0xe9,
2343 
2344  /* Transport header. */
2345  0xff,
2346 
2347  /* Application layer. */
2348  0xc9, 0x05, 0x0c, 0x01, 0x28, 0x01, 0x00, 0x00,
2349  };
2350 
2351  uint8_t request_partial2[] = {
2352  /* Remainder of application layer. */
2353  0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x72,
2354  0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
2355  };
2356 
2357  uint8_t response_partial1[] = {
2358  /* DNP3 start. */
2359  0x05, 0x64, 0x1c, 0x44, 0x01, 0x00, 0x02, 0x00,
2360  0xe2, 0x59,
2361 
2362  /* Transport header. */
2363  0xc3,
2364 
2365  /* Application layer. */
2366  0xc9, 0x81, 0x00, 0x00, 0x0c, 0x01, 0x28, 0x01,
2367  };
2368 
2369  uint8_t response_partial2[] = {
2370  0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x7a,
2371  0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2372  0xff, 0xff
2373  };
2374 
2375  /* Boiler plate for app layer setup. */
2377  Flow flow;
2378  TcpSession ssn;
2379  memset(&flow, 0, sizeof(flow));
2380  memset(&ssn, 0, sizeof(ssn));
2381  flow.protoctx = (void *)&ssn;
2382  flow.proto = IPPROTO_TCP;
2383  flow.alproto = ALPROTO_DNP3;
2385 
2386  /* Pass in the first partial frame. */
2387 
2388  SCMutexLock(&flow.m);
2389  r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2390  STREAM_TOSERVER, request_partial1, sizeof(request_partial1));
2391  SCMutexUnlock(&flow.m);
2392  FAIL_IF(r != 0);
2393 
2394  /* Frame should just be buffered, but not yet processed. */
2395  state = flow.alstate;
2396  FAIL_IF(state == NULL);
2397  FAIL_IF(state->request_buffer.len != sizeof(request_partial1));
2398  FAIL_IF(state->request_buffer.offset != 0);
2399  FAIL_IF(memcmp(state->request_buffer.buffer, request_partial1,
2400  sizeof(request_partial1)));
2401 
2402  /* There should not be a transaction yet. */
2403  FAIL_IF(state->transaction_max != 0);
2404  FAIL_IF(DNP3GetTx(state, 0) != NULL);
2405 
2406  /* Send the second partial. */
2407  SCMutexLock(&flow.m);
2408  r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2409  STREAM_TOSERVER, request_partial2, sizeof(request_partial2));
2410  SCMutexUnlock(&flow.m);
2411  FAIL_IF(r != 0);
2412 
2413  /* The second partial completed the frame, the buffer should now
2414  * be clear. */
2415  FAIL_IF(state->request_buffer.len != 0);
2416  FAIL_IF(state->request_buffer.offset != 0);
2417 
2418  /* Should now have a complete transaction. */
2419  tx = DNP3GetTx(state, 0);
2420  FAIL_IF(tx == NULL);
2421  FAIL_IF(tx->tx_num != 1);
2422  FAIL_IF(tx != state->curr);
2423  FAIL_IF(tx->request_buffer == NULL);
2424  FAIL_IF(tx->request_buffer_len != 20);
2425  FAIL_IF(tx->request_ah.function_code != DNP3_APP_FC_DIR_OPERATE);
2426 
2427  /* Send partial response. */
2428  SCMutexLock(&flow.m);
2429  r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2430  STREAM_TOCLIENT, response_partial1, sizeof(response_partial1));
2431  SCMutexUnlock(&flow.m);
2432  FAIL_IF(r != 0);
2433  FAIL_IF(state->response_buffer.len != sizeof(response_partial1));
2434  FAIL_IF(state->response_buffer.offset != 0);
2435  FAIL_IF(tx->response_done);
2436 
2437  /* Send rest of response. */
2438  SCMutexLock(&flow.m);
2439  r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2440  STREAM_TOCLIENT, response_partial2, sizeof(response_partial2));
2441  SCMutexUnlock(&flow.m);
2442  FAIL_IF(r != 0);
2443 
2444  /* Buffer should now be empty. */
2445  FAIL_IF(state->response_buffer.len != 0);
2446  FAIL_IF(state->response_buffer.offset != 0);
2447 
2448  /* Transaction should be replied to now. */
2449  FAIL_IF(!tx->response_done);
2450  FAIL_IF(tx->response_buffer == NULL);
2451  FAIL_IF(tx->response_buffer_len == 0);
2452 
2455  FLOW_DESTROY(&flow);
2456  PASS;
2457 }
2458 
2459 /**
2460  * \test Test multiple DNP3 frames in one TCP read.
2461  */
2462 static int DNP3ParserTestMultiFrame(void)
2463 {
2464  DNP3State *state = NULL;
2465 
2466  /* Unsolicited response 1. */
2467  uint8_t unsol_response1[] = {
2468  0x05, 0x64, 0x16, 0x44, 0x01, 0x00, 0x02, 0x00,
2469  0x89, 0xe5, 0xc4, 0xfa, 0x82, 0x00, 0x00, 0x02,
2470  0x02, 0x17, 0x01, 0x01, 0x81, 0xa7, 0x75, 0xd8,
2471  0x32, 0x4c, 0x81, 0x3e, 0x01, 0xa1, 0xc9,
2472  };
2473 
2474  /* Unsolicited response 2. */
2475  uint8_t unsol_response2[] = {
2476  0x05, 0x64, 0x16, 0x44, 0x01, 0x00, 0x02, 0x00,
2477  0x89, 0xe5, 0xc5, 0xfb, 0x82, 0x00, 0x00, 0x02,
2478  0x02, 0x17, 0x01, 0x0c, 0x01, 0xd8, 0x75, 0xd8,
2479  0x32, 0x4c, 0xc9, 0x3c, 0x01, 0xa1, 0xc9,
2480  };
2481 
2482  uint8_t combined[sizeof(unsol_response1) + sizeof(unsol_response2)];
2483  memcpy(combined, unsol_response1, sizeof(unsol_response1));
2484  memcpy(combined + sizeof(unsol_response1), unsol_response2,
2485  sizeof(unsol_response2));
2486 
2487  /* Setup. */
2489  Flow flow;
2490  TcpSession ssn;
2491  int r;
2492  memset(&flow, 0, sizeof(flow));
2493  memset(&ssn, 0, sizeof(ssn));
2494  flow.protoctx = (void *)&ssn;
2495  flow.proto = IPPROTO_TCP;
2496  flow.alproto = ALPROTO_DNP3;
2498 
2499  SCMutexLock(&flow.m);
2500  r = AppLayerParserParse(NULL, alp_tctx, &flow, ALPROTO_DNP3,
2501  STREAM_TOCLIENT, combined, sizeof(combined));
2502  SCMutexUnlock(&flow.m);
2503  FAIL_IF(r != 0);
2504 
2505  state = flow.alstate;
2506  FAIL_IF(state == NULL);
2507  FAIL_IF(state->transaction_max != 2);
2508 
2511  FLOW_DESTROY(&flow);
2512  PASS;
2513 }
2514 
2515 /**
2516  * \test Test the parsing of a request PDU.
2517  *
2518  * The PDU under test contains a single read request object:
2519  * - Group: 1
2520  * - Variation: 0
2521  * - Count: 0
2522  */
2523 static int DNP3ParserTestParsePDU01(void)
2524 {
2525  /* Frame to be tested. This frame is a DNP3 request with one read
2526  * request data object, group 1, variation 0. */
2527  const uint8_t pkt[] = {
2528  0x05, 0x64,
2529  0x0b, 0xc4, 0x17, 0x00, 0xef, 0xff, 0xc4, 0x8f,
2530  0xe1, 0xc8, 0x01, 0x01, 0x00, 0x06, 0x77, 0x6e
2531  };
2532 
2533  DNP3State *dnp3state = DNP3StateAlloc();
2534  int pdus = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
2535  FAIL_IF(pdus < 1);
2536  DNP3Transaction *dnp3tx = DNP3GetTx(dnp3state, 0);
2537  FAIL_IF_NULL(dnp3tx);
2538  FAIL_IF(!dnp3tx->has_request);
2539  FAIL_IF(TAILQ_EMPTY(&dnp3tx->request_objects));
2540  DNP3Object *object = TAILQ_FIRST(&dnp3tx->request_objects);
2541  FAIL_IF(object->group != 1 || object->variation != 0);
2542  FAIL_IF(object->count != 0);
2543 
2544  DNP3StateFree(dnp3state);
2545  PASS;
2546 }
2547 
2548 /**
2549  * \test Test the decode of a DNP3 fragment with a single 70:3 object.
2550  */
2551 static int DNP3ParserDecodeG70V3Test(void)
2552 {
2553  const uint8_t pkt[] = {
2554  0x05, 0x64,
2555  0x63, 0xc4, 0x04, 0x00, 0x03, 0x00, 0xc7, 0xee,
2556  0xc7, 0xc9, 0x1b, 0x46, 0x03, 0x5b, 0x01, 0x55,
2557  0x00, 0x1a, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00,
2558  0x9e, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2559  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560  0x00, 0x00, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x43,
2561  0x3a, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x2f, 0x44,
2562  0x4e, 0x50, 0x44, 0x65, 0x67, 0x7d, 0x76, 0x69,
2563  0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
2564  0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x93, 0x0c,
2565  0x6e, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65,
2566  0x6e, 0x20, 0x74, 0x6f, 0x20, 0x52, 0x65, 0x6d,
2567  0x35, 0x20, 0x6f, 0x74, 0x65, 0x20, 0x44, 0x65,
2568  0x76, 0x69, 0x63, 0x65, 0x2e, 0x78, 0x6d, 0x6c,
2569  0xc4, 0x8b
2570  };
2571 
2572  DNP3State *dnp3state = DNP3StateAlloc();
2573  FAIL_IF_NULL(dnp3state);
2574  int bytes = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
2575  FAIL_IF(bytes != sizeof(pkt));
2576  DNP3Transaction *tx = DNP3GetTx(dnp3state, 0);
2577  FAIL_IF_NULL(tx);
2578  FAIL_IF_NOT(tx->has_request);
2579  DNP3Object *obj = TAILQ_FIRST(&tx->request_objects);
2580  FAIL_IF_NULL(obj);
2581  FAIL_IF_NOT(obj->group == 70);
2582  FAIL_IF_NOT(obj->variation == 3);
2583  FAIL_IF_NOT(obj->prefix_code == 0x5);
2584  FAIL_IF_NOT(obj->range_code == 0xb);
2585  FAIL_IF_NOT(obj->count == 1);
2586  DNP3Point *point = TAILQ_FIRST(obj->points);
2587  FAIL_IF_NULL(point);
2588  FAIL_IF_NOT(point->prefix == 85);
2589  FAIL_IF_NOT(point->size == 85);
2590  FAIL_IF_NULL(point->data);
2591  DNP3ObjectG70V3 *data = point->data;
2592  FAIL_IF_NOT(strcmp(
2593  data->filename,
2594  "C:/temp/DNPDeviceConfiguration written to Remote Device.xml") == 0);
2595  DNP3StateFree(dnp3state);
2596  PASS;
2597 }
2598 
2599 /**
2600  * \brief Test that an alert is raised on an unknown object.
2601  */
2602 static int DNP3ParserUnknownEventAlertTest(void)
2603 {
2604  /* Valid DNP3 frame with 70:3 object. */
2605  uint8_t pkt[] = {
2606  0x05, 0x64, 0x63, 0xc4, 0x04, 0x00, 0x03, 0x00,
2607  0xc7, 0xee,
2608 
2609  0xc7, 0xc9, 0x1b,
2610 
2611  /* Object and variation. Originally 70:3, now 70:99, an
2612  * unknown object. */
2613  0x46, 0x63,
2614 
2615  0x5b, 0x01, 0x55,
2616  0x00, 0x1a, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00,
2617  0x9e, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2618  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2619  0x00, 0x00, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x43,
2620  0x3a, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x2f, 0x44,
2621  0x4e, 0x50, 0x44, 0x65, 0x67, 0x7d, 0x76, 0x69,
2622  0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
2623  0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x93, 0x0c,
2624  0x6e, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65,
2625  0x6e, 0x20, 0x74, 0x6f, 0x20, 0x52, 0x65, 0x6d,
2626  0x35, 0x20, 0x6f, 0x74, 0x65, 0x20, 0x44, 0x65,
2627  0x76, 0x69, 0x63, 0x65, 0x2e, 0x78, 0x6d, 0x6c,
2628  0xc4, 0x8b
2629  };
2630 
2631  DNP3FixCrc(pkt + 10, sizeof(pkt) - 10);
2632 
2633  DNP3State *dnp3state = DNP3StateAlloc();
2634  FAIL_IF_NULL(dnp3state);
2635  int bytes = DNP3HandleRequestLinkLayer(dnp3state, pkt, sizeof(pkt));
2636  FAIL_IF(bytes != sizeof(pkt));
2637 
2638  DNP3StateFree(dnp3state);
2639  PASS;
2640 }
2641 
2642 #endif
2643 
2645 {
2646 #ifdef UNITTESTS
2647  UtRegisterTest("DNP3ParserTestCheckCRC", DNP3ParserTestCheckCRC);
2648  UtRegisterTest("DNP3ParserCheckLinkHeaderCRC",
2649  DNP3ParserCheckLinkHeaderCRC);
2650  UtRegisterTest("DNP3CheckUserDataCRCsTest", DNP3CheckUserDataCRCsTest);
2651  UtRegisterTest("DNP3CalculateLinkLengthTest", DNP3CalculateLinkLengthTest);
2652  UtRegisterTest("DNP3CalculateTransportLengthWithoutCRCsTest",
2653  DNP3CalculateTransportLengthWithoutCRCsTest);
2654  UtRegisterTest("DNP3ReassembleApplicationLayerTest01",
2655  DNP3ReassembleApplicationLayerTest01);
2656  UtRegisterTest("DNP3ProbingParserTest", DNP3ProbingParserTest);
2657  UtRegisterTest("DNP3ParserTestRequestResponse",
2658  DNP3ParserTestRequestResponse);
2659  UtRegisterTest("DNP3ParserTestUnsolicitedResponseConfirm",
2660  DNP3ParserTestUnsolicitedResponseConfirm);
2661  UtRegisterTest("DNP3ParserTestPartialFrame", DNP3ParserTestPartialFrame);
2662  UtRegisterTest("DNP3ParserTestMultiFrame", DNP3ParserTestMultiFrame);
2663  UtRegisterTest("DNP3ParserTestFlooded", DNP3ParserTestFlooded);
2664  UtRegisterTest("DNP3ParserTestParsePDU01", DNP3ParserTestParsePDU01);
2665  UtRegisterTest("DNP3ParserDecodeG70V3Test", DNP3ParserDecodeG70V3Test);
2666  UtRegisterTest("DNP3ParserUnknownEventAlertTest",
2667  DNP3ParserUnknownEventAlertTest);
2668 #endif
2669 }
util-byte.h
DNP3Transaction_::response_lh
DNP3LinkHeader response_lh
Definition: app-layer-dnp3.h:235
AppLayerParserRegisterGetStateProgressFunc
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
Definition: app-layer-parser.c:490
AppLayerProtoDetectPPParseConfPorts
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)
Definition: app-layer-detect-proto.c:1645
len
uint8_t len
Definition: app-layer-dnp3.h:2
DNP3Transaction_::response_done
uint8_t response_done
Definition: app-layer-dnp3.h:234
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DNP3Transaction_::dnp3
struct DNP3State_ * dnp3
Definition: app-layer-dnp3.h:217
dnp3_decoder_event_table
SCEnumCharMap dnp3_decoder_event_table[]
Definition: app-layer-dnp3.c:90
DNP3Buffer_::size
size_t size
Definition: app-layer-dnp3.h:153
DNP3_DECODER_EVENT_MALFORMED
@ DNP3_DECODER_EVENT_MALFORMED
Definition: app-layer-dnp3.h:108
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
DNP3_APP_FC_DIR_OPERATE
#define DNP3_APP_FC_DIR_OPERATE
Definition: app-layer-dnp3.h:36
util-hashlist.h
TAILQ_INIT
#define TAILQ_INIT(head)
Definition: queue.h:370
flow-util.h
AppLayerParserRegisterStateFuncs
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void), void(*StateFree)(void *))
Definition: app-layer-parser.c:397
DetectEngineState_
Definition: detect-engine-state.h:92
stream-tcp.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
DNP3State_::response_buffer
DNP3Buffer response_buffer
Definition: app-layer-dnp3.h:271
DNP3Transaction_::request_done
uint8_t request_done
Definition: app-layer-dnp3.h:220
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
DNP3_DECODER_EVENT_FLOODED
@ DNP3_DECODER_EVENT_FLOODED
Definition: app-layer-dnp3.h:104
AppLayerParserRegisterDetectFlagsFuncs
void AppLayerParserRegisterDetectFlagsFuncs(uint8_t ipproto, AppProto alproto, uint64_t(*GetTxDetectFlags)(void *tx, uint8_t dir), void(*SetTxDetectFlags)(void *tx, uint8_t dir, uint64_t))
Definition: app-layer-parser.c:589
DNP3Transaction_::logged
uint32_t logged
Definition: app-layer-dnp3.h:215
DNP3_SWAP32
#define DNP3_SWAP32(x)
Definition: app-layer-dnp3.h:94
AppLayerParserRegisterLoggerFuncs
void AppLayerParserRegisterLoggerFuncs(uint8_t ipproto, AppProto alproto, LoggerId(*StateGetTxLogged)(void *, void *), void(*StateSetTxLogged)(void *, void *, LoggerId))
Definition: app-layer-parser.c:447
Flow_::proto
uint8_t proto
Definition: flow.h:361
DNP3ParserRegisterTests
void DNP3ParserRegisterTests(void)
Definition: app-layer-dnp3.c:2644
DNP3Object_
Struct to hold the list of decoded objects.
Definition: app-layer-dnp3.h:190
DNP3_APP_FC_FREEZE_CLEAR_NR
#define DNP3_APP_FC_FREEZE_CLEAR_NR
Definition: app-layer-dnp3.h:41
DNP3Transaction_::has_request
uint8_t has_request
Definition: app-layer-dnp3.h:219
AppLayerParserConfParserEnabled
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
Definition: app-layer-parser.c:302
Flow_
Flow data structure.
Definition: flow.h:343
DNP3State_::transaction_max
uint64_t transaction_max
Definition: app-layer-dnp3.h:263
AppLayerEventType
enum AppLayerEventType_ AppLayerEventType
AppLayerParserRegisterGetEventsFunc
void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto, AppLayerDecoderEvents *(*StateGetEvents)(void *))
Definition: app-layer-parser.c:436
LoggerId
LoggerId
Definition: suricata-common.h:439
DNP3_APP_FC_CONFIRM
#define DNP3_APP_FC_CONFIRM
Definition: app-layer-dnp3.h:31
logged
int logged
Definition: app-layer-htp.h:1
DNP3State_::flooded
uint8_t flooded
Definition: app-layer-dnp3.h:266
DNP3Buffer_::offset
int offset
Definition: app-layer-dnp3.h:155
DNP3DecodeObject
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.
Definition: app-layer-dnp3-objects.c:8588
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:501
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:347
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
DNP3Transaction_::response_buffer
uint8_t * response_buffer
Definition: app-layer-dnp3.h:239
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:279
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
DNP3PrefixIsSize
int DNP3PrefixIsSize(uint8_t prefix_code)
Check if the prefix code is a size prefix.
Definition: app-layer-dnp3.c:1562
AppLayerDecoderEventsFreeEvents
void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events)
Definition: app-layer-events.c:148
AppLayerParserRegisterDetectStateFuncs
void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, DetectEngineState *(*GetTxDetectState)(void *tx), int(*SetTxDetectState)(void *tx, DetectEngineState *))
Definition: app-layer-parser.c:577
DNP3ObjectG70V3_::filename
char filename[65535]
Definition: app-layer-dnp3-objects.h:1227
DNP3_APP_FC_UNSOLICITED_RESP
#define DNP3_APP_FC_UNSOLICITED_RESP
Definition: app-layer-dnp3.h:68
NEXT_TH_SEQNO
#define NEXT_TH_SEQNO(current)
Definition: app-layer-dnp3.c:104
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:385
DNP3State_::request_buffer
DNP3Buffer request_buffer
Definition: app-layer-dnp3.h:268
DNP3_DEFAULT_REQ_FLOOD_COUNT
#define DNP3_DEFAULT_REQ_FLOOD_COUNT
Definition: app-layer-dnp3.c:37
Flow_::protoctx
void * protoctx
Definition: flow.h:416
DNP3_TH_SEQ
#define DNP3_TH_SEQ(x)
Definition: app-layer-dnp3.h:81
DNP3_LINK_FC_UNCONFIRMED_USER_DATA
@ DNP3_LINK_FC_UNCONFIRMED_USER_DATA
Definition: app-layer-dnp3.c:68
DNP3Point_::data
void * data
Definition: app-layer-dnp3.h:181
DNP3Transaction_::response_complete
uint8_t response_complete
Definition: app-layer-dnp3.h:242
AppLayerDecoderEvents_
Data structure to store app layer decoder events.
Definition: app-layer-events.h:34
util-unittest.h
APP_LAYER_EVENT_TYPE_TRANSACTION
@ APP_LAYER_EVENT_TYPE_TRANSACTION
Definition: app-layer-events.h:57
DNP3Transaction_::has_response
uint8_t has_response
Definition: app-layer-dnp3.h:233
RegisterDNP3Parsers
void RegisterDNP3Parsers(void)
Register the DNP3 application protocol parser.
Definition: app-layer-dnp3.c:1599
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
DNP3Buffer_::len
int len
Definition: app-layer-dnp3.h:154
DNP3_SWAP16
#define DNP3_SWAP16(x)
Definition: app-layer-dnp3.h:93
DNP3FreeObjectPointList
void DNP3FreeObjectPointList(int group, int variation, DNP3PointList *list)
Free a DNP3PointList.
Definition: app-layer-dnp3-objects.c:58
DNP3State_::events
uint16_t events
Definition: app-layer-dnp3.h:264
AppLayerProtoDetectPPRegister
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
Definition: app-layer-detect-proto.c:1611
DNP3Object_::points
DNP3PointList * points
Definition: app-layer-dnp3.h:199
DNP3_DECODER_EVENT_UNKNOWN_OBJECT
@ DNP3_DECODER_EVENT_UNKNOWN_OBJECT
Definition: app-layer-dnp3.h:109
DNP3Transaction_::detect_flags_ts
uint64_t detect_flags_ts
Definition: app-layer-dnp3.h:211
app-layer-detect-proto.h
DNP3_BLOCK_SIZE
#define DNP3_BLOCK_SIZE
Definition: app-layer-dnp3.c:53
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:412
DNP3ObjectG70V3_
Definition: app-layer-dnp3-objects.h:1217
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:339
AppLayerParserState_
Definition: app-layer-parser.c:155
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
DNP3Transaction_::response_iin
DNP3InternalInd response_iin
Definition: app-layer-dnp3.h:238
DNP3Point_::size
uint32_t size
Definition: app-layer-dnp3.h:179
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:44
app-layer-dnp3.h
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
DNP3Transaction_::response_th
DNP3TransportHeader response_th
Definition: app-layer-dnp3.h:236
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
DNP3_CRC_LEN
#define DNP3_CRC_LEN
Definition: app-layer-dnp3.c:49
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:19
DNP3_APP_FC_FREEZE_AT_TIME_NR
#define DNP3_APP_FC_FREEZE_AT_TIME_NR
Definition: app-layer-dnp3.h:43
util-print.h
DNP3Transaction_::request_complete
uint8_t request_complete
Definition: app-layer-dnp3.h:227
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
Flow_::m
SCMutex m
Definition: flow.h:410
DNP3Buffer_::buffer
uint8_t * buffer
Definition: app-layer-dnp3.h:152
app-layer-parser.h
TRUE
#define TRUE
Definition: suricata-common.h:33
DNP3_TH_FIN
#define DNP3_TH_FIN(x)
Definition: app-layer-dnp3.h:79
AppLayerDecoderEvents_::cnt
uint8_t cnt
Definition: app-layer-events.h:38
DNP3_MIN_LEN
#define DNP3_MIN_LEN
Definition: app-layer-dnp3.c:46
SCReturn
#define SCReturn
Definition: util-debug.h:302
DNP3_APP_FC_AUTH_REQ_NR
#define DNP3_APP_FC_AUTH_REQ_NR
Definition: app-layer-dnp3.h:64
stream.h
BasicSearch
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't start searches that wont fit in the r...
Definition: util-spm-bs.c:48
AppLayerParserRegisterProtocolUnittests
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
Definition: app-layer-parser.c:1707
DNP3Object_::group
uint8_t group
Definition: app-layer-dnp3.h:191
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
app-layer-dcerpc-common.h
DNP3Transaction_::request_buffer_len
uint32_t request_buffer_len
Definition: app-layer-dnp3.h:226
SCReturnUInt
#define SCReturnUInt(x)
Definition: util-debug.h:306
DNP3_LINK_DIR
#define DNP3_LINK_DIR(control)
Definition: app-layer-dnp3.h:72
AppLayerParserRegisterGetEventInfo
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type))
Definition: app-layer-parser.c:565
DNP3_LINK_HDR_LEN
#define DNP3_LINK_HDR_LEN
Definition: app-layer-dnp3.c:63
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:316
DNP3_START_BYTE1
#define DNP3_START_BYTE1
Definition: app-layer-dnp3.c:43
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1826
DNP3Object_::start
uint32_t start
Definition: app-layer-dnp3.h:196
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:264
TAILQ_FOREACH_SAFE
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:356
AppLayerParserRegisterParser
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser)
Register app layer parser for the protocol.
Definition: app-layer-parser.c:364
DetectEngineStateFree
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:175
AppLayerParserRegisterGetStateProgressCompletionStatus
void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto, int(*StateGetProgressCompletionStatus)(uint8_t direction))
Definition: app-layer-parser.c:542
DNP3Transaction_::request_ah
DNP3ApplicationHeader request_ah
Definition: app-layer-dnp3.h:223
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
crc
uint16_t crc
Definition: app-layer-dnp3.h:6
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:253
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:523
DNP3Transaction_::response_ah
DNP3ApplicationHeader response_ah
Definition: app-layer-dnp3.h:237
length
uint16_t length
Definition: app-layer-modbus.c:2
DNP3Object_::count
uint32_t count
Definition: app-layer-dnp3.h:198
APP_LAYER_OK
#define APP_LAYER_OK
Definition: app-layer-parser.h:56
DNP3Transaction_::request_th
DNP3TransportHeader request_th
Definition: app-layer-dnp3.h:222
SCMapEnumValueToName
const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table)
Maps an enum value to a string name, from the supplied table.
Definition: util-enum.c:68
SCReturnStruct
#define SCReturnStruct(x)
Definition: util-debug.h:320
DNP3PointListAlloc
DNP3PointList * DNP3PointListAlloc(void)
Allocate a list for DNP3 points.
Definition: app-layer-dnp3-objects.c:45
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
DNP3State_::curr
DNP3Transaction * curr
Definition: app-layer-dnp3.h:262
DNP3_APP_FC_FREEZE_NR
#define DNP3_APP_FC_FREEZE_NR
Definition: app-layer-dnp3.h:39
SCMapEnumNameToValue
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:40
flags
uint8_t flags
Definition: decode-gre.h:0
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1171
suricata-common.h
DNP3_DECODER_EVENT_BAD_LINK_CRC
@ DNP3_DECODER_EVENT_BAD_LINK_CRC
Definition: app-layer-dnp3.h:106
DNP3_LINK_FC_CONFIRMED_USER_DATA
@ DNP3_LINK_FC_CONFIRMED_USER_DATA
Definition: app-layer-dnp3.c:67
DNP3Object_::range_code
uint8_t range_code
Definition: app-layer-dnp3.h:195
SCEnumCharMap_
Definition: util-enum.h:27
AppLayerDecoderEventsSetEventRaw
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
Definition: app-layer-events.c:89
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC
@ DNP3_DECODER_EVENT_BAD_TRANSPORT_CRC
Definition: app-layer-dnp3.h:107
DNP3_OBJ_PREFIX
#define DNP3_OBJ_PREFIX(x)
Definition: app-layer-dnp3.c:84
DNP3Object_::prefix_code
uint8_t prefix_code
Definition: app-layer-dnp3.h:194
DNP3Transaction_::request_lh
DNP3LinkHeader request_lh
Definition: app-layer-dnp3.h:221
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
DNP3Transaction_::tx_num
uint64_t tx_num
Definition: app-layer-dnp3.h:214
DNP3Transaction_::request_objects
DNP3ObjectList request_objects
Definition: app-layer-dnp3.h:231
DNP3_APP_FC_DIR_OPERATE_NR
#define DNP3_APP_FC_DIR_OPERATE_NR
Definition: app-layer-dnp3.h:37
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:244
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DNP3Transaction_::request_buffer
uint8_t * request_buffer
Definition: app-layer-dnp3.h:224
Flow_::alstate
void * alstate
Definition: flow.h:454
DNP3Object_::variation
uint8_t variation
Definition: app-layer-dnp3.h:192
AppLayerParserRegisterGetEventInfoById
void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfoById)(int event_id, const char **event_name, AppLayerEventType *event_type))
Definition: app-layer-parser.c:553
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:61
DNP3_APP_SEQ
#define DNP3_APP_SEQ(x)
Definition: app-layer-dnp3.h:88
DNP3Transaction_::detect_flags_tc
uint64_t detect_flags_tc
Definition: app-layer-dnp3.h:212
DNP3_TH_FIR
#define DNP3_TH_FIR(x)
Definition: app-layer-dnp3.h:80
app-layer-protos.h
DNP3State_
Per flow DNP3 state.
Definition: app-layer-dnp3.h:260
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
DNP3_DEFAULT_PORT
#define DNP3_DEFAULT_PORT
Definition: app-layer-dnp3.c:39
AppLayerParserRegisterGetTxCnt
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
Definition: app-layer-parser.c:512
APP_LAYER_ERROR
#define APP_LAYER_ERROR
Definition: app-layer-parser.h:60
SC_ERR_INVALID_ENUM_MAP
@ SC_ERR_INVALID_ENUM_MAP
Definition: util-error.h:45
DNP3Transaction_::de_state
DetectEngineState * de_state
Definition: app-layer-dnp3.h:250
DNP3State_::unreplied
uint32_t unreplied
Definition: app-layer-dnp3.h:265
DNP3_LINK_FC
#define DNP3_LINK_FC(control)
Definition: app-layer-dnp3.h:76
app-layer-dnp3-objects.h
DNP3TransportHeader
uint8_t DNP3TransportHeader
DNP3 transport header.
Definition: app-layer-dnp3.h:128
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:85
DNP3Point_::prefix
uint32_t prefix
Definition: app-layer-dnp3.h:174
TcpSession_
Definition: stream-tcp-private.h:260
DNP3_START_BYTE0
#define DNP3_START_BYTE0
Definition: app-layer-dnp3.c:42
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:425
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
AppLayerProtoDetectConfProtoDetectionEnabled
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
Definition: app-layer-detect-proto.c:1890
DNP3_OBJ_RANGE
#define DNP3_OBJ_RANGE(x)
Definition: app-layer-dnp3.c:87
SC_ERR_ALPARSER
@ SC_ERR_ALPARSER
Definition: util-error.h:89
DNP3Transaction_::response_buffer_len
uint32_t response_buffer_len
Definition: app-layer-dnp3.h:241
DNP3Transaction_::decoder_events
AppLayerDecoderEvents * decoder_events
Definition: app-layer-dnp3.h:248
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
DNP3Point_
DNP3 object point.
Definition: app-layer-dnp3.h:173
DNP3Transaction_
DNP3 transaction.
Definition: app-layer-dnp3.h:209
DNP3Transaction_::response_objects
DNP3ObjectList response_objects
Definition: app-layer-dnp3.h:246
DNP3Buffer_
A struct used for buffering incoming data prior to reassembly.
Definition: app-layer-dnp3.h:151
DNP3_DECODER_EVENT_LEN_TOO_SMALL
@ DNP3_DECODER_EVENT_LEN_TOO_SMALL
Definition: app-layer-dnp3.h:105