suricata
util-classification-config.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2010 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22 *
23 * Used for parsing a classification.config file
24 */
25
26#include "suricata-common.h"
27#include "detect.h"
28#include "detect-engine.h"
29#include "util-hash.h"
30
31#include "conf.h"
33#include "util-unittest.h"
34#include "util-error.h"
35#include "util-debug.h"
36#include "util-fmemopen.h"
37#include "util-byte.h"
38
39/* Regex to parse the classtype argument from a Signature. The first substring
40 * holds the classtype name, the second substring holds the classtype the
41 * classtype description, and the third argument holds the priority */
42#define DETECT_CLASSCONFIG_REGEX "^\\s*config\\s*classification\\s*:\\s*([a-zA-Z][a-zA-Z0-9-_]*)\\s*,\\s*(.+)\\s*,\\s*(\\d+)\\s*$"
43
44/* Default path for the classification.config file */
45#if defined OS_WIN32 || defined __CYGWIN__
46#define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "\\\\classification.config"
47#else
48#define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/classification.config"
49#endif
50
51uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen);
52char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
53 void *data2, uint16_t datalen2);
54void SCClassConfClasstypeHashFree(void *ch);
55static const char *SCClassConfGetConfFilename(const DetectEngineCtx *de_ctx);
56
57static SCClassConfClasstype *SCClassConfAllocClasstype(uint16_t classtype_id,
58 const char *classtype, const char *classtype_desc, int priority);
59static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct);
60
62{
63 int en;
64 PCRE2_SIZE eo;
65 int opts = 0;
66
67 de_ctx->class_conf_regex = pcre2_compile(
68 (PCRE2_SPTR8)DETECT_CLASSCONFIG_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
69 if (de_ctx->class_conf_regex == NULL) {
70 PCRE2_UCHAR errbuffer[256];
71 pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
72 SCLogWarning("pcre2 compile of \"%s\" failed at "
73 "offset %d: %s",
74 DETECT_CLASSCONFIG_REGEX, (int)eo, errbuffer);
75 return;
76 }
78 pcre2_match_data_create_from_pattern(de_ctx->class_conf_regex, NULL);
79}
80
82{
83 if (de_ctx->class_conf_regex != NULL) {
84 pcre2_code_free(de_ctx->class_conf_regex);
86 }
87 if (de_ctx->class_conf_regex_match != NULL) {
88 pcre2_match_data_free(de_ctx->class_conf_regex_match);
90 }
91}
92
93
94/**
95 * \brief Inits the context to be used by the Classification Config parsing API.
96 *
97 * This function initializes the hash table to be used by the Detection
98 * Engine Context to hold the data from the classification.config file,
99 * obtains the file desc to parse the classification.config file, and
100 * inits the regex used to parse the lines from classification.config
101 * file.
102 *
103 * \param de_ctx Pointer to the Detection Engine Context.
104 * \param fd Pointer to already opened file
105 *
106 * \note even if the file open fails we will keep the de_ctx->class_conf_ht
107 * initialized.
108 *
109 * \retval fp NULL on error
110 */
111static FILE *SCClassConfInitContextAndLocalResources(DetectEngineCtx *de_ctx, FILE *fd)
112{
113 /* init the hash table to be used by the classification config Classtypes */
117 if (de_ctx->class_conf_ht == NULL) {
118 SCLogError("Error initializing the hash "
119 "table");
120 return NULL;
121 }
122
123 /* if it is not NULL, use the file descriptor. The hack so that we can
124 * avoid using a dummy classification file for testing purposes and
125 * instead use an input stream against a buffer containing the
126 * classification strings */
127 if (fd == NULL) {
128 const char *filename = SCClassConfGetConfFilename(de_ctx);
129 if ( (fd = fopen(filename, "r")) == NULL) {
130#ifdef UNITTESTS
131 if (RunmodeIsUnittests())
132 return NULL; // silently fail
133#endif
134 SCLogWarning("could not open: \"%s\": %s", filename, strerror(errno));
135 return NULL;
136 }
137 }
138
139 return fd;
140}
141
142
143/**
144 * \brief Returns the path for the Classification Config file. We check if we
145 * can retrieve the path from the yaml conf file. If it is not present,
146 * return the default path for the classification file which is
147 * "./classification.config".
148 *
149 * \retval log_filename Pointer to a string containing the path for the
150 * Classification Config file.
151 */
152static const char *SCClassConfGetConfFilename(const DetectEngineCtx *de_ctx)
153{
154 const char *log_filename = NULL;
155
156 if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) {
157 char config_value[256];
158 snprintf(config_value, sizeof(config_value),
159 "%s.classification-file", de_ctx->config_prefix);
160
161 /* try loading prefix setting, fall back to global if that
162 * fails. */
163 if (SCConfGet(config_value, &log_filename) != 1) {
164 if (SCConfGet("classification-file", &log_filename) != 1) {
165 log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH;
166 }
167 }
168 } else {
169 if (SCConfGet("classification-file", &log_filename) != 1) {
170 log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH;
171 }
172 }
173
174 return log_filename;
175}
176
177/**
178 * \brief Releases resources used by the Classification Config API.
179 */
180static void SCClassConfDeInitLocalResources(FILE *fd)
181{
182 if (fd != NULL) {
183 fclose(fd);
184 }
185}
186
187/**
188 * \brief Releases resources used by the Classification Config API.
189 */
197
198/**
199 * \brief Converts a string to lowercase.
200 *
201 * \param str Pointer to the string to be converted.
202 */
203static char *SCClassConfStringToLowercase(const char *str)
204{
205 char *new_str = NULL;
206 char *temp_str = NULL;
207
208 if ( (new_str = SCStrdup(str)) == NULL) {
209 SCLogError("Error allocating memory");
210 return NULL;
211 }
212
213 temp_str = new_str;
214 while (*temp_str != '\0') {
215 *temp_str = u8_tolower((unsigned char)*temp_str);
216 temp_str++;
217 }
218
219 return new_str;
220}
221
222/**
223 * \brief Parses a line from the classification file and adds it to Classtype
224 * hash table in DetectEngineCtx, i.e. DetectEngineCtx->class_conf_ht.
225 *
226 * \param rawstr Pointer to the string to be parsed.
227 * \param index Relative index of the string to be parsed.
228 * \param de_ctx Pointer to the Detection Engine Context.
229 *
230 * \retval 0 On success.
231 * \retval -1 On failure.
232 */
233int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t index)
234{
235 char ct_name[CLASSTYPE_NAME_MAX_LEN];
236 char ct_desc[CLASSTYPE_DESC_MAX_LEN];
237 char ct_priority_str[16];
238 uint32_t ct_priority = 0;
239 uint16_t ct_id = index;
240
241 SCClassConfClasstype *ct_new = NULL;
242 SCClassConfClasstype *ct_lookup = NULL;
243
244 int ret = 0;
245
246 ret = pcre2_match(de_ctx->class_conf_regex, (PCRE2_SPTR8)rawstr, strlen(rawstr), 0, 0,
248 if (ret < 0) {
249 SCLogError("Invalid Classtype in "
250 "classification.config file %s: \"%s\"",
251 SCClassConfGetConfFilename(de_ctx), rawstr);
252 goto error;
253 }
254
255 size_t copylen = sizeof(ct_name);
256 /* retrieve the classtype name */
257 ret = pcre2_substring_copy_bynumber(
258 de_ctx->class_conf_regex_match, 1, (PCRE2_UCHAR8 *)ct_name, &copylen);
259 if (ret < 0) {
260 SCLogInfo("pcre2_substring_copy_bynumber() failed");
261 goto error;
262 }
263
264 /* retrieve the classtype description */
265 copylen = sizeof(ct_desc);
266 ret = pcre2_substring_copy_bynumber(
267 de_ctx->class_conf_regex_match, 2, (PCRE2_UCHAR8 *)ct_desc, &copylen);
268 if (ret < 0) {
269 SCLogInfo("pcre2_substring_copy_bynumber() failed");
270 goto error;
271 }
272
273 /* retrieve the classtype priority */
274 copylen = sizeof(ct_priority_str);
275 ret = pcre2_substring_copy_bynumber(
276 de_ctx->class_conf_regex_match, 3, (PCRE2_UCHAR8 *)ct_priority_str, &copylen);
277 if (ret < 0) {
278 SCLogInfo("pcre2_substring_copy_bynumber() failed");
279 goto error;
280 }
281 if (StringParseUint32(&ct_priority, 10, 0, (const char *)ct_priority_str) < 0) {
282 goto error;
283 }
284
285 /* Create a new instance of the parsed Classtype string */
286 ct_new = SCClassConfAllocClasstype(ct_id, ct_name, ct_desc, ct_priority);
287 if (ct_new == NULL)
288 goto error;
289
290 /* Check if the Classtype is present in the HashTable. In case it's present
291 * ignore it, as it is a duplicate. If not present, add it to the table */
292 ct_lookup = HashTableLookup(de_ctx->class_conf_ht, ct_new, 0);
293 if (ct_lookup == NULL) {
294 if (HashTableAdd(de_ctx->class_conf_ht, ct_new, 0) < 0)
295 SCLogDebug("HashTable Add failed");
296 } else {
297 SCLogDebug("Duplicate classtype found inside classification.config");
298 if (ct_new->classtype_desc) SCFree(ct_new->classtype_desc);
299 if (ct_new->classtype) SCFree(ct_new->classtype);
300 SCFree(ct_new);
301 }
302
303 return 0;
304
305 error:
306 return -1;
307}
308
309/**
310 * \brief Checks if a string is a comment or a blank line.
311 *
312 * Comments lines are lines of the following format -
313 * "# This is a comment string" or
314 * " # This is a comment string".
315 *
316 * \param line String that has to be checked
317 *
318 * \retval 1 On the argument string being a comment or blank line
319 * \retval 0 Otherwise
320 */
321static int SCClassConfIsLineBlankOrComment(char *line)
322{
323 while (*line != '\0') {
324 /* we have a comment */
325 if (*line == '#')
326 return 1;
327
328 /* this line is neither a comment line, nor a blank line */
329 if (!isspace((unsigned char)*line))
330 return 0;
331
332 line++;
333 }
334
335 /* we have a blank line */
336 return 1;
337}
338
339/**
340 * \brief Parses the Classification Config file and updates the
341 * DetectionEngineCtx->class_conf_ht with the Classtype information.
342 *
343 * \param de_ctx Pointer to the Detection Engine Context.
344 */
345static bool SCClassConfParseFile(DetectEngineCtx *de_ctx, FILE *fd)
346{
347 char line[1024];
348 uint16_t i = 1;
349 int errors = 0;
350
351 while (fgets(line, sizeof(line), fd) != NULL) {
352 if (SCClassConfIsLineBlankOrComment(line))
353 continue;
354
355 if (SCClassConfAddClasstype(de_ctx, line, i) == -1) {
356 errors++;
357 } else {
358 i++;
359 }
360 }
361
362#ifdef UNITTESTS
363 if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0)
364 SCLogInfo("tenant id %d: Added \"%d\" classification types from the classification file",
366 else
367 SCLogInfo("Added \"%d\" classification types from the classification file",
369#endif
370
371 return errors == 0;
372}
373
374/**
375 * \internal
376 * \brief Returns a new SCClassConfClasstype instance. The classtype string
377 * is converted into lowercase, before being assigned to the instance.
378 *
379 * \param classtype Pointer to the classification type.
380 * \param classtype_desc Pointer to the classification type description.
381 * \param priority Holds the priority for the classification type.
382 *
383 * \retval ct Pointer to the new instance of SCClassConfClasstype on success;
384 * NULL on failure.
385 */
386static SCClassConfClasstype *SCClassConfAllocClasstype(uint16_t classtype_id,
387 const char *classtype,
388 const char *classtype_desc,
389 int priority)
390{
391 SCClassConfClasstype *ct = NULL;
392
393 if (classtype == NULL)
394 return NULL;
395
396 if ((ct = SCCalloc(1, sizeof(SCClassConfClasstype))) == NULL)
397 return NULL;
398
399 if ((ct->classtype = SCClassConfStringToLowercase(classtype)) == NULL) {
400 SCClassConfDeAllocClasstype(ct);
401 return NULL;
402 }
403
404 if (classtype_desc != NULL &&
405 (ct->classtype_desc = SCStrdup(classtype_desc)) == NULL) {
406 SCLogError("Error allocating memory");
407
408 SCClassConfDeAllocClasstype(ct);
409 return NULL;
410 }
411
412 ct->classtype_id = classtype_id;
413 ct->priority = priority;
414
415 return ct;
416}
417
418/**
419 * \internal
420 * \brief Frees a SCClassConfClasstype instance
421 *
422 * \param Pointer to the SCClassConfClasstype instance that has to be freed
423 */
424static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct)
425{
426 if (ct != NULL) {
427 if (ct->classtype != NULL)
428 SCFree(ct->classtype);
429
430 if (ct->classtype_desc != NULL)
432
433 SCFree(ct);
434 }
435}
436
437/**
438 * \brief Hashing function to be used to hash the Classtype name. Would be
439 * supplied as an argument to the HashTableInit function for
440 * DetectEngineCtx->class_conf_ht.
441 *
442 * \param ht Pointer to the HashTable.
443 * \param data Pointer to the data to be hashed. In this case, the data
444 * would be a pointer to a SCClassConfClasstype instance.
445 * \param datalen Not used by this function.
446 */
447uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen)
448{
450 uint32_t hash = 0;
451 size_t i = 0;
452
453 size_t len = strlen(ct->classtype);
454
455 for (i = 0; i < len; i++)
456 hash += u8_tolower((unsigned char)(ct->classtype)[i]);
457
458 hash = hash % ht->array_size;
459
460 return hash;
461}
462
463/**
464 * \brief Used to compare two Classtypes that have been stored in the HashTable.
465 * This function is supplied as an argument to the HashTableInit function
466 * for DetectionEngineCtx->class_conf_ct.
467 *
468 * \param data1 Pointer to the first SCClassConfClasstype to be compared.
469 * \param len1 Not used by this function.
470 * \param data2 Pointer to the second SCClassConfClasstype to be compared.
471 * \param len2 Not used by this function.
472 *
473 * \retval 1 On data1 and data2 being equal.
474 * \retval 0 On data1 and data2 not being equal.
475 */
476char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
477 void *data2, uint16_t datalen2)
478{
481 size_t len1 = 0;
482 size_t len2 = 0;
483
484 if (ct1 == NULL || ct2 == NULL)
485 return 0;
486
487 if (ct1->classtype == NULL || ct2->classtype == NULL)
488 return 0;
489
490 len1 = strlen(ct1->classtype);
491 len2 = strlen(ct2->classtype);
492
493 if (len1 == len2 && memcmp(ct1->classtype, ct2->classtype, len1) == 0) {
494 SCLogDebug("Match found inside Classification-Config hash function");
495 return 1;
496 }
497
498 return 0;
499}
500
501/**
502 * \brief Used to free the Classification Config Hash Data that was stored in
503 * DetectEngineCtx->class_conf_ht Hashtable.
504 *
505 * \param ch Pointer to the data that has to be freed.
506 */
508{
509 SCClassConfDeAllocClasstype(ch);
510}
511
512/**
513 * \brief Loads the Classtype info from the classification.config file.
514 *
515 * The classification.config file contains the different classtypes,
516 * that can be used to label Signatures. Each line of the file should
517 * have the following format -
518 * classtype_name, classtype_description, priority
519 * None of the above parameters should hold a quote inside the file.
520 *
521 * \param de_ctx Pointer to the Detection Engine Context that should be updated
522 * with Classtype information.
523 */
525{
526 fd = SCClassConfInitContextAndLocalResources(de_ctx, fd);
527 if (fd == NULL) {
528#ifdef UNITTESTS
529 if (RunmodeIsUnittests()) {
530 return false;
531 }
532#endif
533 SCLogError("please check the \"classification-file\" "
534 "option in your suricata.yaml file");
535 return false;
536 }
537
538 bool ret = true;
539 if (!SCClassConfParseFile(de_ctx, fd)) {
540 SCLogWarning("Error loading classification configuration from %s",
541 SCClassConfGetConfFilename(de_ctx));
542 ret = false;
543 }
544
545 SCClassConfDeInitLocalResources(fd);
546
547 return ret;
548}
549
550/**
551 * \brief Gets the classtype from the corresponding hash table stored
552 * in the Detection Engine Context's class conf ht, given the
553 * classtype name.
554 *
555 * \param ct_name Pointer to the classtype name that has to be looked up.
556 * \param de_ctx Pointer to the Detection Engine Context.
557 *
558 * \retval lookup_ct_info Pointer to the SCClassConfClasstype instance from
559 * the hash table on success; NULL on failure.
560 */
563{
564 char name[strlen(ct_name) + 1];
565 size_t s;
566 for (s = 0; s < strlen(ct_name); s++)
567 name[s] = u8_tolower((unsigned char)ct_name[s]);
568 name[s] = '\0';
569
570 SCClassConfClasstype ct_lookup = {0, 0, name, NULL };
572 &ct_lookup, 0);
573 return lookup_ct_info;
574}
575
576/*----------------------------------Unittests---------------------------------*/
577
578
579#ifdef UNITTESTS
580
581/**
582 * \brief Creates a dummy classification file, with all valid Classtypes, for
583 * testing purposes.
584 *
585 * \file_path Pointer to the file_path for the dummy classification file.
586 */
588{
589 const char *buffer =
590 "config classification: nothing-wrong,Nothing Wrong With Us,3\n"
591 "config classification: unknown,Unknown are we,3\n"
592 "config classification: bad-unknown,We think it's bad, 2\n";
593
594 FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
595 if (fd == NULL)
596 SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
597
598 return fd;
599}
600
601/**
602 * \brief Creates a dummy classification file, with some valid Classtypes and a
603 * couple of invalid Classtypes, for testing purposes.
604 *
605 * \file_path Pointer to the file_path for the dummy classification file.
606 */
608{
609 const char *buffer =
610 "config classification: not-suspicious,Not Suspicious Traffic,3\n"
611 "onfig classification: unknown,Unknown Traffic,3\n"
612 "config classification: _badunknown,Potentially Bad Traffic, 2\n"
613 "config classification: bamboola1,Unknown Traffic,3\n"
614 "config classification: misc-activity,Misc activity,-1\n"
615 "config classification: policy-violation,Potential Corporate "
616 "config classification: bamboola,Unknown Traffic,3\n";
617
618 FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
619 if (fd == NULL)
620 SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
621
622 return fd;
623}
624
625/**
626 * \brief Creates a dummy classification file, with all invalid Classtypes, for
627 * testing purposes.
628 *
629 * \file_path Pointer to the file_path for the dummy classification file.
630 */
632{
633 const char *buffer =
634 "conig classification: not-suspicious,Not Suspicious Traffic,3\n"
635 "onfig classification: unknown,Unknown Traffic,3\n"
636 "config classification: _badunknown,Potentially Bad Traffic, 2\n"
637 "config classification: misc-activity,Misc activity,-1\n";
638
639 FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
640 if (fd == NULL)
641 SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
642
643 return fd;
644}
645
646/**
647 * \test Check that the classification file is loaded and the detection engine
648 * content class_conf_hash_table loaded with the classtype data.
649 */
650static int SCClassConfTest01(void)
651{
653 int result = 0;
654
655 if (de_ctx == NULL)
656 return result;
657
660
661 if (de_ctx->class_conf_ht == NULL)
662 return result;
663
664 result = (de_ctx->class_conf_ht->count == 3);
665 if (result == 0) printf("de_ctx->class_conf_ht->count %u: ", de_ctx->class_conf_ht->count);
666
668
669 return result;
670}
671
672/**
673 * \test Check that invalid classtypes present in the classification config file
674 * aren't loaded.
675 */
676static int SCClassConfTest02(void)
677{
679 int result = 0;
680
681 if (de_ctx == NULL)
682 return result;
683
686
687 if (de_ctx->class_conf_ht == NULL)
688 return result;
689
690 result = (de_ctx->class_conf_ht->count == 0);
691
693
694 return result;
695}
696
697/**
698 * \test Check that only valid classtypes are loaded into the hash table from
699 * the classification.config file.
700 */
701static int SCClassConfTest03(void)
702{
704
706
709
711
712 PASS;
713}
714
715/**
716 * \test Check if the classtype info from the classification.config file have
717 * been loaded into the hash table.
718 */
719static int SCClassConfTest04(void)
720{
722 int result = 1;
723
724 if (de_ctx == NULL)
725 return 0;
726
729
730 if (de_ctx->class_conf_ht == NULL)
731 return 0;
732
733 result = (de_ctx->class_conf_ht->count == 3);
734
735 result &= (SCClassConfGetClasstype("unknown", de_ctx) != NULL);
736 result &= (SCClassConfGetClasstype("unKnoWn", de_ctx) != NULL);
737 result &= (SCClassConfGetClasstype("bamboo", de_ctx) == NULL);
738 result &= (SCClassConfGetClasstype("bad-unknown", de_ctx) != NULL);
739 result &= (SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) != NULL);
740 result &= (SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL);
741
743
744 return result;
745}
746
747/**
748 * \test Check if the classtype info from the invalid classification.config file
749 * have not been loaded into the hash table, and cross verify to check
750 * that the hash table contains no classtype data.
751 */
752static int SCClassConfTest05(void)
753{
755 int result = 1;
756
757 if (de_ctx == NULL)
758 return 0;
759
762
763 if (de_ctx->class_conf_ht == NULL)
764 return 0;
765
766 result = (de_ctx->class_conf_ht->count == 0);
767
768 result &= (SCClassConfGetClasstype("unknown", de_ctx) == NULL);
769 result &= (SCClassConfGetClasstype("unKnoWn", de_ctx) == NULL);
770 result &= (SCClassConfGetClasstype("bamboo", de_ctx) == NULL);
771 result &= (SCClassConfGetClasstype("bad-unknown", de_ctx) == NULL);
772 result &= (SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) == NULL);
773 result &= (SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL);
774
776
777 return result;
778}
779
780/**
781 * \brief This function registers unit tests for Classification Config API.
782 */
784{
785 UtRegisterTest("SCClassConfTest01", SCClassConfTest01);
786 UtRegisterTest("SCClassConfTest02", SCClassConfTest02);
787 UtRegisterTest("SCClassConfTest03", SCClassConfTest03);
788 UtRegisterTest("SCClassConfTest04", SCClassConfTest04);
789 UtRegisterTest("SCClassConfTest05", SCClassConfTest05);
790}
791#endif /* UNITTESTS */
uint8_t len
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition conf.c:350
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
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 PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
main detection engine ctx
Definition detect.h:932
HashTable * class_conf_ht
Definition detect.h:1117
uint32_t tenant_id
Definition detect.h:939
pcre2_code * class_conf_regex
Definition detect.h:1118
char config_prefix[64]
Definition detect.h:1051
pcre2_match_data * class_conf_regex_match
Definition detect.h:1119
uint32_t count
Definition util-hash.h:39
uint32_t array_size
Definition util-hash.h:37
Container for a Classtype from the Classification.config file.
#define u8_tolower(c)
#define str(s)
int RunmodeIsUnittests(void)
Definition suricata.c:270
const char * name
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:313
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen)
Hashing function to be used to hash the Classtype name. Would be supplied as an argument to the HashT...
void SCClassConfRegisterTests(void)
This function registers unit tests for Classification Config API.
void SCClassSCConfInit(DetectEngineCtx *de_ctx)
FILE * SCClassConfGenerateInvalidDummyClassConfigFD02(void)
Creates a dummy classification file, with some valid Classtypes and a couple of invalid Classtypes,...
void SCClassConfClasstypeHashFree(void *ch)
Used to free the Classification Config Hash Data that was stored in DetectEngineCtx->class_conf_ht Ha...
#define DETECT_CLASSCONFIG_REGEX
void SCClassConfDeInitContext(DetectEngineCtx *de_ctx)
Releases resources used by the Classification Config API.
int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t index)
Parses a line from the classification file and adds it to Classtype hash table in DetectEngineCtx,...
void SCClassConfDeinit(DetectEngineCtx *de_ctx)
SCClassConfClasstype * SCClassConfGetClasstype(const char *ct_name, DetectEngineCtx *de_ctx)
Gets the classtype from the corresponding hash table stored in the Detection Engine Context's class c...
bool SCClassConfLoadClassificationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
#define SC_CLASS_CONF_DEF_CONF_FILEPATH
char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1, void *data2, uint16_t datalen2)
Used to compare two Classtypes that have been stored in the HashTable. This function is supplied as a...
FILE * SCClassConfGenerateInvalidDummyClassConfigFD03(void)
Creates a dummy classification file, with all invalid Classtypes, for testing purposes.
#define CLASSTYPE_DESC_MAX_LEN
#define CLASSTYPE_NAME_MAX_LEN
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCFmemopen
int HashTableAdd(HashTable *ht, void *data, uint16_t datalen)
Definition util-hash.c:104
HashTable * HashTableInit(uint32_t size, uint32_t(*Hash)(struct HashTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition util-hash.c:35
void HashTableFree(HashTable *ht)
Definition util-hash.c:78
void * HashTableLookup(HashTable *ht, void *data, uint16_t datalen)
Definition util-hash.c:183
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define SCStrdup(s)
Definition util-mem.h:56