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