suricata
datasets.c
Go to the documentation of this file.
1 /* Copyright (C) 2017-2024 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 Victor Julien <victor@inliniac.net>
22  */
23 
24 #include "suricata-common.h"
25 #include "suricata.h"
26 #include "rust.h"
27 #include "conf.h"
28 #include "datasets.h"
29 #include "datasets-string.h"
30 #include "datasets-ipv4.h"
31 #include "datasets-ipv6.h"
32 #include "datasets-md5.h"
33 #include "datasets-sha256.h"
34 #include "datasets-reputation.h"
35 #include "util-conf.h"
36 #include "util-thash.h"
37 #include "util-print.h"
38 #include "util-base64.h" // decode base64
39 #include "util-byte.h"
40 #include "util-misc.h"
41 #include "util-path.h"
42 #include "util-debug.h"
43 
45 static Dataset *sets = NULL;
46 static uint32_t set_ids = 0;
47 
48 static int DatasetAddwRep(Dataset *set, const uint8_t *data, const uint32_t data_len,
49  DataRepType *rep);
50 
51 static inline void DatasetUnlockData(THashData *d)
52 {
53  (void) THashDecrUsecnt(d);
54  THashDataUnlock(d);
55 }
56 static bool DatasetIsStatic(const char *save, const char *load);
57 static void GetDefaultMemcap(uint64_t *memcap, uint32_t *hashsize);
58 
59 enum DatasetTypes DatasetGetTypeFromString(const char *s)
60 {
61  if (strcasecmp("md5", s) == 0)
62  return DATASET_TYPE_MD5;
63  if (strcasecmp("sha256", s) == 0)
64  return DATASET_TYPE_SHA256;
65  if (strcasecmp("string", s) == 0)
66  return DATASET_TYPE_STRING;
67  if (strcasecmp("ipv4", s) == 0)
68  return DATASET_TYPE_IPV4;
69  if (strcasecmp("ip", s) == 0)
70  return DATASET_TYPE_IPV6;
71  return DATASET_TYPE_NOTSET;
72 }
73 
74 static Dataset *DatasetAlloc(const char *name)
75 {
76  Dataset *set = SCCalloc(1, sizeof(*set));
77  if (set) {
78  set->id = set_ids++;
79  }
80  return set;
81 }
82 
83 static Dataset *DatasetSearchByName(const char *name)
84 {
85  Dataset *set = sets;
86  while (set) {
87  if (strcasecmp(name, set->name) == 0 && set->hidden == false) {
88  return set;
89  }
90  set = set->next;
91  }
92  return NULL;
93 }
94 
95 static int HexToRaw(const uint8_t *in, size_t ins, uint8_t *out, size_t outs)
96 {
97  if (ins < 2)
98  return -1;
99  if (ins % 2 != 0)
100  return -1;
101  if (outs != ins / 2)
102  return -1;
103 
104  uint8_t hash[outs];
105  memset(hash, 0, outs);
106  size_t i, x;
107  for (x = 0, i = 0; i < ins; i+=2, x++) {
108  char buf[3] = { 0, 0, 0 };
109  buf[0] = in[i];
110  buf[1] = in[i+1];
111 
112  long value = strtol(buf, NULL, 16);
113  if (value >= 0 && value <= 255)
114  hash[x] = (uint8_t)value;
115  else {
116  SCLogError("hash byte out of range %ld", value);
117  return -1;
118  }
119  }
120 
121  memcpy(out, hash, outs);
122  return 0;
123 }
124 
125 static int ParseRepLine(const char *in, size_t ins, DataRepType *rep_out)
126 {
127  SCLogDebug("in '%s'", in);
128  char raw[ins + 1];
129  memcpy(raw, in, ins);
130  raw[ins] = '\0';
131  char *line = raw;
132 
133  char *ptrs[1] = {NULL};
134  int idx = 0;
135 
136  size_t i = 0;
137  while (i < ins + 1) {
138  if (line[i] == ',' || line[i] == '\n' || line[i] == '\0') {
139  line[i] = '\0';
140  SCLogDebug("line '%s'", line);
141 
142  ptrs[idx] = line;
143  idx++;
144 
145  if (idx == 1)
146  break;
147  } else {
148  i++;
149  }
150  }
151 
152  if (idx != 1) {
153  SCLogDebug("idx %d", idx);
154  return -1;
155  }
156 
157  uint16_t v = 0;
158  int r = StringParseU16RangeCheck(&v, 10, strlen(ptrs[0]), ptrs[0], 0, USHRT_MAX);
159  if (r != (int)strlen(ptrs[0])) {
160  SCLogError("'%s' is not a valid reputation value (0-65535)", ptrs[0]);
161  return -1;
162  }
163  SCLogDebug("v %"PRIu16" raw %s", v, ptrs[0]);
164 
165  rep_out->value = v;
166  return 0;
167 }
168 
169 static int DatasetLoadIPv4(Dataset *set)
170 {
171  if (strlen(set->load) == 0)
172  return 0;
173 
174  SCLogConfig("dataset: %s loading from '%s'", set->name, set->load);
175  const char *fopen_mode = "r";
176  if (strlen(set->save) > 0 && strcmp(set->save, set->load) == 0) {
177  fopen_mode = "a+";
178  }
179 
180  FILE *fp = fopen(set->load, fopen_mode);
181  if (fp == NULL) {
182  SCLogError("fopen '%s' failed: %s", set->load, strerror(errno));
183  return -1;
184  }
185 
186  uint32_t cnt = 0;
187  char line[1024];
188  while (fgets(line, (int)sizeof(line), fp) != NULL) {
189  char *r = strchr(line, ',');
190  if (r == NULL) {
191  line[strlen(line) - 1] = '\0';
192  SCLogDebug("line: '%s'", line);
193 
194  struct in_addr in;
195  if (inet_pton(AF_INET, line, &in) != 1) {
196  FatalErrorOnInit("dataset data parse failed %s/%s: %s", set->name, set->load, line);
197  continue;
198  }
199 
200  if (DatasetAdd(set, (const uint8_t *)&in.s_addr, 4) < 0) {
201  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
202  continue;
203  }
204  cnt++;
205 
206  /* list with rep data */
207  } else {
208  line[strlen(line) - 1] = '\0';
209  SCLogDebug("IPv4 with REP line: '%s'", line);
210 
211  *r = '\0';
212 
213  struct in_addr in;
214  if (inet_pton(AF_INET, line, &in) != 1) {
215  FatalErrorOnInit("dataset data parse failed %s/%s: %s", set->name, set->load, line);
216  continue;
217  }
218 
219  r++;
220 
221  DataRepType rep = { .value = 0 };
222  if (ParseRepLine(r, strlen(r), &rep) < 0) {
223  FatalErrorOnInit("bad rep for dataset %s/%s", set->name, set->load);
224  continue;
225  }
226 
227  SCLogDebug("rep v:%u", rep.value);
228  if (DatasetAddwRep(set, (const uint8_t *)&in.s_addr, 4, &rep) < 0) {
229  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
230  continue;
231  }
232 
233  cnt++;
234  }
235  }
237 
238  fclose(fp);
239  SCLogConfig("dataset: %s loaded %u records", set->name, cnt);
240  return 0;
241 }
242 
243 static int ParseIpv6String(Dataset *set, char *line, struct in6_addr *in6)
244 {
245  /* Checking IPv6 case */
246  char *got_colon = strchr(line, ':');
247  if (got_colon) {
248  uint32_t ip6addr[4];
249  if (inet_pton(AF_INET6, line, in6) != 1) {
250  FatalErrorOnInit("dataset data parse failed %s/%s: %s", set->name, set->load, line);
251  return -1;
252  }
253  memcpy(&ip6addr, in6->s6_addr, sizeof(ip6addr));
254  /* IPv4 in IPv6 notation needs transformation to internal Suricata storage */
255  if (ip6addr[0] == 0 && ip6addr[1] == 0 && ip6addr[2] == 0xFFFF0000) {
256  ip6addr[0] = ip6addr[3];
257  ip6addr[2] = 0;
258  ip6addr[3] = 0;
259  memcpy(in6, ip6addr, sizeof(struct in6_addr));
260  }
261  } else {
262  /* IPv4 case */
263  struct in_addr in;
264  if (inet_pton(AF_INET, line, &in) != 1) {
265  FatalErrorOnInit("dataset data parse failed %s/%s: %s", set->name, set->load, line);
266  return -1;
267  }
268  memset(in6, 0, sizeof(struct in6_addr));
269  memcpy(in6, &in, sizeof(struct in_addr));
270  }
271  return 0;
272 }
273 
274 static int DatasetLoadIPv6(Dataset *set)
275 {
276  if (strlen(set->load) == 0)
277  return 0;
278 
279  SCLogConfig("dataset: %s loading from '%s'", set->name, set->load);
280  const char *fopen_mode = "r";
281  if (strlen(set->save) > 0 && strcmp(set->save, set->load) == 0) {
282  fopen_mode = "a+";
283  }
284 
285  FILE *fp = fopen(set->load, fopen_mode);
286  if (fp == NULL) {
287  SCLogError("fopen '%s' failed: %s", set->load, strerror(errno));
288  return -1;
289  }
290 
291  uint32_t cnt = 0;
292  char line[1024];
293  while (fgets(line, (int)sizeof(line), fp) != NULL) {
294  char *r = strchr(line, ',');
295  if (r == NULL) {
296  line[strlen(line) - 1] = '\0';
297  SCLogDebug("line: '%s'", line);
298 
299  struct in6_addr in6;
300  int ret = ParseIpv6String(set, line, &in6);
301  if (ret < 0) {
302  FatalErrorOnInit("unable to parse IP address");
303  continue;
304  }
305 
306  if (DatasetAdd(set, (const uint8_t *)&in6.s6_addr, 16) < 0) {
307  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
308  continue;
309  }
310  cnt++;
311 
312  /* list with rep data */
313  } else {
314  line[strlen(line) - 1] = '\0';
315  SCLogDebug("IPv6 with REP line: '%s'", line);
316 
317  *r = '\0';
318 
319  struct in6_addr in6;
320  int ret = ParseIpv6String(set, line, &in6);
321  if (ret < 0) {
322  FatalErrorOnInit("unable to parse IP address");
323  continue;
324  }
325 
326  r++;
327 
328  DataRepType rep = { .value = 0 };
329  if (ParseRepLine(r, strlen(r), &rep) < 0) {
330  FatalErrorOnInit("bad rep for dataset %s/%s", set->name, set->load);
331  continue;
332  }
333 
334  SCLogDebug("rep v:%u", rep.value);
335  if (DatasetAddwRep(set, (const uint8_t *)&in6.s6_addr, 16, &rep) < 0) {
336  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
337  continue;
338  }
339 
340  cnt++;
341  }
342  }
344 
345  fclose(fp);
346  SCLogConfig("dataset: %s loaded %u records", set->name, cnt);
347  return 0;
348 }
349 
350 static int DatasetLoadMd5(Dataset *set)
351 {
352  if (strlen(set->load) == 0)
353  return 0;
354 
355  SCLogConfig("dataset: %s loading from '%s'", set->name, set->load);
356  const char *fopen_mode = "r";
357  if (strlen(set->save) > 0 && strcmp(set->save, set->load) == 0) {
358  fopen_mode = "a+";
359  }
360 
361  FILE *fp = fopen(set->load, fopen_mode);
362  if (fp == NULL) {
363  SCLogError("fopen '%s' failed: %s", set->load, strerror(errno));
364  return -1;
365  }
366 
367  uint32_t cnt = 0;
368  char line[1024];
369  while (fgets(line, (int)sizeof(line), fp) != NULL) {
370  /* straight black/white list */
371  if (strlen(line) == 33) {
372  line[strlen(line) - 1] = '\0';
373  SCLogDebug("line: '%s'", line);
374 
375  uint8_t hash[16];
376  if (HexToRaw((const uint8_t *)line, 32, hash, sizeof(hash)) < 0) {
377  FatalErrorOnInit("bad hash for dataset %s/%s", set->name, set->load);
378  continue;
379  }
380 
381  if (DatasetAdd(set, (const uint8_t *)hash, 16) < 0) {
382  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
383  continue;
384  }
385  cnt++;
386 
387  /* list with rep data */
388  } else if (strlen(line) > 33 && line[32] == ',') {
389  line[strlen(line) - 1] = '\0';
390  SCLogDebug("MD5 with REP line: '%s'", line);
391 
392  uint8_t hash[16];
393  if (HexToRaw((const uint8_t *)line, 32, hash, sizeof(hash)) < 0) {
394  FatalErrorOnInit("bad hash for dataset %s/%s", set->name, set->load);
395  continue;
396  }
397 
398  DataRepType rep = { .value = 0};
399  if (ParseRepLine(line + 33, strlen(line) - 33, &rep) < 0) {
400  FatalErrorOnInit("bad rep for dataset %s/%s", set->name, set->load);
401  continue;
402  }
403 
404  SCLogDebug("rep v:%u", rep.value);
405  if (DatasetAddwRep(set, hash, 16, &rep) < 0) {
406  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
407  continue;
408  }
409 
410  cnt++;
411  }
412  else {
413  FatalErrorOnInit("MD5 bad line len %u: '%s'", (uint32_t)strlen(line), line);
414  continue;
415  }
416  }
418 
419  fclose(fp);
420  SCLogConfig("dataset: %s loaded %u records", set->name, cnt);
421  return 0;
422 }
423 
424 static int DatasetLoadSha256(Dataset *set)
425 {
426  if (strlen(set->load) == 0)
427  return 0;
428 
429  SCLogConfig("dataset: %s loading from '%s'", set->name, set->load);
430  const char *fopen_mode = "r";
431  if (strlen(set->save) > 0 && strcmp(set->save, set->load) == 0) {
432  fopen_mode = "a+";
433  }
434 
435  FILE *fp = fopen(set->load, fopen_mode);
436  if (fp == NULL) {
437  SCLogError("fopen '%s' failed: %s", set->load, strerror(errno));
438  return -1;
439  }
440 
441  uint32_t cnt = 0;
442  char line[1024];
443  while (fgets(line, (int)sizeof(line), fp) != NULL) {
444  /* straight black/white list */
445  if (strlen(line) == 65) {
446  line[strlen(line) - 1] = '\0';
447  SCLogDebug("line: '%s'", line);
448 
449  uint8_t hash[32];
450  if (HexToRaw((const uint8_t *)line, 64, hash, sizeof(hash)) < 0) {
451  FatalErrorOnInit("bad hash for dataset %s/%s", set->name, set->load);
452  continue;
453  }
454 
455  if (DatasetAdd(set, (const uint8_t *)hash, (uint32_t)32) < 0) {
456  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
457  continue;
458  }
459  cnt++;
460 
461  /* list with rep data */
462  } else if (strlen(line) > 65 && line[64] == ',') {
463  line[strlen(line) - 1] = '\0';
464  SCLogDebug("SHA-256 with REP line: '%s'", line);
465 
466  uint8_t hash[32];
467  if (HexToRaw((const uint8_t *)line, 64, hash, sizeof(hash)) < 0) {
468  FatalErrorOnInit("bad hash for dataset %s/%s", set->name, set->load);
469  continue;
470  }
471 
472  DataRepType rep = { .value = 0 };
473  if (ParseRepLine(line + 65, strlen(line) - 65, &rep) < 0) {
474  FatalErrorOnInit("bad rep for dataset %s/%s", set->name, set->load);
475  continue;
476  }
477 
478  SCLogDebug("rep %u", rep.value);
479 
480  if (DatasetAddwRep(set, hash, 32, &rep) < 0) {
481  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
482  continue;
483  }
484  cnt++;
485  }
486  }
488 
489  fclose(fp);
490  SCLogConfig("dataset: %s loaded %u records", set->name, cnt);
491  return 0;
492 }
493 
494 static int DatasetLoadString(Dataset *set)
495 {
496  if (strlen(set->load) == 0)
497  return 0;
498 
499  SCLogConfig("dataset: %s loading from '%s'", set->name, set->load);
500  const char *fopen_mode = "r";
501  if (strlen(set->save) > 0 && strcmp(set->save, set->load) == 0) {
502  fopen_mode = "a+";
503  }
504 
505  FILE *fp = fopen(set->load, fopen_mode);
506  if (fp == NULL) {
507  SCLogError("fopen '%s' failed: %s", set->load, strerror(errno));
508  return -1;
509  }
510 
511  uint32_t cnt = 0;
512  char line[1024];
513  while (fgets(line, (int)sizeof(line), fp) != NULL) {
514  if (strlen(line) <= 1)
515  continue;
516 
517  char *r = strchr(line, ',');
518  if (r == NULL) {
519  line[strlen(line) - 1] = '\0';
520  SCLogDebug("line: '%s'", line);
521 
522  // coverity[alloc_strlen : FALSE]
523  uint8_t decoded[strlen(line)];
524  uint32_t consumed = 0, num_decoded = 0;
525  Base64Ecode code = DecodeBase64(decoded, (uint32_t)strlen(line), (const uint8_t *)line,
526  (uint32_t)strlen(line), &consumed, &num_decoded, Base64ModeStrict);
527  if (code == BASE64_ECODE_ERR) {
528  FatalErrorOnInit("bad base64 encoding %s/%s", set->name, set->load);
529  continue;
530  }
531 
532  if (DatasetAdd(set, (const uint8_t *)decoded, num_decoded) < 0) {
533  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
534  continue;
535  }
536  cnt++;
537  } else {
538  line[strlen(line) - 1] = '\0';
539  SCLogDebug("line: '%s'", line);
540 
541  *r = '\0';
542 
543  // coverity[alloc_strlen : FALSE]
544  uint8_t decoded[strlen(line)];
545  uint32_t consumed = 0, num_decoded = 0;
546  Base64Ecode code = DecodeBase64(decoded, (uint32_t)strlen(line), (const uint8_t *)line,
547  (uint32_t)strlen(line), &consumed, &num_decoded, Base64ModeStrict);
548  if (code == BASE64_ECODE_ERR) {
549  FatalErrorOnInit("bad base64 encoding %s/%s", set->name, set->load);
550  continue;
551  }
552 
553  r++;
554  SCLogDebug("r '%s'", r);
555 
556  DataRepType rep = { .value = 0 };
557  if (ParseRepLine(r, strlen(r), &rep) < 0) {
558  FatalErrorOnInit("die: bad rep");
559  continue;
560  }
561  SCLogDebug("rep %u", rep.value);
562 
563  if (DatasetAddwRep(set, (const uint8_t *)decoded, num_decoded, &rep) < 0) {
564  FatalErrorOnInit("dataset data add failed %s/%s", set->name, set->load);
565  continue;
566  }
567  cnt++;
568 
569  SCLogDebug("line with rep %s, %s", line, r);
570  }
571  }
573 
574  fclose(fp);
575  SCLogConfig("dataset: %s loaded %u records", set->name, cnt);
576  return 0;
577 }
578 
579 extern bool g_system;
580 
584 };
585 
586 static void DatasetGetPath(const char *in_path,
587  char *out_path, size_t out_size, enum DatasetGetPathType type)
588 {
589  char path[PATH_MAX];
590  struct stat st;
591 
592  if (PathIsAbsolute(in_path)) {
593  strlcpy(path, in_path, sizeof(path));
594  strlcpy(out_path, path, out_size);
595  return;
596  }
597 
598  const char *data_dir = ConfigGetDataDirectory();
599  if (stat(data_dir, &st) != 0) {
600  SCLogDebug("data-dir '%s': %s", data_dir, strerror(errno));
601  return;
602  }
603 
604  snprintf(path, sizeof(path), "%s/%s", data_dir, in_path); // TODO WINDOWS
605 
606  if (type == TYPE_LOAD) {
607  if (stat(path, &st) != 0) {
608  SCLogDebug("path %s: %s", path, strerror(errno));
609  if (!g_system) {
610  snprintf(path, sizeof(path), "%s", in_path);
611  }
612  }
613  }
614  strlcpy(out_path, path, out_size);
615  SCLogDebug("in_path \'%s\' => \'%s\'", in_path, out_path);
616 }
617 
618 /** \brief look for set by name without creating it */
619 Dataset *DatasetFind(const char *name, enum DatasetTypes type)
620 {
622  Dataset *set = DatasetSearchByName(name);
623  if (set) {
624  if (set->type != type) {
626  return NULL;
627  }
628  }
630  return set;
631 }
632 
633 Dataset *DatasetGet(const char *name, enum DatasetTypes type, const char *save, const char *load,
634  uint64_t memcap, uint32_t hashsize)
635 {
636  uint64_t default_memcap = 0;
637  uint32_t default_hashsize = 0;
638  if (strlen(name) > DATASET_NAME_MAX_LEN) {
639  return NULL;
640  }
641 
643  Dataset *set = DatasetSearchByName(name);
644  if (set) {
645  if (type != DATASET_TYPE_NOTSET && set->type != type) {
646  SCLogError("dataset %s already "
647  "exists and is of type %u",
648  set->name, set->type);
650  return NULL;
651  }
652 
653  if ((save == NULL || strlen(save) == 0) &&
654  (load == NULL || strlen(load) == 0)) {
655  // OK, rule keyword doesn't have to set state/load,
656  // even when yaml set has set it.
657  } else {
658  if ((save == NULL && strlen(set->save) > 0) ||
659  (save != NULL && strcmp(set->save, save) != 0)) {
660  SCLogError("dataset %s save mismatch: %s != %s", set->name, set->save, save);
662  return NULL;
663  }
664  if ((load == NULL && strlen(set->load) > 0) ||
665  (load != NULL && strcmp(set->load, load) != 0)) {
666  SCLogError("dataset %s load mismatch: %s != %s", set->name, set->load, load);
668  return NULL;
669  }
670  }
671 
673  return set;
674  } else {
675  if (type == DATASET_TYPE_NOTSET) {
676  SCLogError("dataset %s not defined", name);
677  goto out_err;
678  }
679  }
680 
681  set = DatasetAlloc(name);
682  if (set == NULL) {
683  goto out_err;
684  }
685 
686  strlcpy(set->name, name, sizeof(set->name));
687  set->type = type;
688  if (save && strlen(save)) {
689  strlcpy(set->save, save, sizeof(set->save));
690  SCLogDebug("name %s save '%s'", name, set->save);
691  }
692  if (load && strlen(load)) {
693  strlcpy(set->load, load, sizeof(set->load));
694  SCLogDebug("set \'%s\' loading \'%s\' from \'%s\'", set->name, load, set->load);
695  }
696 
697  char cnf_name[128];
698  snprintf(cnf_name, sizeof(cnf_name), "datasets.%s.hash", name);
699 
700  GetDefaultMemcap(&default_memcap, &default_hashsize);
701  switch (type) {
702  case DATASET_TYPE_MD5:
703  set->hash = THashInit(cnf_name, sizeof(Md5Type), Md5StrSet, Md5StrFree, Md5StrHash,
704  Md5StrCompare, NULL, NULL, load != NULL ? 1 : 0,
705  memcap > 0 ? memcap : default_memcap,
706  hashsize > 0 ? hashsize : default_hashsize);
707  if (set->hash == NULL)
708  goto out_err;
709  if (DatasetLoadMd5(set) < 0)
710  goto out_err;
711  break;
712  case DATASET_TYPE_STRING:
713  set->hash = THashInit(cnf_name, sizeof(StringType), StringSet, StringFree, StringHash,
714  StringCompare, NULL, StringGetLength, load != NULL ? 1 : 0,
715  memcap > 0 ? memcap : default_memcap,
716  hashsize > 0 ? hashsize : default_hashsize);
717  if (set->hash == NULL)
718  goto out_err;
719  if (DatasetLoadString(set) < 0)
720  goto out_err;
721  break;
722  case DATASET_TYPE_SHA256:
723  set->hash = THashInit(cnf_name, sizeof(Sha256Type), Sha256StrSet, Sha256StrFree,
724  Sha256StrHash, Sha256StrCompare, NULL, NULL, load != NULL ? 1 : 0,
725  memcap > 0 ? memcap : default_memcap,
726  hashsize > 0 ? hashsize : default_hashsize);
727  if (set->hash == NULL)
728  goto out_err;
729  if (DatasetLoadSha256(set) < 0)
730  goto out_err;
731  break;
732  case DATASET_TYPE_IPV4:
733  set->hash =
734  THashInit(cnf_name, sizeof(IPv4Type), IPv4Set, IPv4Free, IPv4Hash, IPv4Compare,
735  NULL, NULL, load != NULL ? 1 : 0, memcap > 0 ? memcap : default_memcap,
736  hashsize > 0 ? hashsize : default_hashsize);
737  if (set->hash == NULL)
738  goto out_err;
739  if (DatasetLoadIPv4(set) < 0)
740  goto out_err;
741  break;
742  case DATASET_TYPE_IPV6:
743  set->hash =
744  THashInit(cnf_name, sizeof(IPv6Type), IPv6Set, IPv6Free, IPv6Hash, IPv6Compare,
745  NULL, NULL, load != NULL ? 1 : 0, memcap > 0 ? memcap : default_memcap,
746  hashsize > 0 ? hashsize : default_hashsize);
747  if (set->hash == NULL)
748  goto out_err;
749  if (DatasetLoadIPv6(set) < 0)
750  goto out_err;
751  break;
752  }
753 
754  if (set->hash && SC_ATOMIC_GET(set->hash->memcap_reached)) {
755  SCLogError("dataset too large for set memcap");
756  goto out_err;
757  }
758 
759  SCLogDebug("set %p/%s type %u save %s load %s",
760  set, set->name, set->type, set->save, set->load);
761 
762  set->next = sets;
763  sets = set;
764 
766  return set;
767 out_err:
768  if (set) {
769  if (set->hash) {
770  THashShutdown(set->hash);
771  }
772  SCFree(set);
773  }
775  return NULL;
776 }
777 
778 static bool DatasetIsStatic(const char *save, const char *load)
779 {
780  /* A set is static if it does not have any dynamic properties like
781  * save and/or state defined but has load defined.
782  * */
783  if ((load != NULL && strlen(load) > 0) &&
784  (save == NULL || strlen(save) == 0)) {
785  return true;
786  }
787  return false;
788 }
789 
790 void DatasetReload(void)
791 {
792  /* In order to reload the datasets, just mark the current sets as hidden
793  * and clean them up later.
794  * New datasets shall be created with the rule reload and do not require
795  * any intervention.
796  * */
798  Dataset *set = sets;
799  while (set) {
800  if (!DatasetIsStatic(set->save, set->load) || set->from_yaml == true) {
801  SCLogDebug("Not a static set, skipping %s", set->name);
802  set = set->next;
803  continue;
804  }
805  set->hidden = true;
806  SCLogDebug("Set %s at %p hidden successfully", set->name, set);
807  set = set->next;
808  }
810 }
811 
813 {
814  SCLogDebug("Post Reload Cleanup starting.. Hidden sets will be removed");
816  Dataset *cur = sets;
817  Dataset *prev = NULL;
818  while (cur) {
819  Dataset *next = cur->next;
820  if (cur->hidden == false) {
821  prev = cur;
822  cur = next;
823  continue;
824  }
825  // Delete the set in case it was hidden
826  if (prev != NULL) {
827  prev->next = next;
828  } else {
829  sets = next;
830  }
831  THashShutdown(cur->hash);
832  SCFree(cur);
833  cur = next;
834  }
836 }
837 
838 static void GetDefaultMemcap(uint64_t *memcap, uint32_t *hashsize)
839 {
840  const char *str = NULL;
841  if (ConfGet("datasets.defaults.memcap", &str) == 1) {
842  if (ParseSizeStringU64(str, memcap) < 0) {
843  SCLogWarning("memcap value cannot be deduced: %s,"
844  " resetting to default",
845  str);
846  *memcap = 0;
847  }
848  }
849  if (ConfGet("datasets.defaults.hashsize", &str) == 1) {
850  if (ParseSizeStringU32(str, hashsize) < 0) {
851  SCLogWarning("hashsize value cannot be deduced: %s,"
852  " resetting to default",
853  str);
854  *hashsize = 0;
855  }
856  }
857 }
858 
859 int DatasetsInit(void)
860 {
861  SCLogDebug("datasets start");
862  ConfNode *datasets = ConfGetNode("datasets");
863  uint64_t default_memcap = 0;
864  uint32_t default_hashsize = 0;
865  GetDefaultMemcap(&default_memcap, &default_hashsize);
866  if (datasets != NULL) {
867  int list_pos = 0;
868  ConfNode *iter = NULL;
869  TAILQ_FOREACH(iter, &datasets->head, next) {
870  if (iter->name == NULL) {
871  list_pos++;
872  continue;
873  }
874 
875  char save[PATH_MAX] = "";
876  char load[PATH_MAX] = "";
877  uint64_t memcap = 0;
878  uint32_t hashsize = 0;
879 
880  const char *set_name = iter->name;
881  if (strlen(set_name) > DATASET_NAME_MAX_LEN) {
883  "set name '%s' too long, max %d chars", set_name, DATASET_NAME_MAX_LEN);
884  continue;
885  }
886 
887  ConfNode *set_type =
888  ConfNodeLookupChild(iter, "type");
889  if (set_type == NULL) {
890  list_pos++;
891  continue;
892  }
893 
894  ConfNode *set_save =
895  ConfNodeLookupChild(iter, "state");
896  if (set_save) {
897  DatasetGetPath(set_save->val, save, sizeof(save), TYPE_STATE);
898  strlcpy(load, save, sizeof(load));
899  } else {
900  ConfNode *set_load =
901  ConfNodeLookupChild(iter, "load");
902  if (set_load) {
903  DatasetGetPath(set_load->val, load, sizeof(load), TYPE_LOAD);
904  }
905  }
906 
907  ConfNode *set_memcap = ConfNodeLookupChild(iter, "memcap");
908  if (set_memcap) {
909  if (ParseSizeStringU64(set_memcap->val, &memcap) < 0) {
910  SCLogWarning("memcap value cannot be"
911  " deduced: %s, resetting to default",
912  set_memcap->val);
913  memcap = 0;
914  }
915  }
916  ConfNode *set_hashsize = ConfNodeLookupChild(iter, "hashsize");
917  if (set_hashsize) {
918  if (ParseSizeStringU32(set_hashsize->val, &hashsize) < 0) {
919  SCLogWarning("hashsize value cannot be"
920  " deduced: %s, resetting to default",
921  set_hashsize->val);
922  hashsize = 0;
923  }
924  }
925  char conf_str[1024];
926  snprintf(conf_str, sizeof(conf_str), "datasets.%d.%s", list_pos, set_name);
927 
928  SCLogDebug("set %s type %s. Conf %s", set_name, set_type->val, conf_str);
929 
930  if (strcmp(set_type->val, "md5") == 0) {
931  Dataset *dset = DatasetGet(set_name, DATASET_TYPE_MD5, save, load,
932  memcap > 0 ? memcap : default_memcap,
933  hashsize > 0 ? hashsize : default_hashsize);
934  if (dset == NULL) {
935  FatalErrorOnInit("failed to setup dataset for %s", set_name);
936  continue;
937  }
938  SCLogDebug("dataset %s: id %u type %s", set_name, dset->id, set_type->val);
939  dset->from_yaml = true;
940 
941  } else if (strcmp(set_type->val, "sha256") == 0) {
942  Dataset *dset = DatasetGet(set_name, DATASET_TYPE_SHA256, save, load,
943  memcap > 0 ? memcap : default_memcap,
944  hashsize > 0 ? hashsize : default_hashsize);
945  if (dset == NULL) {
946  FatalErrorOnInit("failed to setup dataset for %s", set_name);
947  continue;
948  }
949  SCLogDebug("dataset %s: id %u type %s", set_name, dset->id, set_type->val);
950  dset->from_yaml = true;
951 
952  } else if (strcmp(set_type->val, "string") == 0) {
953  Dataset *dset = DatasetGet(set_name, DATASET_TYPE_STRING, save, load,
954  memcap > 0 ? memcap : default_memcap,
955  hashsize > 0 ? hashsize : default_hashsize);
956  if (dset == NULL) {
957  FatalErrorOnInit("failed to setup dataset for %s", set_name);
958  continue;
959  }
960  SCLogDebug("dataset %s: id %u type %s", set_name, dset->id, set_type->val);
961  dset->from_yaml = true;
962 
963  } else if (strcmp(set_type->val, "ipv4") == 0) {
964  Dataset *dset = DatasetGet(set_name, DATASET_TYPE_IPV4, save, load,
965  memcap > 0 ? memcap : default_memcap,
966  hashsize > 0 ? hashsize : default_hashsize);
967  if (dset == NULL) {
968  FatalErrorOnInit("failed to setup dataset for %s", set_name);
969  continue;
970  }
971  SCLogDebug("dataset %s: id %u type %s", set_name, dset->id, set_type->val);
972  dset->from_yaml = true;
973 
974  } else if (strcmp(set_type->val, "ip") == 0) {
975  Dataset *dset = DatasetGet(set_name, DATASET_TYPE_IPV6, save, load,
976  memcap > 0 ? memcap : default_memcap,
977  hashsize > 0 ? hashsize : default_hashsize);
978  if (dset == NULL) {
979  FatalErrorOnInit("failed to setup dataset for %s", set_name);
980  continue;
981  }
982  SCLogDebug("dataset %s: id %u type %s", set_name, dset->id, set_type->val);
983  dset->from_yaml = true;
984  }
985 
986  list_pos++;
987  }
988  }
989  SCLogDebug("datasets done: %p", datasets);
990  return 0;
991 }
992 
993 void DatasetsDestroy(void)
994 {
995  SCLogDebug("destroying datasets: %p", sets);
997  Dataset *set = sets;
998  while (set) {
999  SCLogDebug("destroying set %s", set->name);
1000  Dataset *next = set->next;
1001  THashShutdown(set->hash);
1002  SCFree(set);
1003  set = next;
1004  }
1005  sets = NULL;
1007  SCLogDebug("destroying datasets done: %p", sets);
1008 }
1009 
1010 static int SaveCallback(void *ctx, const uint8_t *data, const uint32_t data_len)
1011 {
1012  FILE *fp = ctx;
1013  //PrintRawDataFp(fp, data, data_len);
1014  if (fp) {
1015  return (int)fwrite(data, data_len, 1, fp);
1016  }
1017  return 0;
1018 }
1019 
1020 static int Md5AsAscii(const void *s, char *out, size_t out_size)
1021 {
1022  const Md5Type *md5 = s;
1023  char str[256];
1024  PrintHexString(str, sizeof(str), (uint8_t *)md5->md5, sizeof(md5->md5));
1025  strlcat(out, str, out_size);
1026  strlcat(out, "\n", out_size);
1027  return (int)strlen(out);
1028 }
1029 
1030 static int Sha256AsAscii(const void *s, char *out, size_t out_size)
1031 {
1032  const Sha256Type *sha = s;
1033  char str[256];
1034  PrintHexString(str, sizeof(str), (uint8_t *)sha->sha256, sizeof(sha->sha256));
1035  strlcat(out, str, out_size);
1036  strlcat(out, "\n", out_size);
1037  return (int)strlen(out);
1038 }
1039 
1040 static int IPv4AsAscii(const void *s, char *out, size_t out_size)
1041 {
1042  const IPv4Type *ip4 = s;
1043  char str[256];
1044  PrintInet(AF_INET, ip4->ipv4, str, sizeof(str));
1045  strlcat(out, str, out_size);
1046  strlcat(out, "\n", out_size);
1047  return (int)strlen(out);
1048 }
1049 
1050 static int IPv6AsAscii(const void *s, char *out, size_t out_size)
1051 {
1052  const IPv6Type *ip6 = s;
1053  char str[256];
1054  bool is_ipv4 = true;
1055  for (int i = 4; i <= 15; i++) {
1056  if (ip6->ipv6[i] != 0) {
1057  is_ipv4 = false;
1058  break;
1059  }
1060  }
1061  if (is_ipv4) {
1062  PrintInet(AF_INET, ip6->ipv6, str, sizeof(str));
1063  } else {
1064  PrintInet(AF_INET6, ip6->ipv6, str, sizeof(str));
1065  }
1066  strlcat(out, str, out_size);
1067  strlcat(out, "\n", out_size);
1068  return (int)strlen(out);
1069 }
1070 
1071 void DatasetsSave(void)
1072 {
1073  SCLogDebug("saving datasets: %p", sets);
1075  Dataset *set = sets;
1076  while (set) {
1077  if (strlen(set->save) == 0)
1078  goto next;
1079 
1080  FILE *fp = fopen(set->save, "w");
1081  if (fp == NULL)
1082  goto next;
1083 
1084  SCLogDebug("dumping %s to %s", set->name, set->save);
1085 
1086  switch (set->type) {
1087  case DATASET_TYPE_STRING:
1088  THashWalk(set->hash, StringAsBase64, SaveCallback, fp);
1089  break;
1090  case DATASET_TYPE_MD5:
1091  THashWalk(set->hash, Md5AsAscii, SaveCallback, fp);
1092  break;
1093  case DATASET_TYPE_SHA256:
1094  THashWalk(set->hash, Sha256AsAscii, SaveCallback, fp);
1095  break;
1096  case DATASET_TYPE_IPV4:
1097  THashWalk(set->hash, IPv4AsAscii, SaveCallback, fp);
1098  break;
1099  case DATASET_TYPE_IPV6:
1100  THashWalk(set->hash, IPv6AsAscii, SaveCallback, fp);
1101  break;
1102  }
1103 
1104  fclose(fp);
1105 
1106  next:
1107  set = set->next;
1108  }
1110 }
1111 
1112 static int DatasetLookupString(Dataset *set, const uint8_t *data, const uint32_t data_len)
1113 {
1114  if (set == NULL)
1115  return -1;
1116 
1117  StringType lookup = { .ptr = (uint8_t *)data, .len = data_len, .rep.value = 0 };
1118  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1119  if (rdata) {
1120  DatasetUnlockData(rdata);
1121  return 1;
1122  }
1123  return 0;
1124 }
1125 
1126 static DataRepResultType DatasetLookupStringwRep(Dataset *set,
1127  const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1128 {
1129  DataRepResultType rrep = { .found = false, .rep = { .value = 0 }};
1130 
1131  if (set == NULL)
1132  return rrep;
1133 
1134  StringType lookup = { .ptr = (uint8_t *)data, .len = data_len, .rep = *rep };
1135  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1136  if (rdata) {
1137  StringType *found = rdata->data;
1138  rrep.found = true;
1139  rrep.rep = found->rep;
1140  DatasetUnlockData(rdata);
1141  return rrep;
1142  }
1143  return rrep;
1144 }
1145 
1146 static int DatasetLookupIPv4(Dataset *set, const uint8_t *data, const uint32_t data_len)
1147 {
1148  if (set == NULL)
1149  return -1;
1150 
1151  if (data_len != 4)
1152  return -1;
1153 
1154  IPv4Type lookup = { .rep.value = 0 };
1155  memcpy(lookup.ipv4, data, 4);
1156  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1157  if (rdata) {
1158  DatasetUnlockData(rdata);
1159  return 1;
1160  }
1161  return 0;
1162 }
1163 
1164 static DataRepResultType DatasetLookupIPv4wRep(
1165  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1166 {
1167  DataRepResultType rrep = { .found = false, .rep = { .value = 0 } };
1168 
1169  if (set == NULL)
1170  return rrep;
1171 
1172  if (data_len != 4)
1173  return rrep;
1174 
1175  IPv4Type lookup = { .rep.value = 0 };
1176  memcpy(lookup.ipv4, data, data_len);
1177  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1178  if (rdata) {
1179  IPv4Type *found = rdata->data;
1180  rrep.found = true;
1181  rrep.rep = found->rep;
1182  DatasetUnlockData(rdata);
1183  return rrep;
1184  }
1185  return rrep;
1186 }
1187 
1188 static int DatasetLookupIPv6(Dataset *set, const uint8_t *data, const uint32_t data_len)
1189 {
1190  if (set == NULL)
1191  return -1;
1192 
1193  if (data_len != 16 && data_len != 4)
1194  return -1;
1195 
1196  IPv6Type lookup = { .rep.value = 0 };
1197  memcpy(lookup.ipv6, data, data_len);
1198  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1199  if (rdata) {
1200  DatasetUnlockData(rdata);
1201  return 1;
1202  }
1203  return 0;
1204 }
1205 
1206 static DataRepResultType DatasetLookupIPv6wRep(
1207  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1208 {
1209  DataRepResultType rrep = { .found = false, .rep = { .value = 0 } };
1210 
1211  if (set == NULL)
1212  return rrep;
1213 
1214  if (data_len != 16 && data_len != 4)
1215  return rrep;
1216 
1217  IPv6Type lookup = { .rep.value = 0 };
1218  memcpy(lookup.ipv6, data, data_len);
1219  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1220  if (rdata) {
1221  IPv6Type *found = rdata->data;
1222  rrep.found = true;
1223  rrep.rep = found->rep;
1224  DatasetUnlockData(rdata);
1225  return rrep;
1226  }
1227  return rrep;
1228 }
1229 
1230 static int DatasetLookupMd5(Dataset *set, const uint8_t *data, const uint32_t data_len)
1231 {
1232  if (set == NULL)
1233  return -1;
1234 
1235  if (data_len != 16)
1236  return -1;
1237 
1238  Md5Type lookup = { .rep.value = 0 };
1239  memcpy(lookup.md5, data, data_len);
1240  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1241  if (rdata) {
1242  DatasetUnlockData(rdata);
1243  return 1;
1244  }
1245  return 0;
1246 }
1247 
1248 static DataRepResultType DatasetLookupMd5wRep(Dataset *set,
1249  const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1250 {
1251  DataRepResultType rrep = { .found = false, .rep = { .value = 0 }};
1252 
1253  if (set == NULL)
1254  return rrep;
1255 
1256  if (data_len != 16)
1257  return rrep;
1258 
1259  Md5Type lookup = { .rep.value = 0};
1260  memcpy(lookup.md5, data, data_len);
1261  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1262  if (rdata) {
1263  Md5Type *found = rdata->data;
1264  rrep.found = true;
1265  rrep.rep = found->rep;
1266  DatasetUnlockData(rdata);
1267  return rrep;
1268  }
1269  return rrep;
1270 }
1271 
1272 static int DatasetLookupSha256(Dataset *set, const uint8_t *data, const uint32_t data_len)
1273 {
1274  if (set == NULL)
1275  return -1;
1276 
1277  if (data_len != 32)
1278  return -1;
1279 
1280  Sha256Type lookup = { .rep.value = 0 };
1281  memcpy(lookup.sha256, data, data_len);
1282  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1283  if (rdata) {
1284  DatasetUnlockData(rdata);
1285  return 1;
1286  }
1287  return 0;
1288 }
1289 
1290 static DataRepResultType DatasetLookupSha256wRep(Dataset *set,
1291  const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1292 {
1293  DataRepResultType rrep = { .found = false, .rep = { .value = 0 }};
1294 
1295  if (set == NULL)
1296  return rrep;
1297 
1298  if (data_len != 32)
1299  return rrep;
1300 
1301  Sha256Type lookup = { .rep.value = 0 };
1302  memcpy(lookup.sha256, data, data_len);
1303  THashData *rdata = THashLookupFromHash(set->hash, &lookup);
1304  if (rdata) {
1305  Sha256Type *found = rdata->data;
1306  rrep.found = true;
1307  rrep.rep = found->rep;
1308  DatasetUnlockData(rdata);
1309  return rrep;
1310  }
1311  return rrep;
1312 }
1313 
1314 /**
1315  * \brief see if \a data is part of the set
1316  * \param set dataset
1317  * \param data data to look up
1318  * \param data_len length in bytes of \a data
1319  * \retval -1 error
1320  * \retval 0 not found
1321  * \retval 1 found
1322  */
1323 int DatasetLookup(Dataset *set, const uint8_t *data, const uint32_t data_len)
1324 {
1325  if (set == NULL)
1326  return -1;
1327 
1328  switch (set->type) {
1329  case DATASET_TYPE_STRING:
1330  return DatasetLookupString(set, data, data_len);
1331  case DATASET_TYPE_MD5:
1332  return DatasetLookupMd5(set, data, data_len);
1333  case DATASET_TYPE_SHA256:
1334  return DatasetLookupSha256(set, data, data_len);
1335  case DATASET_TYPE_IPV4:
1336  return DatasetLookupIPv4(set, data, data_len);
1337  case DATASET_TYPE_IPV6:
1338  return DatasetLookupIPv6(set, data, data_len);
1339  }
1340  return -1;
1341 }
1342 
1343 DataRepResultType DatasetLookupwRep(Dataset *set, const uint8_t *data, const uint32_t data_len,
1344  const DataRepType *rep)
1345 {
1346  DataRepResultType rrep = { .found = false, .rep = { .value = 0 }};
1347  if (set == NULL)
1348  return rrep;
1349 
1350  switch (set->type) {
1351  case DATASET_TYPE_STRING:
1352  return DatasetLookupStringwRep(set, data, data_len, rep);
1353  case DATASET_TYPE_MD5:
1354  return DatasetLookupMd5wRep(set, data, data_len, rep);
1355  case DATASET_TYPE_SHA256:
1356  return DatasetLookupSha256wRep(set, data, data_len, rep);
1357  case DATASET_TYPE_IPV4:
1358  return DatasetLookupIPv4wRep(set, data, data_len, rep);
1359  case DATASET_TYPE_IPV6:
1360  return DatasetLookupIPv6wRep(set, data, data_len, rep);
1361  }
1362  return rrep;
1363 }
1364 
1365 /**
1366  * \retval 1 data was added to the hash
1367  * \retval 0 data was not added to the hash as it is already there
1368  * \retval -1 failed to add data to the hash
1369  */
1370 static int DatasetAddString(Dataset *set, const uint8_t *data, const uint32_t data_len)
1371 {
1372  if (set == NULL)
1373  return -1;
1374 
1375  StringType lookup = { .ptr = (uint8_t *)data, .len = data_len,
1376  .rep.value = 0 };
1377  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1378  if (res.data) {
1379  DatasetUnlockData(res.data);
1380  return res.is_new ? 1 : 0;
1381  }
1382  return -1;
1383 }
1384 
1385 /**
1386  * \retval 1 data was added to the hash
1387  * \retval 0 data was not added to the hash as it is already there
1388  * \retval -1 failed to add data to the hash
1389  */
1390 static int DatasetAddStringwRep(
1391  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1392 {
1393  if (set == NULL)
1394  return -1;
1395 
1396  StringType lookup = { .ptr = (uint8_t *)data, .len = data_len,
1397  .rep = *rep };
1398  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1399  if (res.data) {
1400  DatasetUnlockData(res.data);
1401  return res.is_new ? 1 : 0;
1402  }
1403  return -1;
1404 }
1405 
1406 static int DatasetAddIPv4(Dataset *set, const uint8_t *data, const uint32_t data_len)
1407 {
1408  if (set == NULL) {
1409  return -1;
1410  }
1411 
1412  if (data_len < 4) {
1413  return -2;
1414  }
1415 
1416  IPv4Type lookup = { .rep.value = 0 };
1417  memcpy(lookup.ipv4, data, 4);
1418  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1419  if (res.data) {
1420  DatasetUnlockData(res.data);
1421  return res.is_new ? 1 : 0;
1422  }
1423  return -1;
1424 }
1425 
1426 static int DatasetAddIPv6(Dataset *set, const uint8_t *data, const uint32_t data_len)
1427 {
1428  if (set == NULL) {
1429  return -1;
1430  }
1431 
1432  if (data_len != 16) {
1433  return -2;
1434  }
1435 
1436  IPv6Type lookup = { .rep.value = 0 };
1437  memcpy(lookup.ipv6, data, 16);
1438  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1439  if (res.data) {
1440  DatasetUnlockData(res.data);
1441  return res.is_new ? 1 : 0;
1442  }
1443  return -1;
1444 }
1445 
1446 static int DatasetAddIPv4wRep(
1447  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1448 {
1449  if (set == NULL)
1450  return -1;
1451 
1452  if (data_len < 4)
1453  return -2;
1454 
1455  IPv4Type lookup = { .rep = *rep };
1456  memcpy(lookup.ipv4, data, 4);
1457  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1458  if (res.data) {
1459  DatasetUnlockData(res.data);
1460  return res.is_new ? 1 : 0;
1461  }
1462  return -1;
1463 }
1464 
1465 static int DatasetAddIPv6wRep(
1466  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1467 {
1468  if (set == NULL)
1469  return -1;
1470 
1471  if (data_len != 16)
1472  return -2;
1473 
1474  IPv6Type lookup = { .rep = *rep };
1475  memcpy(lookup.ipv6, data, 16);
1476  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1477  if (res.data) {
1478  DatasetUnlockData(res.data);
1479  return res.is_new ? 1 : 0;
1480  }
1481  return -1;
1482 }
1483 
1484 static int DatasetAddMd5(Dataset *set, const uint8_t *data, const uint32_t data_len)
1485 {
1486  if (set == NULL)
1487  return -1;
1488 
1489  if (data_len != 16)
1490  return -2;
1491 
1492  Md5Type lookup = { .rep.value = 0 };
1493  memcpy(lookup.md5, data, 16);
1494  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1495  if (res.data) {
1496  DatasetUnlockData(res.data);
1497  return res.is_new ? 1 : 0;
1498  }
1499  return -1;
1500 }
1501 
1502 static int DatasetAddMd5wRep(
1503  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1504 {
1505  if (set == NULL)
1506  return -1;
1507 
1508  if (data_len != 16)
1509  return -2;
1510 
1511  Md5Type lookup = { .rep = *rep };
1512  memcpy(lookup.md5, data, 16);
1513  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1514  if (res.data) {
1515  DatasetUnlockData(res.data);
1516  return res.is_new ? 1 : 0;
1517  }
1518  return -1;
1519 }
1520 
1521 static int DatasetAddSha256wRep(
1522  Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
1523 {
1524  if (set == NULL)
1525  return -1;
1526 
1527  if (data_len != 32)
1528  return -2;
1529 
1530  Sha256Type lookup = { .rep = *rep };
1531  memcpy(lookup.sha256, data, 32);
1532  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1533  if (res.data) {
1534  DatasetUnlockData(res.data);
1535  return res.is_new ? 1 : 0;
1536  }
1537  return -1;
1538 }
1539 
1540 static int DatasetAddSha256(Dataset *set, const uint8_t *data, const uint32_t data_len)
1541 {
1542  if (set == NULL)
1543  return -1;
1544 
1545  if (data_len != 32)
1546  return -2;
1547 
1548  Sha256Type lookup = { .rep.value = 0 };
1549  memcpy(lookup.sha256, data, 32);
1550  struct THashDataGetResult res = THashGetFromHash(set->hash, &lookup);
1551  if (res.data) {
1552  DatasetUnlockData(res.data);
1553  return res.is_new ? 1 : 0;
1554  }
1555  return -1;
1556 }
1557 
1558 int DatasetAdd(Dataset *set, const uint8_t *data, const uint32_t data_len)
1559 {
1560  if (set == NULL)
1561  return -1;
1562 
1563  switch (set->type) {
1564  case DATASET_TYPE_STRING:
1565  return DatasetAddString(set, data, data_len);
1566  case DATASET_TYPE_MD5:
1567  return DatasetAddMd5(set, data, data_len);
1568  case DATASET_TYPE_SHA256:
1569  return DatasetAddSha256(set, data, data_len);
1570  case DATASET_TYPE_IPV4:
1571  return DatasetAddIPv4(set, data, data_len);
1572  case DATASET_TYPE_IPV6:
1573  return DatasetAddIPv6(set, data, data_len);
1574  }
1575  return -1;
1576 }
1577 
1578 static int DatasetAddwRep(Dataset *set, const uint8_t *data, const uint32_t data_len,
1579  DataRepType *rep)
1580 {
1581  if (set == NULL)
1582  return -1;
1583 
1584  switch (set->type) {
1585  case DATASET_TYPE_STRING:
1586  return DatasetAddStringwRep(set, data, data_len, rep);
1587  case DATASET_TYPE_MD5:
1588  return DatasetAddMd5wRep(set, data, data_len, rep);
1589  case DATASET_TYPE_SHA256:
1590  return DatasetAddSha256wRep(set, data, data_len, rep);
1591  case DATASET_TYPE_IPV4:
1592  return DatasetAddIPv4wRep(set, data, data_len, rep);
1593  case DATASET_TYPE_IPV6:
1594  return DatasetAddIPv6wRep(set, data, data_len, rep);
1595  }
1596  return -1;
1597 }
1598 
1599 typedef int (*DatasetOpFunc)(Dataset *set, const uint8_t *data, const uint32_t data_len);
1600 
1601 static int DatasetOpSerialized(Dataset *set, const char *string, DatasetOpFunc DatasetOpString,
1602  DatasetOpFunc DatasetOpMd5, DatasetOpFunc DatasetOpSha256, DatasetOpFunc DatasetOpIPv4,
1603  DatasetOpFunc DatasetOpIPv6)
1604 {
1605  if (set == NULL)
1606  return -1;
1607 
1608  switch (set->type) {
1609  case DATASET_TYPE_STRING: {
1610  // coverity[alloc_strlen : FALSE]
1611  uint8_t decoded[strlen(string)];
1612  uint32_t consumed = 0, num_decoded = 0;
1613  Base64Ecode code =
1614  DecodeBase64(decoded, (uint32_t)strlen(string), (const uint8_t *)string,
1615  (uint32_t)strlen(string), &consumed, &num_decoded, Base64ModeStrict);
1616  if (code == BASE64_ECODE_ERR) {
1617  return -2;
1618  }
1619 
1620  return DatasetOpString(set, decoded, num_decoded);
1621  }
1622  case DATASET_TYPE_MD5: {
1623  if (strlen(string) != 32)
1624  return -2;
1625  uint8_t hash[16];
1626  if (HexToRaw((const uint8_t *)string, 32, hash, sizeof(hash)) < 0)
1627  return -2;
1628  return DatasetOpMd5(set, hash, 16);
1629  }
1630  case DATASET_TYPE_SHA256: {
1631  if (strlen(string) != 64)
1632  return -2;
1633  uint8_t hash[32];
1634  if (HexToRaw((const uint8_t *)string, 64, hash, sizeof(hash)) < 0)
1635  return -2;
1636  return DatasetOpSha256(set, hash, 32);
1637  }
1638  case DATASET_TYPE_IPV4: {
1639  struct in_addr in;
1640  if (inet_pton(AF_INET, string, &in) != 1)
1641  return -2;
1642  return DatasetOpIPv4(set, (uint8_t *)&in.s_addr, 4);
1643  }
1644  case DATASET_TYPE_IPV6: {
1645  struct in6_addr in;
1646  if (inet_pton(AF_INET6, string, &in) != 1)
1647  return -2;
1648  return DatasetOpIPv6(set, (uint8_t *)&in.s6_addr, 16);
1649  }
1650  }
1651  return -1;
1652 }
1653 
1654 /** \brief add serialized data to set
1655  * \retval int 1 added
1656  * \retval int 0 already in hash
1657  * \retval int -1 API error (not added)
1658  * \retval int -2 DATA error
1659  */
1660 int DatasetAddSerialized(Dataset *set, const char *string)
1661 {
1662  return DatasetOpSerialized(set, string, DatasetAddString, DatasetAddMd5, DatasetAddSha256,
1663  DatasetAddIPv4, DatasetAddIPv6);
1664 }
1665 
1666 /** \brief add serialized data to set
1667  * \retval int 1 added
1668  * \retval int 0 already in hash
1669  * \retval int -1 API error (not added)
1670  * \retval int -2 DATA error
1671  */
1672 int DatasetLookupSerialized(Dataset *set, const char *string)
1673 {
1674  return DatasetOpSerialized(set, string, DatasetLookupString, DatasetLookupMd5,
1675  DatasetLookupSha256, DatasetLookupIPv4, DatasetLookupIPv6);
1676 }
1677 
1678 /**
1679  * \retval 1 data was removed from the hash
1680  * \retval 0 data not removed (busy)
1681  * \retval -1 data not found
1682  */
1683 static int DatasetRemoveString(Dataset *set, const uint8_t *data, const uint32_t data_len)
1684 {
1685  if (set == NULL)
1686  return -1;
1687 
1688  StringType lookup = { .ptr = (uint8_t *)data, .len = data_len,
1689  .rep.value = 0 };
1690  return THashRemoveFromHash(set->hash, &lookup);
1691 }
1692 
1693 static int DatasetRemoveIPv4(Dataset *set, const uint8_t *data, const uint32_t data_len)
1694 {
1695  if (set == NULL)
1696  return -1;
1697 
1698  if (data_len != 4)
1699  return -2;
1700 
1701  IPv4Type lookup = { .rep.value = 0 };
1702  memcpy(lookup.ipv4, data, 4);
1703  return THashRemoveFromHash(set->hash, &lookup);
1704 }
1705 
1706 static int DatasetRemoveIPv6(Dataset *set, const uint8_t *data, const uint32_t data_len)
1707 {
1708  if (set == NULL)
1709  return -1;
1710 
1711  if (data_len != 16)
1712  return -2;
1713 
1714  IPv6Type lookup = { .rep.value = 0 };
1715  memcpy(lookup.ipv6, data, 16);
1716  return THashRemoveFromHash(set->hash, &lookup);
1717 }
1718 
1719 static int DatasetRemoveMd5(Dataset *set, const uint8_t *data, const uint32_t data_len)
1720 {
1721  if (set == NULL)
1722  return -1;
1723 
1724  if (data_len != 16)
1725  return -2;
1726 
1727  Md5Type lookup = { .rep.value = 0 };
1728  memcpy(lookup.md5, data, 16);
1729  return THashRemoveFromHash(set->hash, &lookup);
1730 }
1731 
1732 static int DatasetRemoveSha256(Dataset *set, const uint8_t *data, const uint32_t data_len)
1733 {
1734  if (set == NULL)
1735  return -1;
1736 
1737  if (data_len != 32)
1738  return -2;
1739 
1740  Sha256Type lookup = { .rep.value = 0 };
1741  memcpy(lookup.sha256, data, 32);
1742  return THashRemoveFromHash(set->hash, &lookup);
1743 }
1744 
1745 /** \brief remove serialized data from set
1746  * \retval int 1 removed
1747  * \retval int 0 found but busy (not removed)
1748  * \retval int -1 API error (not removed)
1749  * \retval int -2 DATA error */
1750 int DatasetRemoveSerialized(Dataset *set, const char *string)
1751 {
1752  return DatasetOpSerialized(set, string, DatasetRemoveString, DatasetRemoveMd5,
1753  DatasetRemoveSha256, DatasetRemoveIPv4, DatasetRemoveIPv6);
1754 }
util-byte.h
sets_lock
SCMutex sets_lock
Definition: datasets.c:44
StringType::rep
DataRepType rep
Definition: datasets-string.h:31
len
uint8_t len
Definition: app-layer-dnp3.h:2
datasets-string.h
DataRepResultType::rep
DataRepType rep
Definition: datasets-reputation.h:33
THashDataGetResult::data
THashData * data
Definition: util-thash.h:191
datasets-md5.h
THashInit
THashTableContext * THashInit(const char *cnf_prefix, size_t data_size, int(*DataSet)(void *, void *), void(*DataFree)(void *), uint32_t(*DataHash)(void *), bool(*DataCompare)(void *, void *), bool(*DataExpired)(void *, SCTime_t), uint32_t(*DataSize)(void *), bool reset_memcap, uint64_t memcap, uint32_t hashsize)
Definition: util-thash.c:302
Dataset::name
char name[DATASET_NAME_MAX_LEN+1]
Definition: datasets.h:41
ConfNode_::val
char * val
Definition: conf.h:34
BASE64_ECODE_ERR
@ BASE64_ECODE_ERR
Definition: util-base64.h:36
Dataset::id
uint32_t id
Definition: datasets.h:43
Dataset::save
char save[PATH_MAX]
Definition: datasets.h:49
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:190
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
datasets-sha256.h
IPv6Compare
bool IPv6Compare(void *a, void *b)
Definition: datasets-ipv6.c:40
THashRemoveFromHash
int THashRemoveFromHash(THashTableContext *ctx, void *data)
Definition: util-thash.c:870
TYPE_STATE
@ TYPE_STATE
Definition: datasets.c:582
Md5Type
Definition: datasets-md5.h:29
Dataset::hash
THashTableContext * hash
Definition: datasets.h:46
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:181
IPv6Hash
uint32_t IPv6Hash(void *s)
Definition: datasets-ipv6.c:48
ctx
struct Thresholds ctx
Sha256Type::sha256
uint8_t sha256[32]
Definition: datasets-sha256.h:30
Md5Type::rep
DataRepType rep
Definition: datasets-md5.h:31
DataRepResultType::found
bool found
Definition: datasets-reputation.h:32
PrintHexString
void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
Definition: util-print.c:255
Dataset::type
enum DatasetTypes type
Definition: datasets.h:42
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
THashConsolidateMemcap
void THashConsolidateMemcap(THashTableContext *ctx)
Definition: util-thash.c:349
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
util-base64.h
rust.h
DATASET_TYPE_SHA256
@ DATASET_TYPE_SHA256
Definition: datasets.h:34
Sha256Type::rep
DataRepType rep
Definition: datasets-sha256.h:31
SCMUTEX_INITIALIZER
#define SCMUTEX_INITIALIZER
Definition: threads-debug.h:121
datasets-reputation.h
ConfigGetDataDirectory
const char * ConfigGetDataDirectory(void)
Definition: util-conf.c:80
Md5Type::md5
uint8_t md5[16]
Definition: datasets-md5.h:30
DATASET_TYPE_IPV6
@ DATASET_TYPE_IPV6
Definition: datasets.h:36
Md5StrCompare
bool Md5StrCompare(void *a, void *b)
Definition: datasets-md5.c:41
DatasetLookupSerialized
int DatasetLookupSerialized(Dataset *set, const char *string)
add serialized data to set
Definition: datasets.c:1672
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
DataRepResultType
Definition: datasets-reputation.h:31
Md5StrHash
uint32_t Md5StrHash(void *s)
Definition: datasets-md5.c:49
DatasetGet
Dataset * DatasetGet(const char *name, enum DatasetTypes type, const char *save, const char *load, uint64_t memcap, uint32_t hashsize)
Definition: datasets.c:633
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:335
StringSet
int StringSet(void *dst, void *src)
Definition: datasets-string.c:61
datasets.h
IPv6Set
int IPv6Set(void *dst, void *src)
Definition: datasets-ipv6.c:31
util-debug.h
TYPE_LOAD
@ TYPE_LOAD
Definition: datasets.c:583
DatasetAdd
int DatasetAdd(Dataset *set, const uint8_t *data, const uint32_t data_len)
Definition: datasets.c:1558
DecodeBase64
Base64Ecode DecodeBase64(uint8_t *dest, uint32_t dest_size, const uint8_t *src, uint32_t len, uint32_t *consumed_bytes, uint32_t *decoded_bytes, DetectBase64Mode mode)
Decodes a base64-encoded string buffer into an ascii-encoded byte buffer.
Definition: util-base64.c:276
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
StringAsBase64
int StringAsBase64(const void *s, char *out, size_t out_size)
Definition: datasets-string.c:46
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
datasets-ipv6.h
IPv6Type::ipv6
uint8_t ipv6[16]
Definition: datasets-ipv6.h:30
DATASET_TYPE_NOTSET
#define DATASET_TYPE_NOTSET
Definition: datasets.h:31
IPv6Type::rep
DataRepType rep
Definition: datasets-ipv6.h:31
util-print.h
DatasetPostReloadCleanup
void DatasetPostReloadCleanup(void)
Definition: datasets.c:812
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:231
StringParseU16RangeCheck
int StringParseU16RangeCheck(uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
Definition: util-byte.c:433
DatasetOpFunc
int(* DatasetOpFunc)(Dataset *set, const uint8_t *data, const uint32_t data_len)
Definition: datasets.c:1599
datasets-ipv4.h
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
StringGetLength
uint32_t StringGetLength(void *s)
Definition: datasets-string.c:101
Sha256StrSet
int Sha256StrSet(void *dst, void *src)
Definition: datasets-sha256.c:32
DatasetsDestroy
void DatasetsDestroy(void)
Definition: datasets.c:993
THashDataGetResult
Definition: util-thash.h:190
StringType
Definition: datasets-string.h:29
IPv4Set
int IPv4Set(void *dst, void *src)
Definition: datasets-ipv4.c:31
type
uint16_t type
Definition: decode-vlan.c:107
DatasetsSave
void DatasetsSave(void)
Definition: datasets.c:1071
conf.h
IPv6Type
Definition: datasets-ipv6.h:29
DatasetLookup
int DatasetLookup(Dataset *set, const uint8_t *data, const uint32_t data_len)
see if data is part of the set
Definition: datasets.c:1323
DATASET_TYPE_IPV4
@ DATASET_TYPE_IPV4
Definition: datasets.h:35
StringType::ptr
uint8_t * ptr
Definition: datasets-string.h:32
DatasetRemoveSerialized
int DatasetRemoveSerialized(Dataset *set, const char *string)
remove serialized data from set
Definition: datasets.c:1750
Sha256StrHash
uint32_t Sha256StrHash(void *s)
Definition: datasets-sha256.c:49
g_system
bool g_system
Definition: suricata.c:189
ConfNodeLookupChild
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:781
THashShutdown
void THashShutdown(THashTableContext *ctx)
shutdown the flow engine
Definition: util-thash.c:357
DatasetTypes
DatasetTypes
Definition: datasets.h:30
Dataset::next
struct Dataset * next
Definition: datasets.h:51
THashData_::data
void * data
Definition: util-thash.h:92
cnt
uint32_t cnt
Definition: tmqh-packetpool.h:7
util-conf.h
Sha256Type
Definition: datasets-sha256.h:29
Sha256StrFree
void Sha256StrFree(void *s)
Definition: datasets-sha256.c:61
THashData_
Definition: util-thash.h:85
IPv4Free
void IPv4Free(void *s)
Definition: datasets-ipv4.c:60
IPv4Hash
uint32_t IPv4Hash(void *s)
Definition: datasets-ipv4.c:48
suricata-common.h
util-path.h
StringHash
uint32_t StringHash(void *s)
Definition: datasets-string.c:88
FatalErrorOnInit
#define FatalErrorOnInit(...)
Fatal error IF we're starting up, and configured to consider errors to be fatal errors.
Definition: util-debug.h:511
DATASET_NAME_MAX_LEN
#define DATASET_NAME_MAX_LEN
Definition: datasets.h:39
ConfNode_::name
char * name
Definition: conf.h:33
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:44
Md5StrSet
int Md5StrSet(void *dst, void *src)
Definition: datasets-md5.c:32
StringCompare
bool StringCompare(void *a, void *b)
Definition: datasets-string.c:77
THashGetFromHash
struct THashDataGetResult THashGetFromHash(THashTableContext *ctx, void *data)
Definition: util-thash.c:617
hashsize
#define hashsize(n)
Definition: util-hash-lookup3.h:40
THashLookupFromHash
THashData * THashLookupFromHash(THashTableContext *ctx, void *data)
look up data in the hash
Definition: util-thash.c:727
IPv4Type
Definition: datasets-ipv4.h:29
DataRepType::value
uint16_t value
Definition: datasets-reputation.h:28
ParseSizeStringU32
int ParseSizeStringU32(const char *size, uint32_t *res)
Definition: util-misc.c:173
THashDecrUsecnt
#define THashDecrUsecnt(h)
Definition: util-thash.h:169
IPv4Compare
bool IPv4Compare(void *a, void *b)
Definition: datasets-ipv4.c:40
DatasetFind
Dataset * DatasetFind(const char *name, enum DatasetTypes type)
look for set by name without creating it
Definition: datasets.c:619
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
DatasetsInit
int DatasetsInit(void)
Definition: datasets.c:859
str
#define str(s)
Definition: suricata-common.h:291
DatasetGetTypeFromString
enum DatasetTypes DatasetGetTypeFromString(const char *s)
Definition: datasets.c:59
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
THashWalk
int THashWalk(THashTableContext *ctx, THashFormatFunc FormatterFunc, THashOutputFunc OutputterFunc, void *output_ctx)
Walk the hash.
Definition: util-thash.c:391
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
Dataset::hidden
bool hidden
Definition: datasets.h:45
DatasetReload
void DatasetReload(void)
Definition: datasets.c:790
DatasetGetPathType
DatasetGetPathType
Definition: datasets.c:581
Sha256StrCompare
bool Sha256StrCompare(void *a, void *b)
Definition: datasets-sha256.c:41
DATASET_TYPE_MD5
@ DATASET_TYPE_MD5
Definition: datasets.h:33
DATASET_TYPE_STRING
@ DATASET_TYPE_STRING
Definition: datasets.h:32
THashDataGetResult::is_new
bool is_new
Definition: util-thash.h:192
IPv6Free
void IPv6Free(void *s)
Definition: datasets-ipv6.c:60
suricata.h
IPv4Type::ipv4
uint8_t ipv4[4]
Definition: datasets-ipv4.h:30
DatasetAddSerialized
int DatasetAddSerialized(Dataset *set, const char *string)
add serialized data to set
Definition: datasets.c:1660
Dataset
Definition: datasets.h:40
Dataset::from_yaml
bool from_yaml
Definition: datasets.h:44
IPv4Type::rep
DataRepType rep
Definition: datasets-ipv4.h:31
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
util-misc.h
util-thash.h
Dataset::load
char load[PATH_MAX]
Definition: datasets.h:48
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DataRepType
Definition: datasets-reputation.h:27
Md5StrFree
void Md5StrFree(void *s)
Definition: datasets-md5.c:61
SCMutex
#define SCMutex
Definition: threads-debug.h:114
StringFree
void StringFree(void *s)
Definition: datasets-string.c:108
Base64Ecode
Base64Ecode
Definition: util-base64.h:35
DatasetLookupwRep
DataRepResultType DatasetLookupwRep(Dataset *set, const uint8_t *data, const uint32_t data_len, const DataRepType *rep)
Definition: datasets.c:1343