45 static uint32_t set_ids = 0;
49 static inline void DatasetUnlockData(
THashData *d)
54 static bool DatasetIsStatic(
const char *save,
const char *load);
55 static void GetDefaultMemcap(uint64_t *memcap, uint32_t *
hashsize);
59 if (strcasecmp(
"md5", s) == 0)
61 if (strcasecmp(
"sha256", s) == 0)
63 if (strcasecmp(
"string", s) == 0)
65 if (strcasecmp(
"ipv4", s) == 0)
67 if (strcasecmp(
"ip", s) == 0)
81 static Dataset *DatasetSearchByName(
const char *
name)
93 static int HexToRaw(
const uint8_t *in,
size_t ins, uint8_t *out,
size_t outs)
103 memset(hash, 0, outs);
105 for (x = 0, i = 0; i < ins; i+=2, x++) {
106 char buf[3] = { 0, 0, 0 };
110 long value = strtol(buf, NULL, 16);
111 if (value >= 0 && value <= 255)
112 hash[x] = (uint8_t)value;
114 SCLogError(
"hash byte out of range %ld", value);
119 memcpy(out, hash, outs);
123 static int DatasetLoadIPv4(
Dataset *set)
125 if (strlen(set->
load) == 0)
129 const char *fopen_mode =
"r";
130 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
134 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSIpv4);
137 }
else if (retval == -1) {
146 static int ParseIpv6String(
Dataset *set,
const char *line,
struct in6_addr *in6)
149 char *got_colon = strchr(line,
':');
152 if (inet_pton(AF_INET6, line, in6) != 1) {
156 memcpy(&ip6addr, in6->s6_addr,
sizeof(ip6addr));
158 if (ip6addr[0] == 0 && ip6addr[1] == 0 && ip6addr[2] == 0xFFFF0000) {
159 ip6addr[0] = ip6addr[3];
162 memcpy(in6, ip6addr,
sizeof(
struct in6_addr));
167 if (inet_pton(AF_INET, line, &in) != 1) {
171 memset(in6, 0,
sizeof(
struct in6_addr));
172 memcpy(in6, &in,
sizeof(
struct in_addr));
177 static int DatasetLoadIPv6(
Dataset *set)
179 if (strlen(set->
load) == 0)
183 const char *fopen_mode =
"r";
184 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
188 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSIpv6);
191 }
else if (retval == -1) {
200 static int DatasetLoadMd5(
Dataset *set)
202 if (strlen(set->
load) == 0)
206 const char *fopen_mode =
"r";
207 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
211 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSMd5);
214 }
else if (retval == -1) {
223 static int DatasetLoadSha256(
Dataset *set)
225 if (strlen(set->
load) == 0)
229 const char *fopen_mode =
"r";
230 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
234 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSSha256);
237 }
else if (retval == -1) {
246 static int DatasetLoadString(
Dataset *set)
248 if (strlen(set->
load) == 0)
253 const char *fopen_mode =
"r";
254 if (strlen(set->
save) > 0 && strcmp(set->
save, set->
load) == 0) {
258 int retval = ParseDatasets(set, set->
name, set->
load, fopen_mode, DSString);
261 }
else if (retval == -1) {
277 static void DatasetGetPath(
const char *in_path,
284 strlcpy(path, in_path,
sizeof(path));
285 strlcpy(out_path, path, out_size);
290 if (stat(data_dir, &st) != 0) {
291 SCLogDebug(
"data-dir '%s': %s", data_dir, strerror(errno));
295 snprintf(path,
sizeof(path),
"%s/%s", data_dir, in_path);
298 if (stat(path, &st) != 0) {
299 SCLogDebug(
"path %s: %s", path, strerror(errno));
301 snprintf(path,
sizeof(path),
"%s", in_path);
305 strlcpy(out_path, path, out_size);
306 SCLogDebug(
"in_path \'%s\' => \'%s\'", in_path, out_path);
327 uint64_t default_memcap = 0;
328 uint32_t default_hashsize = 0;
338 "exists and is of type %u",
344 if ((save == NULL || strlen(save) == 0) &&
345 (load == NULL || strlen(load) == 0)) {
349 if ((save == NULL && strlen(set->
save) > 0) ||
350 (save != NULL && strcmp(set->
save, save) != 0)) {
355 if ((load == NULL && strlen(set->
load) > 0) ||
356 (load != NULL && strcmp(set->
load, load) != 0)) {
372 set = DatasetAlloc(
name);
379 if (save && strlen(save)) {
383 if (load && strlen(load)) {
389 snprintf(cnf_name,
sizeof(cnf_name),
"datasets.%s.hash",
name);
391 GetDefaultMemcap(&default_memcap, &default_hashsize);
396 memcap > 0 ? memcap : default_memcap,
398 if (set->
hash == NULL)
400 if (DatasetLoadMd5(set) < 0)
406 memcap > 0 ? memcap : default_memcap,
408 if (set->
hash == NULL)
410 if (DatasetLoadString(set) < 0)
416 memcap > 0 ? memcap : default_memcap,
418 if (set->
hash == NULL)
420 if (DatasetLoadSha256(set) < 0)
426 NULL, NULL, load != NULL ? 1 : 0, memcap > 0 ? memcap : default_memcap,
428 if (set->
hash == NULL)
430 if (DatasetLoadIPv4(set) < 0)
436 NULL, NULL, load != NULL ? 1 : 0, memcap > 0 ? memcap : default_memcap,
438 if (set->
hash == NULL)
440 if (DatasetLoadIPv6(set) < 0)
446 SCLogError(
"dataset too large for set memcap");
450 SCLogDebug(
"set %p/%s type %u save %s load %s",
469 static bool DatasetIsStatic(
const char *save,
const char *load)
474 if ((load != NULL && strlen(load) > 0) &&
475 (save == NULL || strlen(save) == 0)) {
505 SCLogDebug(
"Post Reload Cleanup starting.. Hidden sets will be removed");
529 static void GetDefaultMemcap(uint64_t *memcap, uint32_t *
hashsize)
531 const char *
str = NULL;
532 if (
ConfGet(
"datasets.defaults.memcap", &
str) == 1) {
535 " resetting to default",
540 if (
ConfGet(
"datasets.defaults.hashsize", &
str) == 1) {
543 " resetting to default",
554 uint64_t default_memcap = 0;
555 uint32_t default_hashsize = 0;
556 GetDefaultMemcap(&default_memcap, &default_hashsize);
557 if (datasets != NULL) {
561 if (iter->
name == NULL) {
566 char save[PATH_MAX] =
"";
567 char load[PATH_MAX] =
"";
571 const char *set_name = iter->
name;
580 if (set_type == NULL) {
588 DatasetGetPath(set_save->
val, save,
sizeof(save),
TYPE_STATE);
589 strlcpy(load, save,
sizeof(load));
594 DatasetGetPath(set_load->
val, load,
sizeof(load),
TYPE_LOAD);
602 " deduced: %s, resetting to default",
611 " deduced: %s, resetting to default",
617 snprintf(conf_str,
sizeof(conf_str),
"datasets.%d.%s", list_pos, set_name);
619 SCLogDebug(
"set %s type %s. Conf %s", set_name, set_type->
val, conf_str);
621 if (strcmp(set_type->
val,
"md5") == 0) {
623 memcap > 0 ? memcap : default_memcap,
629 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
632 }
else if (strcmp(set_type->
val,
"sha256") == 0) {
634 memcap > 0 ? memcap : default_memcap,
640 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
643 }
else if (strcmp(set_type->
val,
"string") == 0) {
645 memcap > 0 ? memcap : default_memcap,
651 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
654 }
else if (strcmp(set_type->
val,
"ipv4") == 0) {
656 memcap > 0 ? memcap : default_memcap,
662 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
665 }
else if (strcmp(set_type->
val,
"ip") == 0) {
667 memcap > 0 ? memcap : default_memcap,
673 SCLogDebug(
"dataset %s: id %u type %s", set_name, dset->
id, set_type->
val);
698 SCLogDebug(
"destroying datasets done: %p", sets);
701 static int SaveCallback(
void *
ctx,
const uint8_t *data,
const uint32_t data_len)
706 return (
int)fwrite(data, data_len, 1, fp);
711 static int Md5AsAscii(
const void *s,
char *out,
size_t out_size)
718 return (
int)strlen(out);
721 static int Sha256AsAscii(
const void *s,
char *out,
size_t out_size)
728 return (
int)strlen(out);
731 static int IPv4AsAscii(
const void *s,
char *out,
size_t out_size)
738 return (
int)strlen(out);
741 static int IPv6AsAscii(
const void *s,
char *out,
size_t out_size)
746 for (
int i = 4; i <= 15; i++) {
747 if (ip6->
ipv6[i] != 0) {
759 return (
int)strlen(out);
768 if (strlen(set->
save) == 0)
771 FILE *fp = fopen(set->
save,
"w");
803 static int DatasetLookupString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
808 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .rep.value = 0 };
811 DatasetUnlockData(rdata);
818 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
825 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .rep = *rep };
831 DatasetUnlockData(rdata);
837 static int DatasetLookupIPv4(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
846 memcpy(lookup.
ipv4, data, 4);
849 DatasetUnlockData(rdata);
856 Dataset *set,
const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
867 memcpy(lookup.
ipv4, data, data_len);
873 DatasetUnlockData(rdata);
879 static int DatasetLookupIPv6(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
884 if (data_len != 16 && data_len != 4)
888 memcpy(lookup.
ipv6, data, data_len);
891 DatasetUnlockData(rdata);
898 Dataset *set,
const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
905 if (data_len != 16 && data_len != 4)
909 memcpy(lookup.
ipv6, data, data_len);
915 DatasetUnlockData(rdata);
921 static int DatasetLookupMd5(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
930 memcpy(lookup.
md5, data, data_len);
933 DatasetUnlockData(rdata);
940 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
951 memcpy(lookup.
md5, data, data_len);
957 DatasetUnlockData(rdata);
963 static int DatasetLookupSha256(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
972 memcpy(lookup.
sha256, data, data_len);
975 DatasetUnlockData(rdata);
982 const uint8_t *data,
const uint32_t data_len,
const DataRepType *rep)
993 memcpy(lookup.
sha256, data, data_len);
999 DatasetUnlockData(rdata);
1019 switch (set->
type) {
1021 return DatasetLookupString(set, data, data_len);
1023 return DatasetLookupMd5(set, data, data_len);
1025 return DatasetLookupSha256(set, data, data_len);
1027 return DatasetLookupIPv4(set, data, data_len);
1029 return DatasetLookupIPv6(set, data, data_len);
1035 const DataRepType *rep)
1041 switch (set->
type) {
1043 return DatasetLookupStringwRep(set, data, data_len, rep);
1045 return DatasetLookupMd5wRep(set, data, data_len, rep);
1047 return DatasetLookupSha256wRep(set, data, data_len, rep);
1049 return DatasetLookupIPv4wRep(set, data, data_len, rep);
1051 return DatasetLookupIPv6wRep(set, data, data_len, rep);
1061 static int DatasetAddString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1066 StringType lookup = { .ptr = (uint8_t *)data, .
len = data_len,
1070 DatasetUnlockData(res.
data);
1071 return res.
is_new ? 1 : 0;
1081 static int DatasetAddStringwRep(
1082 Dataset *set,
const uint8_t *
data,
const uint32_t data_len,
const DataRepType *rep)
1091 DatasetUnlockData(res.
data);
1092 return res.
is_new ? 1 : 0;
1097 static int DatasetAddIPv4(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1111 DatasetUnlockData(res.
data);
1112 return res.
is_new ? 1 : 0;
1117 static int DatasetAddIPv6(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1123 if (data_len != 16) {
1131 DatasetUnlockData(res.
data);
1132 return res.
is_new ? 1 : 0;
1137 static int DatasetAddIPv4wRep(
1138 Dataset *set,
const uint8_t *
data,
const uint32_t data_len,
const DataRepType *rep)
1150 DatasetUnlockData(res.
data);
1151 return res.
is_new ? 1 : 0;
1156 static int DatasetAddIPv6wRep(
1157 Dataset *set,
const uint8_t *
data,
const uint32_t data_len,
const DataRepType *rep)
1169 DatasetUnlockData(res.
data);
1170 return res.
is_new ? 1 : 0;
1175 static int DatasetAddMd5(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1187 DatasetUnlockData(res.
data);
1188 return res.
is_new ? 1 : 0;
1193 static int DatasetAddMd5wRep(
1194 Dataset *set,
const uint8_t *
data,
const uint32_t data_len,
const DataRepType *rep)
1206 DatasetUnlockData(res.
data);
1207 return res.
is_new ? 1 : 0;
1212 static int DatasetAddSha256wRep(
1213 Dataset *set,
const uint8_t *
data,
const uint32_t data_len,
const DataRepType *rep)
1225 DatasetUnlockData(res.
data);
1226 return res.
is_new ? 1 : 0;
1231 static int DatasetAddSha256(
Dataset *set,
const uint8_t *
data,
const uint32_t data_len)
1243 DatasetUnlockData(res.
data);
1244 return res.
is_new ? 1 : 0;
1254 switch (set->
type) {
1256 return DatasetAddString(set,
data, data_len);
1258 return DatasetAddMd5(set,
data, data_len);
1260 return DatasetAddSha256(set,
data, data_len);
1262 return DatasetAddIPv4(set,
data, data_len);
1264 return DatasetAddIPv6(set,
data, data_len);
1274 switch (set->
type) {
1276 return DatasetAddStringwRep(set,
data, data_len, rep);
1278 return DatasetAddMd5wRep(set,
data, data_len, rep);
1280 return DatasetAddSha256wRep(set,
data, data_len, rep);
1282 return DatasetAddIPv4wRep(set,
data, data_len, rep);
1284 return DatasetAddIPv6wRep(set,
data, data_len, rep);
1291 static int DatasetOpSerialized(
Dataset *set,
const char *
string,
DatasetOpFunc DatasetOpString,
1297 if (strlen(
string) == 0)
1300 switch (set->
type) {
1302 uint32_t decoded_size = SCBase64DecodeBufferSize(strlen(
string));
1303 uint8_t decoded[decoded_size];
1304 uint32_t num_decoded = SCBase64Decode(
1305 (
const uint8_t *)
string, strlen(
string), SCBase64ModeStrict, decoded);
1306 if (num_decoded == 0) {
1310 return DatasetOpString(set, decoded, num_decoded);
1313 if (strlen(
string) != 32)
1316 if (HexToRaw((
const uint8_t *)
string, 32, hash,
sizeof(hash)) < 0)
1318 return DatasetOpMd5(set, hash, 16);
1321 if (strlen(
string) != 64)
1324 if (HexToRaw((
const uint8_t *)
string, 64, hash,
sizeof(hash)) < 0)
1326 return DatasetOpSha256(set, hash, 32);
1330 if (inet_pton(AF_INET,
string, &in) != 1)
1332 return DatasetOpIPv4(set, (uint8_t *)&in.s_addr, 4);
1335 struct in6_addr in6;
1336 if (ParseIpv6String(set,
string, &in6) != 0) {
1337 SCLogError(
"Dataset failed to import %s as IPv6",
string);
1340 return DatasetOpIPv6(set, (uint8_t *)&in6.s6_addr, 16);
1354 return DatasetOpSerialized(set,
string, DatasetAddString, DatasetAddMd5, DatasetAddSha256,
1355 DatasetAddIPv4, DatasetAddIPv6);
1366 return DatasetOpSerialized(set,
string, DatasetLookupString, DatasetLookupMd5,
1367 DatasetLookupSha256, DatasetLookupIPv4, DatasetLookupIPv6);
1375 static int DatasetRemoveString(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1380 StringType lookup = { .ptr = (uint8_t *)data, .
len = data_len,
1385 static int DatasetRemoveIPv4(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1394 memcpy(lookup.
ipv4, data, 4);
1398 static int DatasetRemoveIPv6(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1407 memcpy(lookup.
ipv6, data, 16);
1411 static int DatasetRemoveMd5(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1420 memcpy(lookup.
md5, data, 16);
1424 static int DatasetRemoveSha256(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
1433 memcpy(lookup.
sha256, data, 32);
1444 return DatasetOpSerialized(set,
string, DatasetRemoveString, DatasetRemoveMd5,
1445 DatasetRemoveSha256, DatasetRemoveIPv4, DatasetRemoveIPv6);
1453 switch (set->
type) {
1455 return DatasetRemoveString(set, data, data_len);
1457 return DatasetRemoveMd5(set, data, data_len);
1459 return DatasetRemoveSha256(set, data, data_len);
1461 return DatasetRemoveIPv4(set, data, data_len);
1463 return DatasetRemoveIPv6(set, data, data_len);