47 static uint32_t set_ids = 0;
54 static void DatasetUpdateHashsize(
const char *
name, uint32_t hash_size);
56 static inline void DatasetUnlockData(
THashData *d)
61 static bool DatasetIsStatic(
const char *save,
const char *load);
65 if (strcasecmp(
"md5", s) == 0)
67 if (strcasecmp(
"sha256", s) == 0)
69 if (strcasecmp(
"string", s) == 0)
71 if (strcasecmp(
"ipv4", s) == 0)
73 if (strcasecmp(
"ip", s) == 0)
81 if (set->
hash == NULL) {
86 SCLogError(
"dataset too large for set memcap");
91 "set %p/%s type %u save %s load %s", set, set->
name, set->
type, set->
save, set->
load);
132 static int DatasetLoadIPv4(
Dataset *set)
134 if (strlen(set->
load) == 0)
138 const char *fopen_mode =
"r";
139 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
143 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSIpv4);
146 }
else if (retval == -1) {
158 const char *got_colon = strchr(line,
':');
161 if (inet_pton(AF_INET6, line, in6) != 1) {
165 memcpy(&ip6addr, in6->s6_addr,
sizeof(ip6addr));
167 if (ip6addr[0] == 0 && ip6addr[1] == 0 && ip6addr[2] == 0xFFFF0000) {
168 ip6addr[0] = ip6addr[3];
171 memcpy(in6, ip6addr,
sizeof(
struct in6_addr));
176 if (inet_pton(AF_INET, line, &in) != 1) {
180 memset(in6, 0,
sizeof(
struct in6_addr));
181 memcpy(in6, &in,
sizeof(
struct in_addr));
186 static int DatasetLoadIPv6(
Dataset *set)
188 if (strlen(set->
load) == 0)
192 const char *fopen_mode =
"r";
193 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
197 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSIpv6);
200 }
else if (retval == -1) {
209 static int DatasetLoadMd5(
Dataset *set)
211 if (strlen(set->
load) == 0)
215 const char *fopen_mode =
"r";
216 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
220 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSMd5);
223 }
else if (retval == -1) {
232 static int DatasetLoadSha256(
Dataset *set)
234 if (strlen(set->
load) == 0)
238 const char *fopen_mode =
"r";
239 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
243 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSSha256);
246 }
else if (retval == -1) {
255 static int DatasetLoadString(
Dataset *set)
257 if (strlen(set->
load) == 0)
262 const char *fopen_mode =
"r";
263 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
267 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSString);
270 }
else if (retval == -1) {
286 static void DatasetGetPath(
293 strlcpy(path, in_path,
sizeof(path));
294 strlcpy(out_path, path, out_size);
299 if (stat(data_dir, &st) != 0) {
300 SCLogDebug(
"data-dir '%s': %s", data_dir, strerror(errno));
304 snprintf(path,
sizeof(path),
"%s/%s", data_dir, in_path);
307 if (stat(path, &st) != 0) {
308 SCLogDebug(
"path %s: %s", path, strerror(errno));
310 snprintf(path,
sizeof(path),
"%s", in_path);
314 strlcpy(out_path, path, out_size);
315 SCLogDebug(
"in_path \'%s\' => \'%s\'", in_path, out_path);
333 static bool DatasetCheckHashsize(
const char *
name, uint32_t hash_size)
336 SCLogError(
"hashsize %u in dataset '%s' exceeds configured 'single-hashsize' limit (%u)",
344 SCLogError(
"hashsize %u in dataset '%s' exceeds configured 'total-hashsizes' limit (%u, in "
353 static void DatasetUpdateHashsize(
const char *
name, uint32_t hash_size)
371 uint64_t default_memcap = 0;
372 uint32_t default_hashsize = 0;
381 "exists and is of type %u",
386 if ((save == NULL || strlen(save) == 0) &&
387 (load == NULL || strlen(load) == 0)) {
391 if ((save == NULL && strlen(set->
save) > 0) ||
392 (save != NULL && strcmp(set->
save, save) != 0)) {
397 if ((load == NULL && strlen(set->
load) > 0) ||
398 (load != NULL && strcmp(set->
load, load) != 0)) {
418 *memcap = default_memcap;
432 if (save && strlen(save)) {
436 if (load && strlen(load)) {
469 snprintf(cnf_name,
sizeof(cnf_name),
"datasets.%s.hash",
name);
474 if (set->
hash == NULL)
476 if (DatasetLoadMd5(set) < 0)
482 if (set->
hash == NULL)
484 if (DatasetLoadString(set) < 0)
491 if (set->
hash == NULL)
493 if (DatasetLoadSha256(set) < 0)
499 if (set->
hash == NULL)
501 if (DatasetLoadIPv4(set) < 0)
507 if (set->
hash == NULL)
509 if (DatasetLoadIPv6(set) < 0)
530 static bool DatasetIsStatic(
const char *save,
const char *load)
535 return (load != NULL && strlen(load) > 0) && (save == NULL || strlen(save) == 0);
567 SCLogDebug(
"Post Reload Cleanup starting.. Hidden sets will be removed");
592 #define DATASETS_HASHSIZE_DEFAULT 4096
596 const char *
str = NULL;
600 " resetting to default",
611 " resetting to default: %u",
621 uint64_t default_memcap = 0;
622 uint32_t default_hashsize = 0;
624 if (datasets != NULL) {
625 const char *
str = NULL;
628 FatalError(
"failed to parse datasets.limits.total-hashsizes value: %s",
str);
633 FatalError(
"failed to parse datasets.limits.single-hashsize value: %s",
str);
638 FatalError(
"total-hashsizes (%u) cannot be smaller than single-hashsize (%u)",
649 if (iter->
name == NULL) {
654 char save[PATH_MAX] =
"";
655 char load[PATH_MAX] =
"";
659 const char *set_name = iter->
name;
667 if (set_type == NULL) {
674 DatasetGetPath(set_save->
val, save,
sizeof(save),
TYPE_STATE);
675 strlcpy(load, save,
sizeof(load));
679 DatasetGetPath(set_load->
val, load,
sizeof(load),
TYPE_LOAD);
687 " deduced: %s, resetting to default",
696 " deduced: %s, resetting to default",
702 snprintf(conf_str,
sizeof(conf_str),
"datasets.%d.%s", list_pos, set_name);
704 SCLogDebug(
"set %s type %s. Conf %s", set_name, set_type->
val, conf_str);
706 if (strcmp(set_type->
val,
"md5") == 0) {
708 memcap > 0 ? memcap : default_memcap,
714 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
717 }
else if (strcmp(set_type->
val,
"sha256") == 0) {
719 memcap > 0 ? memcap : default_memcap,
725 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
728 }
else if (strcmp(set_type->
val,
"string") == 0) {
730 memcap > 0 ? memcap : default_memcap,
736 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
739 }
else if (strcmp(set_type->
val,
"ipv4") == 0) {
741 memcap > 0 ? memcap : default_memcap,
747 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
750 }
else if (strcmp(set_type->
val,
"ip") == 0) {
752 memcap > 0 ? memcap : default_memcap,
758 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
786 SCLogDebug(
"destroying datasets done: %p", sets);
789 static int SaveCallback(
void *
ctx,
const uint8_t *data,
const uint32_t data_len)
794 return (
int)fwrite(data, data_len, 1, fp);
799 static int Md5AsAscii(
const void *s,
char *out,
size_t out_size)
806 return (
int)strlen(out);
809 static int Sha256AsAscii(
const void *s,
char *out,
size_t out_size)
816 return (
int)strlen(out);
819 static int IPv4AsAscii(
const void *s,
char *out,
size_t out_size)
826 return (
int)strlen(out);
829 static int IPv6AsAscii(
const void *s,
char *out,
size_t out_size)
834 for (
int i = 4; i <= 15; i++) {
835 if (ip6->
ipv6[i] != 0) {
847 return (
int)strlen(out);
856 if (strlen(set->
save) == 0)
859 FILE *fp = fopen(set->
save,
"w");
891 static int DatasetLookupString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
899 DatasetUnlockData(rdata);
906 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
913 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .rep = *rep };
919 DatasetUnlockData(rdata);
925 static int DatasetLookupIPv4(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
934 memcpy(lookup.
ipv4, data, 4);
937 DatasetUnlockData(rdata);
955 memcpy(lookup.
ipv4, data, data_len);
961 DatasetUnlockData(rdata);
967 static int DatasetLookupIPv6(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
972 if (data_len != 16 && data_len != 4)
976 memcpy(lookup.
ipv6, data, data_len);
979 DatasetUnlockData(rdata);
993 if (data_len != 16 && data_len != 4)
997 memcpy(lookup.
ipv6, data, data_len);
1003 DatasetUnlockData(rdata);
1009 static int DatasetLookupMd5(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1018 memcpy(lookup.
md5, data, data_len);
1021 DatasetUnlockData(rdata);
1028 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
1039 memcpy(lookup.
md5, data, data_len);
1045 DatasetUnlockData(rdata);
1051 static int DatasetLookupSha256(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1060 memcpy(lookup.
sha256, data, data_len);
1063 DatasetUnlockData(rdata);
1070 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
1081 memcpy(lookup.
sha256, data, data_len);
1087 DatasetUnlockData(rdata);
1107 switch (set->
type) {
1109 return DatasetLookupString(set, data, data_len);
1111 return DatasetLookupMd5(set, data, data_len);
1113 return DatasetLookupSha256(set, data, data_len);
1115 return DatasetLookupIPv4(set, data, data_len);
1117 return DatasetLookupIPv6(set, data, data_len);
1129 switch (set->
type) {
1131 return DatasetLookupStringwRep(set, data, data_len, rep);
1133 return DatasetLookupMd5wRep(set, data, data_len, rep);
1135 return DatasetLookupSha256wRep(set, data, data_len, rep);
1137 return DatasetLookupIPv4wRep(set, data, data_len, rep);
1139 return DatasetLookupIPv6wRep(set, data, data_len, rep);
1149 static int DatasetAddString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1154 StringType lookup = { .ptr = (uint8_t *)data, .
len = data_len, .rep = 0 };
1157 DatasetUnlockData(res.
data);
1158 return res.
is_new ? 1 : 0;
1168 static int DatasetAddStringwRep(
1178 DatasetUnlockData(res.
data);
1179 return res.
is_new ? 1 : 0;
1184 static int DatasetAddIPv4(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1198 DatasetUnlockData(res.
data);
1199 return res.
is_new ? 1 : 0;
1204 static int DatasetAddIPv6(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1210 if (data_len != 16 && data_len != 4) {
1215 memcpy(lookup.
ipv6,
data, data_len);
1218 DatasetUnlockData(res.
data);
1219 return res.
is_new ? 1 : 0;
1224 static int DatasetAddIPv4wRep(
1237 DatasetUnlockData(res.
data);
1238 return res.
is_new ? 1 : 0;
1243 static int DatasetAddIPv6wRep(
1256 DatasetUnlockData(res.
data);
1257 return res.
is_new ? 1 : 0;
1262 static int DatasetAddMd5(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1274 DatasetUnlockData(res.
data);
1275 return res.
is_new ? 1 : 0;
1280 static int DatasetAddMd5wRep(
1293 DatasetUnlockData(res.
data);
1294 return res.
is_new ? 1 : 0;
1299 static int DatasetAddSha256wRep(
1312 DatasetUnlockData(res.
data);
1313 return res.
is_new ? 1 : 0;
1318 static int DatasetAddSha256(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1330 DatasetUnlockData(res.
data);
1331 return res.
is_new ? 1 : 0;
1341 switch (set->
type) {
1343 return DatasetAddString(set,
data, data_len);
1345 return DatasetAddMd5(set,
data, data_len);
1347 return DatasetAddSha256(set,
data, data_len);
1349 return DatasetAddIPv4(set,
data, data_len);
1351 return DatasetAddIPv6(set,
data, data_len);
1362 switch (set->
type) {
1364 return DatasetAddStringwRep(set,
data, data_len, rep);
1366 return DatasetAddMd5wRep(set,
data, data_len, rep);
1368 return DatasetAddSha256wRep(set,
data, data_len, rep);
1370 return DatasetAddIPv4wRep(set,
data, data_len, rep);
1372 return DatasetAddIPv6wRep(set,
data, data_len, rep);
1379 static int DatasetOpSerialized(
Dataset *set,
const char *
string,
DatasetOpFunc DatasetOpString,
1385 if (strlen(
string) == 0)
1388 switch (set->
type) {
1390 if (strlen(
string) > UINT16_MAX) {
1394 uint32_t decoded_size = SCBase64DecodeBufferSize((uint32_t)strlen(
string));
1395 uint8_t decoded[decoded_size];
1396 uint32_t num_decoded = SCBase64Decode(
1397 (
const uint8_t *)
string, strlen(
string), SCBase64ModeStrict, decoded);
1398 if (num_decoded == 0) {
1402 return DatasetOpString(set, decoded, num_decoded);
1405 if (strlen(
string) != 32)
1408 if (
HexToRaw((
const uint8_t *)
string, 32, hash,
sizeof(hash)) < 0)
1410 return DatasetOpMd5(set, hash, 16);
1413 if (strlen(
string) != 64)
1416 if (
HexToRaw((
const uint8_t *)
string, 64, hash,
sizeof(hash)) < 0)
1418 return DatasetOpSha256(set, hash, 32);
1422 if (inet_pton(AF_INET,
string, &in) != 1)
1424 return DatasetOpIPv4(set, (uint8_t *)&in.s_addr, 4);
1427 struct in6_addr in6;
1429 SCLogError(
"Dataset failed to import %s as IPv6",
string);
1432 return DatasetOpIPv6(set, (uint8_t *)&in6.s6_addr, 16);
1446 return DatasetOpSerialized(set,
string, DatasetAddString, DatasetAddMd5, DatasetAddSha256,
1447 DatasetAddIPv4, DatasetAddIPv6);
1458 return DatasetOpSerialized(set,
string, DatasetLookupString, DatasetLookupMd5,
1459 DatasetLookupSha256, DatasetLookupIPv4, DatasetLookupIPv6);
1467 static int DatasetRemoveString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1472 StringType lookup = { .ptr = (uint8_t *)data, .
len = data_len, .rep = 0 };
1476 static int DatasetRemoveIPv4(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1485 memcpy(lookup.
ipv4, data, 4);
1489 static int DatasetRemoveIPv6(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1498 memcpy(lookup.
ipv6, data, 16);
1502 static int DatasetRemoveMd5(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1511 memcpy(lookup.
md5, data, 16);
1515 static int DatasetRemoveSha256(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1524 memcpy(lookup.
sha256, data, 32);
1535 return DatasetOpSerialized(set,
string, DatasetRemoveString, DatasetRemoveMd5,
1536 DatasetRemoveSha256, DatasetRemoveIPv4, DatasetRemoveIPv6);
1544 switch (set->
type) {
1546 return DatasetRemoveString(set, data, data_len);
1548 return DatasetRemoveMd5(set, data, data_len);
1550 return DatasetRemoveSha256(set, data, data_len);
1552 return DatasetRemoveIPv4(set, data, data_len);
1554 return DatasetRemoveIPv6(set, data, data_len);