suricata
detect-dnp3.c
Go to the documentation of this file.
1 /* Copyright (C) 2015-2022 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 
20 #include "stream.h"
21 
22 #include "detect.h"
23 #include "detect-parse.h"
24 #include "detect-dnp3.h"
25 #include "detect-engine.h"
26 #include "detect-engine-buffer.h"
27 #include "detect-engine-mpm.h"
30 
31 #include "app-layer-dnp3.h"
32 #include "util-byte.h"
33 
34 static int g_dnp3_match_buffer_id = 0;
35 static int g_dnp3_data_buffer_id = 0;
36 
37 /**
38  * The detection struct.
39  */
40 typedef struct DetectDNP3_ {
41  union {
42  struct {
43  /* Function code for function code detection. */
44  uint8_t function_code;
45  };
46  struct {
47  /* Internal indicator flags for IIN detection. */
48  uint16_t ind_flags;
49  };
50  struct {
51  /* Object info for object detection. */
52  uint8_t obj_group;
53  uint8_t obj_variation;
54  };
55  };
57 
58 /**
59  * Indicator names to value mappings (Snort compatible).
60  */
62  {"device_restart", 0x8000},
63  {"device_trouble", 0x4000},
64  {"local_control", 0x2000},
65  {"need_time", 0x1000},
66  {"class_3_events", 0x0800},
67  {"class_2_events", 0x0400},
68  {"class_1_events", 0x0200},
69  {"all_stations", 0x0100},
70 
71  {"reserved_1", 0x0080},
72  {"reserved_2", 0x0040},
73  {"config_corrupt", 0x0020},
74  {"already_executing", 0x0010},
75  {"event_buffer_overflow", 0x0008},
76  {"parameter_error", 0x0004},
77  {"object_unknown", 0x0002},
78  {"no_func_code_support", 0x0001},
79 
80  {NULL, 0},
81 };
82 
83 /**
84  * Application function code name to code mappings (Snort compatible).
85  */
87  {"confirm", 0},
88  {"read", 1},
89  {"write", 2},
90  {"select", 3},
91  {"operate", 4},
92  {"direct_operate", 5},
93  {"direct_operate_nr", 6},
94  {"immed_freeze", 7},
95  {"immed_freeze_nr", 8},
96  {"freeze_clear", 9},
97  {"freeze_clear_nr", 10},
98  {"freeze_at_time", 11},
99  {"freeze_at_time_nr", 12},
100  {"cold_restart", 13},
101  {"warm_restart", 14},
102  {"initialize_data", 15},
103  {"initialize_appl", 16},
104  {"start_appl", 17},
105  {"stop_appl", 18},
106  {"save_config", 19},
107  {"enable_unsolicited", 20},
108  {"disable_unsolicited", 21},
109  {"assign_class", 22},
110  {"delay_measure", 23},
111  {"record_current_time", 24},
112  {"open_file", 25},
113  {"close_file", 26},
114  {"delete_file", 27},
115  {"get_file_info", 28},
116  {"authenticate_file", 29},
117  {"abort_file", 30},
118  {"activate_config", 31},
119  {"authenticate_req", 32},
120  {"authenticate_err", 33},
121  {"response", 129},
122  {"unsolicited_response", 130},
123  {"authenticate_resp", 131}
124 };
125 
126 #ifdef UNITTESTS
127 static void DetectDNP3FuncRegisterTests(void);
128 static void DetectDNP3IndRegisterTests(void);
129 static void DetectDNP3ObjRegisterTests(void);
130 #endif
131 
132 /**
133  * \brief Utility function to trim leading and trailing whitespace
134  * from a string.
135  */
136 static char *TrimString(char *str)
137 {
138  char *end = str + strlen(str) - 1;
139  while (isspace(*str)) {
140  str++;
141  }
142  while (end > str && isspace(*end)) {
143  end--;
144  }
145  *(end + 1) = '\0';
146  return str;
147 }
148 
149 static InspectionBuffer *GetDNP3Data(DetectEngineThreadCtx *det_ctx,
150  const DetectEngineTransforms *transforms,
151  Flow *_f, const uint8_t flow_flags,
152  void *txv, const int list_id)
153 {
154  SCLogDebug("list_id %d", list_id);
155  InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
156  if (buffer->inspect == NULL) {
157  DNP3Transaction *tx = (DNP3Transaction *)txv;
158  SCLogDebug("tx %p", tx);
159 
160  if ((flow_flags & STREAM_TOSERVER && !tx->is_request) ||
161  (flow_flags & STREAM_TOCLIENT && tx->is_request)) {
162  return NULL;
163  }
164 
165  if (tx->buffer == NULL || tx->buffer_len == 0) {
166  return NULL;
167  }
168 
169  SCLogDebug("tx %p data %p data_len %u", tx, tx->buffer, tx->buffer_len);
171  det_ctx, list_id, buffer, tx->buffer, tx->buffer_len, transforms);
172  }
173  return buffer;
174 }
175 
176 /**
177  * \brief Parse the provided function name or code to its integer
178  * value.
179  *
180  * If the value passed is a number, it will be checked that it falls
181  * within the range of valid function codes. If function name is
182  * passed it will be resolved to its function code.
183  *
184  * \retval The function code as an integer if successful, -1 on
185  * failure.
186  */
187 static int DetectDNP3FuncParseFunctionCode(const char *str, uint8_t *fc)
188 {
189  if (StringParseUint8(fc, 10, (uint16_t)strlen(str), str) >= 0) {
190  return 1;
191  }
192 
193  /* Lookup by name. */
194  for (size_t i = 0;
195  i < sizeof(DNP3FunctionNameMap) / sizeof(DNP3Mapping); i++) {
196  if (strcasecmp(str, DNP3FunctionNameMap[i].name) == 0) {
197  *fc = (uint8_t)(DNP3FunctionNameMap[i].value);
198  return 1;
199  }
200  }
201 
202  return 0;
203 }
204 
205 static int DetectDNP3FuncSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
206 {
207  SCEnter();
208  DetectDNP3 *dnp3 = NULL;
209  uint8_t function_code;
210 
212  return -1;
213 
214  if (!DetectDNP3FuncParseFunctionCode(str, &function_code)) {
215  SCLogError("Invalid argument \"%s\" supplied to dnp3_func keyword.", str);
216  return -1;
217  }
218 
219  dnp3 = SCCalloc(1, sizeof(DetectDNP3));
220  if (unlikely(dnp3 == NULL)) {
221  goto error;
222  }
224 
226  de_ctx, s, DETECT_DNP3FUNC, (SigMatchCtx *)dnp3, g_dnp3_match_buffer_id) == NULL) {
227  goto error;
228  }
229 
230  SCReturnInt(0);
231 error:
232  if (dnp3 != NULL) {
233  SCFree(dnp3);
234  }
235  SCReturnInt(-1);
236 }
237 
238 static int DetectDNP3IndParseByName(const char *str, uint16_t *flags)
239 {
240  char tmp[strlen(str) + 1];
241  char *p, *last = NULL;
242 
243  strlcpy(tmp, str, sizeof(tmp));
244 
245  for ((p = strtok_r(tmp, ",", &last)); p; (p = strtok_r(NULL, ",", &last))) {
246  p = TrimString(p);
247  int found = 0;
248  int i = 0;
249  while (DNP3IndicatorsMap[i].name != NULL) {
250  if (strcasecmp(p, DNP3IndicatorsMap[i].name) == 0) {
252  found = 1;
253  break;
254  }
255  i++;
256  }
257 
258  if (!found) {
259  SCLogError("Bad argument \"%s\" supplied to dnp3.ind keyword.", p);
260  return 0;
261  }
262  }
263 
264  return 1;
265 }
266 
267 static int DetectDNP3IndParse(const char *str, uint16_t *flags)
268 {
269  *flags = 0;
270 
271  if (StringParseUint16(flags, 0, (uint16_t)strlen(str), str) > 0) {
272  return 1;
273  }
274 
275  /* Parse by name - will log a more specific error message on error. */
276  if (DetectDNP3IndParseByName(str, flags)) {
277  return 1;
278  }
279 
280  return 0;
281 }
282 
283 static int DetectDNP3IndSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
284 {
285  SCEnter();
286  DetectDNP3 *detect = NULL;
287  uint16_t flags;
288 
290  return -1;
291 
292  if (!DetectDNP3IndParse(str, &flags)) {
293  SCLogError("Invalid argument \"%s\" supplied to dnp3.ind keyword.", str);
294  return -1;
295  }
296 
297  detect = SCCalloc(1, sizeof(DetectDNP3));
298  if (unlikely(detect == NULL)) {
299  goto error;
300  }
301  detect->ind_flags = flags;
302 
304  de_ctx, s, DETECT_DNP3IND, (SigMatchCtx *)detect, g_dnp3_match_buffer_id) == NULL) {
305  goto error;
306  }
307 
308  SCReturnInt(0);
309 error:
310  if (detect != NULL) {
311  SCFree(detect);
312  }
313  SCReturnInt(-1);
314 }
315 
316 /**
317  * \brief Parse the value of string of the dnp3_obj keyword.
318  *
319  * \param str the input string
320  * \param gout pointer to variable to store the parsed group integer
321  * \param vout pointer to variable to store the parsed variation integer
322  *
323  * \retval 1 if parsing successful otherwise 0.
324  */
325 static int DetectDNP3ObjParse(const char *str, uint8_t *group, uint8_t *var)
326 {
327  size_t size = strlen(str) + 1;
328  char groupstr[size], *varstr, *sep;
329  strlcpy(groupstr, str, size);
330 
331  sep = strchr(groupstr, ',');
332  if (sep == NULL) {
333  return 0;
334  }
335  *sep = '\0';
336  varstr = sep + 1;
337 
338  if (StringParseUint8(group, 0, (uint16_t)strlen(groupstr), groupstr) < 0) {
339  return 0;
340  }
341 
342  if (StringParseUint8(var, 0, (uint16_t)strlen(varstr), varstr) < 0) {
343  return 0;
344  }
345 
346  return 1;
347 }
348 
349 static int DetectDNP3ObjSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
350 {
351  SCEnter();
352  uint8_t group;
353  uint8_t variation;
354  DetectDNP3 *detect = NULL;
355 
357  return -1;
358 
359  if (!DetectDNP3ObjParse(str, &group, &variation)) {
360  goto fail;
361  }
362 
363  detect = SCCalloc(1, sizeof(*detect));
364  if (unlikely(detect == NULL)) {
365  goto fail;
366  }
367  detect->obj_group = group;
368  detect->obj_variation = variation;
369 
371  de_ctx, s, DETECT_DNP3OBJ, (SigMatchCtx *)detect, g_dnp3_match_buffer_id) == NULL) {
372  goto fail;
373  }
374 
375  SCReturnInt(1);
376 fail:
377  if (detect != NULL) {
378  SCFree(detect);
379  }
380  SCReturnInt(0);
381 }
382 
383 static void DetectDNP3Free(DetectEngineCtx *de_ctx, void *ptr)
384 {
385  SCEnter();
386  if (ptr != NULL) {
387  SCFree(ptr);
388  }
389  SCReturn;
390 }
391 
392 static int DetectDNP3FuncMatch(DetectEngineThreadCtx *det_ctx,
393  Flow *f, uint8_t flags, void *state, void *txv, const Signature *s,
394  const SigMatchCtx *ctx)
395 {
396  DNP3Transaction *tx = (DNP3Transaction *)txv;
397  DetectDNP3 *detect = (DetectDNP3 *)ctx;
398  int match = 0;
399 
400  if (flags & STREAM_TOSERVER && tx->is_request) {
401  match = detect->function_code == tx->ah.function_code;
402  } else if (flags & STREAM_TOCLIENT && !tx->is_request) {
403  match = detect->function_code == tx->ah.function_code;
404  }
405 
406  return match;
407 }
408 
409 static int DetectDNP3ObjMatch(DetectEngineThreadCtx *det_ctx,
410  Flow *f, uint8_t flags, void *state, void *txv, const Signature *s,
411  const SigMatchCtx *ctx)
412 {
413  DNP3Transaction *tx = (DNP3Transaction *)txv;
414  DetectDNP3 *detect = (DetectDNP3 *)ctx;
415  DNP3ObjectList *objects = NULL;
416 
417  if (flags & STREAM_TOSERVER && tx->is_request) {
418  objects = &tx->objects;
419  } else if (flags & STREAM_TOCLIENT && !tx->is_request) {
420  objects = &tx->objects;
421  }
422 
423  if (objects != NULL) {
424  DNP3Object *object;
425  TAILQ_FOREACH(object, objects, next) {
426  if (object->group == detect->obj_group &&
427  object->variation == detect->obj_variation) {
428  return 1;
429  }
430  }
431  }
432 
433  return 0;
434 }
435 
436 static int DetectDNP3IndMatch(DetectEngineThreadCtx *det_ctx,
437  Flow *f, uint8_t flags, void *state, void *txv, const Signature *s,
438  const SigMatchCtx *ctx)
439 {
440  DNP3Transaction *tx = (DNP3Transaction *)txv;
441  DetectDNP3 *detect = (DetectDNP3 *)ctx;
442 
443  if (flags & STREAM_TOCLIENT) {
444  if ((tx->iin.iin1 & (detect->ind_flags >> 8)) ||
445  (tx->iin.iin2 & (detect->ind_flags & 0xf))) {
446  return 1;
447  }
448  }
449 
450  return 0;
451 }
452 
453 static void DetectDNP3FuncRegister(void)
454 {
455  SCEnter();
456 
457  sigmatch_table[DETECT_DNP3FUNC].name = "dnp3_func";
458  sigmatch_table[DETECT_DNP3FUNC].alias = "dnp3.func";
460  "match on the application function code found in DNP3 request and responses";
461  sigmatch_table[DETECT_DNP3FUNC].url = "/rules/dnp3-keywords.html#dnp3-func";
463  sigmatch_table[DETECT_DNP3FUNC].AppLayerTxMatch = DetectDNP3FuncMatch;
464  sigmatch_table[DETECT_DNP3FUNC].Setup = DetectDNP3FuncSetup;
465  sigmatch_table[DETECT_DNP3FUNC].Free = DetectDNP3Free;
466 #ifdef UNITTESTS
467  sigmatch_table[DETECT_DNP3FUNC].RegisterTests = DetectDNP3FuncRegisterTests;
468 #endif
469  SCReturn;
470 }
471 
472 static void DetectDNP3IndRegister(void)
473 {
474  SCEnter();
475 
476  sigmatch_table[DETECT_DNP3IND].name = "dnp3_ind";
477  sigmatch_table[DETECT_DNP3IND].alias = "dnp3.ind";
479  "match on the DNP3 internal indicator flags in the response application header";
480  sigmatch_table[DETECT_DNP3IND].url = "/rules/dnp3-keywords.html#dnp3-ind";
482  sigmatch_table[DETECT_DNP3IND].AppLayerTxMatch = DetectDNP3IndMatch;
483  sigmatch_table[DETECT_DNP3IND].Setup = DetectDNP3IndSetup;
484  sigmatch_table[DETECT_DNP3IND].Free = DetectDNP3Free;
485 #ifdef UNITTESTS
486  sigmatch_table[DETECT_DNP3IND].RegisterTests = DetectDNP3IndRegisterTests;
487 #endif
488  SCReturn;
489 }
490 
491 static void DetectDNP3ObjRegister(void)
492 {
493  SCEnter();
494 
495  sigmatch_table[DETECT_DNP3OBJ].name = "dnp3_obj";
496  sigmatch_table[DETECT_DNP3OBJ].alias = "dnp3.obj";
497  sigmatch_table[DETECT_DNP3OBJ].desc = "match on the DNP3 application data objects";
498  sigmatch_table[DETECT_DNP3OBJ].url = "/rules/dnp3-keywords.html#dnp3-obj";
500  sigmatch_table[DETECT_DNP3OBJ].AppLayerTxMatch = DetectDNP3ObjMatch;
501  sigmatch_table[DETECT_DNP3OBJ].Setup = DetectDNP3ObjSetup;
502  sigmatch_table[DETECT_DNP3OBJ].Free = DetectDNP3Free;
503 #ifdef UNITTESTS
504  sigmatch_table[DETECT_DNP3OBJ].RegisterTests = DetectDNP3ObjRegisterTests;
505 #endif
506  SCReturn;
507 }
508 
509 static int DetectDNP3DataSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
510 {
511  SCEnter();
513  return -1;
514 
515  if (SCDetectBufferSetActiveList(de_ctx, s, g_dnp3_data_buffer_id) != 0)
516  return -1;
517 
518  SCReturnInt(0);
519 }
520 
521 static void DetectDNP3DataRegister(void)
522 {
523  SCEnter();
524 
525  sigmatch_table[DETECT_DNP3DATA].name = "dnp3.data";
526  sigmatch_table[DETECT_DNP3DATA].alias = "dnp3_data";
528  "make the following content options to match on the re-assembled application buffer";
529  sigmatch_table[DETECT_DNP3DATA].url = "/rules/dnp3-keywords.html#dnp3-data";
530  sigmatch_table[DETECT_DNP3DATA].Setup = DetectDNP3DataSetup;
532 
534  DetectEngineInspectBufferGeneric, GetDNP3Data);
536  GetDNP3Data, ALPROTO_DNP3, 0);
537 
539  DetectEngineInspectBufferGeneric, GetDNP3Data);
541  GetDNP3Data, ALPROTO_DNP3, 0);
542 
543  g_dnp3_data_buffer_id = DetectBufferTypeGetByName("dnp3_data");
544  SCReturn;
545 }
546 
548 {
549  DetectDNP3DataRegister();
550 
551  DetectDNP3FuncRegister();
552  DetectDNP3IndRegister();
553  DetectDNP3ObjRegister();
554 
555  /* Register the list of func, ind and obj. */
560 
561  g_dnp3_match_buffer_id = DetectBufferTypeRegister("dnp3");
562 
563 }
564 
565 #ifdef UNITTESTS
566 
567 #include "util-unittest.h"
568 #include "util-unittest-helper.h"
569 #include "app-layer-parser.h"
570 #include "flow-util.h"
571 #include "stream-tcp.h"
572 
573 static int DetectDNP3FuncParseFunctionCodeTest(void)
574 {
575  uint8_t fc;
576 
577  /* Valid. */
578  FAIL_IF_NOT(DetectDNP3FuncParseFunctionCode("0", &fc));
579  FAIL_IF(fc != 0);
580 
581  FAIL_IF_NOT(DetectDNP3FuncParseFunctionCode("1", &fc));
582  FAIL_IF(fc != 1);
583 
584  FAIL_IF_NOT(DetectDNP3FuncParseFunctionCode("254", &fc));
585  FAIL_IF(fc != 254);
586 
587  FAIL_IF_NOT(DetectDNP3FuncParseFunctionCode("255", &fc));
588  FAIL_IF(fc != 255);
589 
590  FAIL_IF_NOT(DetectDNP3FuncParseFunctionCode("confirm", &fc));
591  FAIL_IF(fc != 0);
592 
593  FAIL_IF_NOT(DetectDNP3FuncParseFunctionCode("CONFIRM", &fc));
594  FAIL_IF(fc != 0);
595 
596  /* Invalid. */
597  FAIL_IF(DetectDNP3FuncParseFunctionCode("", &fc));
598  FAIL_IF(DetectDNP3FuncParseFunctionCode("-1", &fc));
599  FAIL_IF(DetectDNP3FuncParseFunctionCode("-2", &fc));
600  FAIL_IF(DetectDNP3FuncParseFunctionCode("256", &fc));
601  FAIL_IF(DetectDNP3FuncParseFunctionCode("unknown_function_code", &fc));
602 
603  PASS;
604 }
605 
606 static int DetectDNP3FuncTest01(void)
607 {
610 
611  Signature *s = DetectEngineAppendSig(de_ctx, "alert dnp3 any any -> any any "
612  "(msg:\"SURICATA DNP3 Write request\"; "
613  "dnp3_func:2; sid:5000009; rev:1;)");
615 
616  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dnp3_match_buffer_id);
617  FAIL_IF_NULL(sm);
618  FAIL_IF_NULL(sm->ctx);
619 
620  DetectDNP3 *dnp3func = (DetectDNP3 *)sm->ctx;
621  FAIL_IF(dnp3func->function_code != 2);
622 
624  PASS;
625 }
626 
627 static int DetectDNP3IndTestParseAsInteger(void)
628 {
629  uint16_t flags = 0;
630 
631  FAIL_IF(!DetectDNP3IndParse("0", &flags));
632  FAIL_IF(flags != 0);
633  FAIL_IF(!DetectDNP3IndParse("1", &flags));
634  FAIL_IF(flags != 0x0001);
635 
636  FAIL_IF(!DetectDNP3IndParse("0x0", &flags));
637  FAIL_IF(flags != 0);
638  FAIL_IF(!DetectDNP3IndParse("0x0000", &flags));
639  FAIL_IF(flags != 0);
640  FAIL_IF(!DetectDNP3IndParse("0x0001", &flags));
641  FAIL_IF(flags != 0x0001);
642 
643  FAIL_IF(!DetectDNP3IndParse("0x8421", &flags));
644  FAIL_IF(flags != 0x8421);
645 
646  FAIL_IF(DetectDNP3IndParse("a", &flags));
647 
648  PASS;
649 }
650 
651 static int DetectDNP3IndTestParseByName(void)
652 {
653  uint16_t flags = 0;
654 
655  FAIL_IF(!DetectDNP3IndParse("all_stations", &flags));
656  FAIL_IF(!(flags & 0x0100));
657  FAIL_IF(!DetectDNP3IndParse("class_1_events , class_2_events", &flags));
658  FAIL_IF(!(flags & 0x0200));
659  FAIL_IF(!(flags & 0x0400));
660  FAIL_IF((flags & 0xf9ff));
661 
662  FAIL_IF(DetectDNP3IndParse("something", &flags));
663 
664  PASS;
665 }
666 
667 static int DetectDNP3ObjSetupTest(void)
668 {
670  FAIL_IF(de_ctx == NULL);
671 
672  Signature *s = DetectEngineAppendSig(de_ctx, "alert dnp3 any any -> any any "
673  "(msg:\"SURICATA DNP3 Object Test\"; "
674  "dnp3_obj:99,99; sid:1; rev:1;)");
675  FAIL_IF(de_ctx->sig_list == NULL);
676 
677  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dnp3_match_buffer_id);
678  FAIL_IF_NULL(sm);
679  FAIL_IF_NULL(sm->ctx);
680 
681  DetectDNP3 *detect = (DetectDNP3 *)sm->ctx;
682  FAIL_IF(detect->obj_group != 99);
683  FAIL_IF(detect->obj_variation != 99);
684 
686  PASS;
687 }
688 
689 static int DetectDNP3ObjParseTest(void)
690 {
691  uint8_t group, var;
692 
693  FAIL_IF(!DetectDNP3ObjParse("0,0", &group, &var));
694  FAIL_IF(group != 0 || var != 0);
695 
696  FAIL_IF(!DetectDNP3ObjParse("255,255", &group, &var));
697  FAIL_IF(group != 255 || var != 255);
698 
699  FAIL_IF(DetectDNP3ObjParse("-1,-1", &group, &var));
700  FAIL_IF(DetectDNP3ObjParse("256,256", &group, &var));
701  FAIL_IF(DetectDNP3ObjParse("a,1", &group, &var));
702  FAIL_IF(DetectDNP3ObjParse("1,a", &group, &var));
703 
704  PASS;
705 }
706 
707 static void DetectDNP3FuncRegisterTests(void)
708 {
709  UtRegisterTest("DetectDNP3FuncParseFunctionCodeTest",
710  DetectDNP3FuncParseFunctionCodeTest);
711  UtRegisterTest("DetectDNP3FuncTest01", DetectDNP3FuncTest01);
712 }
713 
714 static void DetectDNP3IndRegisterTests(void)
715 {
716  UtRegisterTest("DetectDNP3IndTestParseAsInteger",
717  DetectDNP3IndTestParseAsInteger);
718  UtRegisterTest("DetectDNP3IndTestParseByName",
719  DetectDNP3IndTestParseByName);
720 }
721 
722 static void DetectDNP3ObjRegisterTests(void)
723 {
724  UtRegisterTest("DetectDNP3ObjParseTest", DetectDNP3ObjParseTest);
725  UtRegisterTest("DetectDNP3ObjSetupTest", DetectDNP3ObjSetupTest);
726 }
727 #endif
util-byte.h
SigTableElmt_::url
const char * url
Definition: detect.h:1431
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:2313
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1645
SigTableElmt_::desc
const char * desc
Definition: detect.h:1430
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:155
DetectEngineInspectBufferGeneric
uint8_t DetectEngineInspectBufferGeneric(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:2103
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1418
flow-util.h
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:157
SigTableElmt_::name
const char * name
Definition: detect.h:1428
InspectionBufferSetupAndApplyTransforms
void InspectionBufferSetupAndApplyTransforms(DetectEngineThreadCtx *det_ctx, const int list_id, InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len, const DetectEngineTransforms *transforms)
setup the buffer with our initial data
Definition: detect-engine.c:1570
stream-tcp.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
DetectEngineTransforms
Definition: detect.h:415
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DetectDNP3Register
void DetectDNP3Register(void)
Definition: detect-dnp3.c:547
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
DNP3Object_
Struct to hold the list of decoded objects.
Definition: app-layer-dnp3.h:192
InspectionBuffer
Definition: detect.h:380
Flow_
Flow data structure.
Definition: flow.h:356
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1422
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:931
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:337
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2674
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1399
DetectDNP3_
Definition: detect-dnp3.c:40
DNP3Transaction_::objects
DNP3ObjectList objects
Definition: app-layer-dnp3.h:221
detect-dnp3.h
SCDetectBufferSetActiveList
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
Definition: detect-engine-buffer.c:29
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3439
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:271
DNP3Transaction_::buffer_len
uint32_t buffer_len
Definition: app-layer-dnp3.h:220
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1413
DETECT_DNP3DATA
@ DETECT_DNP3DATA
Definition: detect-engine-register.h:265
DetectDNP3_::function_code
uint8_t function_code
Definition: detect-dnp3.c:44
detect-engine-prefilter.h
util-unittest.h
InspectionBufferGet
InspectionBuffer * InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id)
Definition: detect-engine.c:1429
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1157
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
DNP3IndicatorsMap
DNP3Mapping DNP3IndicatorsMap[]
Definition: detect-dnp3.c:61
StringParseUint8
int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:361
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:270
DNP3Transaction_::ah
DNP3ApplicationHeader ah
Definition: app-layer-dnp3.h:224
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
DETECT_DNP3IND
@ DETECT_DNP3IND
Definition: detect-engine-register.h:267
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectDNP3_::ind_flags
uint16_t ind_flags
Definition: detect-dnp3.c:48
DetectEngineThreadCtx_
Definition: detect.h:1223
DNP3Transaction_::iin
DNP3InternalInd iin
Definition: app-layer-dnp3.h:225
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:50
app-layer-dnp3.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect-engine-mpm.h
detect.h
PrefilterGenericMpmRegister
int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:1547
DetectAppLayerMpmRegister
void DetectAppLayerMpmRegister(const char *name, int direction, int priority, PrefilterRegisterFunc PrefilterRegister, InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress)
register an app layer keyword for mpm
Definition: detect-engine-mpm.c:151
app-layer-parser.h
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:359
SCReturn
#define SCReturn
Definition: util-debug.h:273
stream.h
DNP3Object_::group
uint8_t group
Definition: app-layer-dnp3.h:193
variation
uint8_t variation
Definition: app-layer-dnp3.h:1
DETECT_DNP3FUNC
@ DETECT_DNP3FUNC
Definition: detect-engine-register.h:266
name
const char * name
Definition: tm-threads.c:2123
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1396
DetectDNP3_::obj_variation
uint8_t obj_variation
Definition: detect-dnp3.c:53
detect-engine-content-inspection.h
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
DNP3Transaction_::is_request
bool is_request
Definition: app-layer-dnp3.h:215
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1093
flags
uint8_t flags
Definition: decode-gre.h:0
SigTableElmt_::alias
const char * alias
Definition: detect.h:1429
group
uint8_t group
Definition: app-layer-dnp3.h:0
suricata-common.h
DetectDNP3_::obj_group
uint8_t obj_group
Definition: detect-dnp3.c:52
detect-engine-buffer.h
DNP3Mapping_::value
uint16_t value
Definition: detect-dnp3.h:26
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:940
DetectEngineInspectGenericList
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:2060
DNP3Mapping_
Definition: detect-dnp3.h:24
InspectionBuffer::inspect
const uint8_t * inspect
Definition: detect.h:381
str
#define str(s)
Definition: suricata-common.h:308
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DNP3Object_::variation
uint8_t variation
Definition: app-layer-dnp3.h:194
detect-parse.h
Signature_
Signature container.
Definition: detect.h:670
SigMatch_
a single match condition for a signature
Definition: detect.h:356
function_code
uint8_t function_code
Definition: app-layer-dnp3.h:1
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2635
DETECT_DNP3OBJ
@ DETECT_DNP3OBJ
Definition: detect-engine-register.h:268
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1620
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:245
DetectDNP3
struct DetectDNP3_ DetectDNP3
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:464
DNP3FunctionNameMap
DNP3Mapping DNP3FunctionNameMap[]
Definition: detect-dnp3.c:86
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
DNP3Transaction_
DNP3 transaction.
Definition: app-layer-dnp3.h:211
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1420
DNP3Transaction_::buffer
uint8_t * buffer
Definition: app-layer-dnp3.h:219