48 static uint32_t set_ids = 0;
55 static void DatasetUpdateHashsize(
const char *
name, uint32_t hash_size);
57 static inline void DatasetUnlockData(
THashData *d)
62 static bool DatasetIsStatic(
const char *save,
const char *load);
66 if (strcasecmp(
"md5", s) == 0)
68 if (strcasecmp(
"sha256", s) == 0)
70 if (strcasecmp(
"string", s) == 0)
72 if (strcasecmp(
"ipv4", s) == 0)
74 if (strcasecmp(
"ip", s) == 0)
82 if (set->
hash == NULL) {
87 SCLogError(
"dataset too large for set memcap");
92 "set %p/%s type %u save %s load %s", set, set->
name, set->
type, set->
save, set->
load);
133 static int DatasetLoadIPv4(
Dataset *set)
135 if (strlen(set->
load) == 0)
139 const char *fopen_mode =
"r";
140 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
144 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSIpv4);
147 }
else if (retval == -1) {
159 char *got_colon = strchr(line,
':');
162 if (inet_pton(AF_INET6, line, in6) != 1) {
166 memcpy(&ip6addr, in6->s6_addr,
sizeof(ip6addr));
168 if (ip6addr[0] == 0 && ip6addr[1] == 0 && ip6addr[2] == 0xFFFF0000) {
169 ip6addr[0] = ip6addr[3];
172 memcpy(in6, ip6addr,
sizeof(
struct in6_addr));
177 if (inet_pton(AF_INET, line, &in) != 1) {
181 memset(in6, 0,
sizeof(
struct in6_addr));
182 memcpy(in6, &in,
sizeof(
struct in_addr));
187 static int DatasetLoadIPv6(
Dataset *set)
189 if (strlen(set->
load) == 0)
193 const char *fopen_mode =
"r";
194 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
198 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSIpv6);
201 }
else if (retval == -1) {
210 static int DatasetLoadMd5(
Dataset *set)
212 if (strlen(set->
load) == 0)
216 const char *fopen_mode =
"r";
217 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
221 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSMd5);
224 }
else if (retval == -1) {
233 static int DatasetLoadSha256(
Dataset *set)
235 if (strlen(set->
load) == 0)
239 const char *fopen_mode =
"r";
240 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
244 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSSha256);
247 }
else if (retval == -1) {
256 static int DatasetLoadString(
Dataset *set)
258 if (strlen(set->
load) == 0)
263 const char *fopen_mode =
"r";
264 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
268 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSString);
271 }
else if (retval == -1) {
287 static void DatasetGetPath(
294 strlcpy(path, in_path,
sizeof(path));
295 strlcpy(out_path, path, out_size);
300 if (stat(data_dir, &st) != 0) {
301 SCLogDebug(
"data-dir '%s': %s", data_dir, strerror(errno));
305 snprintf(path,
sizeof(path),
"%s/%s", data_dir, in_path);
308 if (stat(path, &st) != 0) {
309 SCLogDebug(
"path %s: %s", path, strerror(errno));
311 snprintf(path,
sizeof(path),
"%s", in_path);
315 strlcpy(out_path, path, out_size);
316 SCLogDebug(
"in_path \'%s\' => \'%s\'", in_path, out_path);
334 static bool DatasetCheckHashsize(
const char *
name, uint32_t hash_size)
337 SCLogError(
"hashsize %u in dataset '%s' exceeds configured 'single-hashsize' limit (%u)",
345 SCLogError(
"hashsize %u in dataset '%s' exceeds configured 'total-hashsizes' limit (%u, in "
354 static void DatasetUpdateHashsize(
const char *
name, uint32_t hash_size)
372 uint64_t default_memcap = 0;
373 uint32_t default_hashsize = 0;
382 "exists and is of type %u",
387 if ((save == NULL || strlen(save) == 0) &&
388 (load == NULL || strlen(load) == 0)) {
392 if ((save == NULL && strlen(set->
save) > 0) ||
393 (save != NULL && strcmp(set->
save, save) != 0)) {
398 if ((load == NULL && strlen(set->
load) > 0) ||
399 (load != NULL && strcmp(set->
load, load) != 0)) {
419 *memcap = default_memcap;
433 if (save && strlen(save)) {
437 if (load && strlen(load)) {
470 snprintf(cnf_name,
sizeof(cnf_name),
"datasets.%s.hash",
name);
475 if (set->
hash == NULL)
477 if (DatasetLoadMd5(set) < 0)
483 if (set->
hash == NULL)
485 if (DatasetLoadString(set) < 0)
492 if (set->
hash == NULL)
494 if (DatasetLoadSha256(set) < 0)
500 if (set->
hash == NULL)
502 if (DatasetLoadIPv4(set) < 0)
508 if (set->
hash == NULL)
510 if (DatasetLoadIPv6(set) < 0)
531 static bool DatasetIsStatic(
const char *save,
const char *load)
536 return (load != NULL && strlen(load) > 0) && (save == NULL || strlen(save) == 0);
568 SCLogDebug(
"Post Reload Cleanup starting.. Hidden sets will be removed");
593 #define DATASETS_HASHSIZE_DEFAULT 4096
597 const char *
str = NULL;
601 " resetting to default",
608 if (
SCConfGet(
"datasets.defaults.hashsize", &
str) == 1) {
612 " resetting to default: %u",
622 uint64_t default_memcap = 0;
623 uint32_t default_hashsize = 0;
625 if (datasets != NULL) {
626 const char *
str = NULL;
627 if (
SCConfGet(
"datasets.limits.total-hashsizes", &
str) == 1) {
629 FatalError(
"failed to parse datasets.limits.total-hashsizes value: %s",
str);
632 if (
SCConfGet(
"datasets.limits.single-hashsize", &
str) == 1) {
634 FatalError(
"failed to parse datasets.limits.single-hashsize value: %s",
str);
639 FatalError(
"total-hashsizes (%u) cannot be smaller than single-hashsize (%u)",
650 if (iter->
name == NULL) {
655 char save[PATH_MAX] =
"";
656 char load[PATH_MAX] =
"";
660 const char *set_name = iter->
name;
668 if (set_type == NULL) {
675 DatasetGetPath(set_save->
val, save,
sizeof(save),
TYPE_STATE);
676 strlcpy(load, save,
sizeof(load));
680 DatasetGetPath(set_load->
val, load,
sizeof(load),
TYPE_LOAD);
688 " deduced: %s, resetting to default",
697 " deduced: %s, resetting to default",
703 snprintf(conf_str,
sizeof(conf_str),
"datasets.%d.%s", list_pos, set_name);
705 SCLogDebug(
"set %s type %s. Conf %s", set_name, set_type->
val, conf_str);
707 if (strcmp(set_type->
val,
"md5") == 0) {
709 memcap > 0 ? memcap : default_memcap,
715 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
718 }
else if (strcmp(set_type->
val,
"sha256") == 0) {
720 memcap > 0 ? memcap : default_memcap,
726 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
729 }
else if (strcmp(set_type->
val,
"string") == 0) {
731 memcap > 0 ? memcap : default_memcap,
737 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
740 }
else if (strcmp(set_type->
val,
"ipv4") == 0) {
742 memcap > 0 ? memcap : default_memcap,
748 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
751 }
else if (strcmp(set_type->
val,
"ip") == 0) {
753 memcap > 0 ? memcap : default_memcap,
759 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
784 SCLogDebug(
"destroying datasets done: %p", sets);
787 static int SaveCallback(
void *
ctx,
const uint8_t *data,
const uint32_t data_len)
792 return (
int)fwrite(data, data_len, 1, fp);
797 static int Md5AsAscii(
const void *s,
char *out,
size_t out_size)
804 return (
int)strlen(out);
807 static int Sha256AsAscii(
const void *s,
char *out,
size_t out_size)
814 return (
int)strlen(out);
817 static int IPv4AsAscii(
const void *s,
char *out,
size_t out_size)
824 return (
int)strlen(out);
827 static int IPv6AsAscii(
const void *s,
char *out,
size_t out_size)
832 for (
int i = 4; i <= 15; i++) {
833 if (ip6->
ipv6[i] != 0) {
845 return (
int)strlen(out);
854 if (strlen(set->
save) == 0)
857 FILE *fp = fopen(set->
save,
"w");
889 static int DatasetLookupString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
897 DatasetUnlockData(rdata);
904 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
911 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .rep = *rep };
917 DatasetUnlockData(rdata);
923 static int DatasetLookupIPv4(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
932 memcpy(lookup.
ipv4, data, 4);
935 DatasetUnlockData(rdata);
953 memcpy(lookup.
ipv4, data, data_len);
959 DatasetUnlockData(rdata);
965 static int DatasetLookupIPv6(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
970 if (data_len != 16 && data_len != 4)
974 memcpy(lookup.
ipv6, data, data_len);
977 DatasetUnlockData(rdata);
991 if (data_len != 16 && data_len != 4)
995 memcpy(lookup.
ipv6, data, data_len);
1001 DatasetUnlockData(rdata);
1007 static int DatasetLookupMd5(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1016 memcpy(lookup.
md5, data, data_len);
1019 DatasetUnlockData(rdata);
1026 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
1037 memcpy(lookup.
md5, data, data_len);
1043 DatasetUnlockData(rdata);
1049 static int DatasetLookupSha256(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1058 memcpy(lookup.
sha256, data, data_len);
1061 DatasetUnlockData(rdata);
1068 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
1079 memcpy(lookup.
sha256, data, data_len);
1085 DatasetUnlockData(rdata);
1105 switch (set->
type) {
1107 return DatasetLookupString(set, data, data_len);
1109 return DatasetLookupMd5(set, data, data_len);
1111 return DatasetLookupSha256(set, data, data_len);
1113 return DatasetLookupIPv4(set, data, data_len);
1115 return DatasetLookupIPv6(set, data, data_len);
1127 switch (set->
type) {
1129 return DatasetLookupStringwRep(set, data, data_len, rep);
1131 return DatasetLookupMd5wRep(set, data, data_len, rep);
1133 return DatasetLookupSha256wRep(set, data, data_len, rep);
1135 return DatasetLookupIPv4wRep(set, data, data_len, rep);
1137 return DatasetLookupIPv6wRep(set, data, data_len, rep);
1147 static int DatasetAddString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1152 StringType lookup = { .ptr = (uint8_t *)data, .
len = data_len, .rep = 0 };
1155 DatasetUnlockData(res.
data);
1156 return res.
is_new ? 1 : 0;
1166 static int DatasetAddStringwRep(
1176 DatasetUnlockData(res.
data);
1177 return res.
is_new ? 1 : 0;
1182 static int DatasetAddIPv4(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1196 DatasetUnlockData(res.
data);
1197 return res.
is_new ? 1 : 0;
1202 static int DatasetAddIPv6(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1208 if (data_len != 16 && data_len != 4) {
1213 memcpy(lookup.
ipv6,
data, data_len);
1216 DatasetUnlockData(res.
data);
1217 return res.
is_new ? 1 : 0;
1222 static int DatasetAddIPv4wRep(
1235 DatasetUnlockData(res.
data);
1236 return res.
is_new ? 1 : 0;
1241 static int DatasetAddIPv6wRep(
1254 DatasetUnlockData(res.
data);
1255 return res.
is_new ? 1 : 0;
1260 static int DatasetAddMd5(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1272 DatasetUnlockData(res.
data);
1273 return res.
is_new ? 1 : 0;
1278 static int DatasetAddMd5wRep(
1291 DatasetUnlockData(res.
data);
1292 return res.
is_new ? 1 : 0;
1297 static int DatasetAddSha256wRep(
1310 DatasetUnlockData(res.
data);
1311 return res.
is_new ? 1 : 0;
1316 static int DatasetAddSha256(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1328 DatasetUnlockData(res.
data);
1329 return res.
is_new ? 1 : 0;
1339 switch (set->
type) {
1341 return DatasetAddString(set,
data, data_len);
1343 return DatasetAddMd5(set,
data, data_len);
1345 return DatasetAddSha256(set,
data, data_len);
1347 return DatasetAddIPv4(set,
data, data_len);
1349 return DatasetAddIPv6(set,
data, data_len);
1360 switch (set->
type) {
1362 return DatasetAddStringwRep(set,
data, data_len, rep);
1364 return DatasetAddMd5wRep(set,
data, data_len, rep);
1366 return DatasetAddSha256wRep(set,
data, data_len, rep);
1368 return DatasetAddIPv4wRep(set,
data, data_len, rep);
1370 return DatasetAddIPv6wRep(set,
data, data_len, rep);
1377 static int DatasetOpSerialized(
Dataset *set,
const char *
string,
DatasetOpFunc DatasetOpString,
1383 if (strlen(
string) == 0)
1386 switch (set->
type) {
1388 if (strlen(
string) > UINT16_MAX) {
1392 uint32_t decoded_size = SCBase64DecodeBufferSize((uint32_t)strlen(
string));
1393 uint8_t decoded[decoded_size];
1394 uint32_t num_decoded = SCBase64Decode(
1395 (
const uint8_t *)
string, strlen(
string), SCBase64ModeStrict, decoded);
1396 if (num_decoded == 0) {
1400 return DatasetOpString(set, decoded, num_decoded);
1403 if (strlen(
string) != 32)
1406 if (
HexToRaw((
const uint8_t *)
string, 32, hash,
sizeof(hash)) < 0)
1408 return DatasetOpMd5(set, hash, 16);
1411 if (strlen(
string) != 64)
1414 if (
HexToRaw((
const uint8_t *)
string, 64, hash,
sizeof(hash)) < 0)
1416 return DatasetOpSha256(set, hash, 32);
1420 if (inet_pton(AF_INET,
string, &in) != 1)
1422 return DatasetOpIPv4(set, (uint8_t *)&in.s_addr, 4);
1425 struct in6_addr in6;
1427 SCLogError(
"Dataset failed to import %s as IPv6",
string);
1430 return DatasetOpIPv6(set, (uint8_t *)&in6.s6_addr, 16);
1444 return DatasetOpSerialized(set,
string, DatasetAddString, DatasetAddMd5, DatasetAddSha256,
1445 DatasetAddIPv4, DatasetAddIPv6);
1456 return DatasetOpSerialized(set,
string, DatasetLookupString, DatasetLookupMd5,
1457 DatasetLookupSha256, DatasetLookupIPv4, DatasetLookupIPv6);
1465 static int DatasetRemoveString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1470 StringType lookup = { .ptr = (uint8_t *)data, .
len = data_len, .rep = 0 };
1474 static int DatasetRemoveIPv4(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1483 memcpy(lookup.
ipv4, data, 4);
1487 static int DatasetRemoveIPv6(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1496 memcpy(lookup.
ipv6, data, 16);
1500 static int DatasetRemoveMd5(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1509 memcpy(lookup.
md5, data, 16);
1513 static int DatasetRemoveSha256(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1522 memcpy(lookup.
sha256, data, 32);
1533 return DatasetOpSerialized(set,
string, DatasetRemoveString, DatasetRemoveMd5,
1534 DatasetRemoveSha256, DatasetRemoveIPv4, DatasetRemoveIPv6);
1542 switch (set->
type) {
1544 return DatasetRemoveString(set, data, data_len);
1546 return DatasetRemoveMd5(set, data, data_len);
1548 return DatasetRemoveSha256(set, data, data_len);
1550 return DatasetRemoveIPv4(set, data, data_len);
1552 return DatasetRemoveIPv6(set, data, data_len);