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"
27#include "detect-engine-mpm.h"
30
31#include "app-layer-dnp3.h"
32#include "util-byte.h"
33
34static int g_dnp3_match_buffer_id = 0;
35static int g_dnp3_data_buffer_id = 0;
36
37/**
38 * The detection struct.
39 */
40typedef struct DetectDNP3_ {
41 union {
42 struct {
43 /* Function code for function code detection. */
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;
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
127static void DetectDNP3FuncRegisterTests(void);
128static void DetectDNP3IndRegisterTests(void);
129static void DetectDNP3ObjRegisterTests(void);
130#endif
131
132/**
133 * \brief Utility function to trim leading and trailing whitespace
134 * from a string.
135 */
136static 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
149static 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 */
187static 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
205static 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);
231error:
232 if (dnp3 != NULL) {
233 SCFree(dnp3);
234 }
235 SCReturnInt(-1);
236}
237
238static 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
267static 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
283static 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);
309error:
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 */
325static 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
349static 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);
376fail:
377 if (detect != NULL) {
378 SCFree(detect);
379 }
380 SCReturnInt(0);
381}
382
383static void DetectDNP3Free(DetectEngineCtx *de_ctx, void *ptr)
384{
385 SCEnter();
386 if (ptr != NULL) {
387 SCFree(ptr);
388 }
389 SCReturn;
390}
391
392static 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
409static 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
436static 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
453static 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
472static 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
491static 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
509static 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
521static 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
536 GetDNP3Data, ALPROTO_DNP3, 0);
537
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
573static 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
606static 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
627static 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
651static 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
667static 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
689static 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
707static void DetectDNP3FuncRegisterTests(void)
708{
709 UtRegisterTest("DetectDNP3FuncParseFunctionCodeTest",
710 DetectDNP3FuncParseFunctionCodeTest);
711 UtRegisterTest("DetectDNP3FuncTest01", DetectDNP3FuncTest01);
712}
713
714static void DetectDNP3IndRegisterTests(void)
715{
716 UtRegisterTest("DetectDNP3IndTestParseAsInteger",
717 DetectDNP3IndTestParseAsInteger);
718 UtRegisterTest("DetectDNP3IndTestParseByName",
719 DetectDNP3IndTestParseByName);
720}
721
722static void DetectDNP3ObjRegisterTests(void)
723{
724 UtRegisterTest("DetectDNP3ObjParseTest", DetectDNP3ObjParseTest);
725 UtRegisterTest("DetectDNP3ObjSetupTest", DetectDNP3ObjSetupTest);
726}
727#endif
uint8_t function_code
uint8_t variation
uint8_t group
struct HtpBodyChunk_ * next
@ ALPROTO_DNP3
uint8_t flags
Definition decode-gre.h:0
struct DetectDNP3_ DetectDNP3
DNP3Mapping DNP3IndicatorsMap[]
Definition detect-dnp3.c:61
DNP3Mapping DNP3FunctionNameMap[]
Definition detect-dnp3.c:86
void DetectDNP3Register(void)
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
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
InspectionBuffer * InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id)
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
int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
int DetectBufferTypeRegister(const char *name)
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.
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
int DetectBufferTypeGetByName(const char *name)
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.
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define SIGMATCH_NOOPT
Definition detect.h:1651
#define SIG_FLAG_TOCLIENT
Definition detect.h:272
#define SIGMATCH_INFO_STICKY_BUFFER
Definition detect.h:1676
#define SIG_FLAG_TOSERVER
Definition detect.h:271
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
struct Thresholds ctx
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
uint16_t value
Definition detect-dnp3.h:26
Struct to hold the list of decoded objects.
uint8_t variation
DNP3 transaction.
DNP3InternalInd iin
DNP3ObjectList objects
DNP3ApplicationHeader ah
uint16_t ind_flags
Definition detect-dnp3.c:48
uint8_t function_code
Definition detect-dnp3.c:44
uint8_t obj_variation
Definition detect-dnp3.c:53
uint8_t obj_group
Definition detect-dnp3.c:52
main detection engine ctx
Definition detect.h:932
Signature * sig_list
Definition detect.h:941
Flow data structure.
Definition flow.h:356
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
a single match condition for a signature
Definition detect.h:356
SigMatchCtx * ctx
Definition detect.h:359
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition detect.h:1424
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * alias
Definition detect.h:1460
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
#define str(s)
size_t strlcpy(char *dst, const char *src, size_t siz)
const char * name
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:337
int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
Definition util-byte.c:361
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCReturn
Definition util-debug.h:279
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define unlikely(expr)