91 #define DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT 3000
98 static uint32_t TenantIdHash(
HashTable *h,
void *data, uint16_t data_len);
99 static char TenantIdCompare(
void *d1, uint16_t d1_len,
void *d2, uint16_t d2_len);
100 static void TenantIdFree(
void *d);
101 static uint32_t DetectEngineTentantGetIdFromLivedev(
const void *ctx,
const Packet *p);
102 static uint32_t DetectEngineTentantGetIdFromVlanId(
const void *ctx,
const Packet *p);
103 static uint32_t DetectEngineTentantGetIdFromPcap(
const void *ctx,
const Packet *p);
143 FatalError(
"failed to register inspect engine %s", name);
155 FatalError(
"failed to register inspect engine %s: %s", name, strerror(errno));
157 new_engine->
sm_list = (uint16_t)sm_list;
162 if (g_pkt_inspect_engines == NULL) {
163 g_pkt_inspect_engines = new_engine;
166 while (t->
next != NULL) {
170 t->
next = new_engine;
183 FatalError(
"failed to register inspect engine %s", name);
200 FatalError(
"failed to register inspect engine %s: %s", name, strerror(errno));
202 new_engine->
sm_list = (uint16_t)sm_list;
204 new_engine->
dir = direction;
209 if (g_frame_inspect_engines == NULL) {
210 g_frame_inspect_engines = new_engine;
213 while (t->
next != NULL) {
217 t->
next = new_engine;
225 AppProto alproto, uint32_t dir,
int progress,
234 FatalError(
"failed to register inspect engine %s", name);
240 (progress < 0 || progress >= SHRT_MAX) ||
246 SCLogError(
"Invalid arguments: must register "
247 "GetData with DetectEngineInspectBufferGeneric");
262 memset(new_engine, 0,
sizeof(*new_engine));
264 new_engine->
dir = direction;
265 new_engine->
sm_list = (uint16_t)sm_list;
267 new_engine->
progress = (int16_t)progress;
271 if (g_app_inspect_engines == NULL) {
272 g_app_inspect_engines = new_engine;
275 while (t->
next != NULL) {
279 t->
next = new_engine;
284 static void DetectAppLayerInspectEngineCopy(
286 int sm_list,
int new_list,
299 new_engine->
sm_list = (uint16_t)new_list;
303 new_engine->
v2 = t->
v2;
310 while (list->
next != NULL) {
314 list->
next = new_engine;
336 new_engine->
v2 = t->
v2;
341 list->
next = new_engine;
350 static void DetectPktInspectEngineCopy(
352 int sm_list,
int new_list,
363 new_engine->
sm_list = (uint16_t)new_list;
366 new_engine->
v1 = t->
v1;
373 while (list->
next != NULL) {
377 list->
next = new_engine;
396 new_engine->
v1 = t->
v1;
402 while (list->
next != NULL) {
406 list->
next = new_engine;
421 FatalError(
"failed to register inspect engine %s", name);
438 FatalError(
"failed to register inspect engine %s: %s", name, strerror(errno));
440 new_engine->
sm_list = (uint16_t)sm_list;
442 new_engine->
dir = direction;
451 while (list->
next != NULL) {
455 list->
next = new_engine;
474 new_engine->
sm_list = (uint16_t)new_list;
480 new_engine->
v1 = t->
v1;
485 while (list->
next != NULL) {
489 list->
next = new_engine;
511 new_engine->
v1 = t->
v1;
517 while (list->
next != NULL) {
521 list->
next = new_engine;
533 static void AppendStreamInspectEngine(
536 bool prepend =
false;
545 new_engine->
mpm =
true;
548 new_engine->
dir = direction;
549 new_engine->
stream =
true;
552 new_engine->
smd = stream;
560 }
else if (prepend) {
567 while (a->
next != NULL) {
571 a->
next = new_engine;
574 SCLogDebug(
"sid %u: engine %p/%u added", s->
id, new_engine, new_engine->
id);
607 bool prepend =
false;
629 new_engine->
mpm =
true;
636 new_engine->
v1 = u->
v1;
642 }
else if (prepend) {
647 while (a->
next != NULL) {
651 a->
next = new_engine;
663 bool prepend =
false;
672 new_engine->
mpm =
true;
678 new_engine->
v1 = e->
v1;
679 SCLogDebug(
"sm_list %d new_engine->v1 %p/%p/%p",
685 }
else if (prepend) {
690 while (a->
next != NULL) {
694 a->
next = new_engine;
700 bool head_is_mpm =
false;
704 bool prepend =
false;
734 new_engine->
mpm =
true;
743 new_engine->
v2 = t->
v2;
744 SCLogDebug(
"sm_list %d new_engine->v2 %p/%p/%p",
750 if (new_engine->
sm_list == files_id) {
751 SCLogDebug(
"sid %u: engine %p/%u is FILE ENGINE", s->
id, new_engine, new_engine->
id);
761 if (new_engine->
sm_list == files_id) {
762 SCLogDebug(
"sid %u: engine %p/%u is FILE ENGINE", s->
id, new_engine, new_engine->
id);
765 new_engine->
id = ++last_id;
770 while (a->
next != NULL) {
779 a->
next = new_engine;
780 if (new_engine->
sm_list == files_id) {
781 SCLogDebug(
"sid %u: engine %p/%u is FILE ENGINE", s->
id, new_engine, new_engine->
id);
784 new_engine->
id = ++last_id;
788 SCLogDebug(
"sid %u: engine %p/%u added", s->
id, new_engine, new_engine->
id);
802 AppendStreamInspectEngine(s, stream, 0, last_id + 1);
804 AppendStreamInspectEngine(s, stream, 1, last_id + 1);
806 AppendStreamInspectEngine(s, stream, 0, last_id + 1);
807 AppendStreamInspectEngine(s, stream, 1, last_id + 1);
821 iter->
sm_list == mpm_list ?
"MPM" :
"");
890 for (
int i = 0; i < nlists; i++)
914 static int g_buffer_type_reg_closed = 0;
918 return g_buffer_type_id;
921 static uint32_t DetectBufferTypeHashNameFunc(
HashListTable *ht,
void *data, uint16_t datalen)
930 static uint32_t DetectBufferTypeHashIdFunc(
HashListTable *ht,
void *data, uint16_t datalen)
933 uint32_t hash = map->
id;
938 static char DetectBufferTypeCompareNameFunc(
void *data1, uint16_t len1,
void *data2, uint16_t len2)
943 char r = (strcmp(map1->
name, map2->
name) == 0);
948 static char DetectBufferTypeCompareIdFunc(
void *data1, uint16_t len1,
void *data2, uint16_t len2)
952 return map1->
id == map2->
id;
955 static void DetectBufferTypeFreeFunc(
void *data)
968 SCLogError(
"%s allocates transform option memory but has no free routine",
978 static int DetectBufferTypeInit(
void)
980 BUG_ON(g_buffer_type_hash);
982 DetectBufferTypeCompareNameFunc, DetectBufferTypeFreeFunc);
983 if (g_buffer_type_hash == NULL)
989 static void DetectBufferTypeFree(
void)
991 if (g_buffer_type_hash == NULL)
995 g_buffer_type_hash = NULL;
999 static int DetectBufferTypeAdd(
const char *
string)
1001 BUG_ON(
string == NULL || strlen(
string) >= 32);
1008 map->
id = g_buffer_type_id++;
1018 memset(&map, 0,
sizeof(map));
1027 BUG_ON(g_buffer_type_reg_closed);
1028 if (g_buffer_type_hash == NULL)
1029 DetectBufferTypeInit();
1033 return DetectBufferTypeAdd(name);
1041 BUG_ON(g_buffer_type_reg_closed);
1045 exists->
frame =
true;
1046 SCLogDebug(
"%p %s -- %d supports frame inspection", exists, name, exists->
id);
1051 BUG_ON(g_buffer_type_reg_closed);
1056 SCLogDebug(
"%p %s -- %d supports packet inspection", exists, name, exists->
id);
1061 BUG_ON(g_buffer_type_reg_closed);
1066 SCLogDebug(
"%p %s -- %d supports mpm", exists, name, exists->
id);
1071 BUG_ON(g_buffer_type_reg_closed);
1076 SCLogDebug(
"%p %s -- %d supports transformations", exists, name, exists->
id);
1092 memset(&map, 0,
sizeof(map));
1102 memset(&lookup, 0,
sizeof(lookup));
1112 return res ? res->
name : NULL;
1117 BUG_ON(
string == NULL || strlen(
string) >= 32);
1133 const int direction,
const AppProto alproto,
const uint8_t frame_type)
1140 const int buffer_id = DetectEngineBufferTypeAdd(
de_ctx, name);
1141 if (buffer_id < 0) {
1170 return DetectEngineBufferTypeAdd(
de_ctx, name);
1178 BUG_ON(desc == NULL || strlen(desc) >= 128);
1209 exists->
frame =
true;
1210 SCLogDebug(
"%p %s -- %d supports frame inspection", exists, name, exists->
id);
1218 SCLogDebug(
"%p %s -- %d supports packet inspection", exists, name, exists->
id);
1226 SCLogDebug(
"%p %s -- %d supports mpm", exists, name, exists->
id);
1234 SCLogDebug(
"%p %s -- %d supports transformations", exists, name, exists->
id);
1258 BUG_ON(g_buffer_type_reg_closed);
1274 bool (*ValidateCallback)(
const Signature *,
const char **sigerror))
1276 BUG_ON(g_buffer_type_reg_closed);
1313 SCLogError(
"previous transforms not consumed "
1314 "(list: %u, transform_cnt %u)",
1319 SCLogDebug(
"buffer %d has transform(s) registered: %d",
1323 if (new_list == -1) {
1353 for (uint32_t x = 0; x <= mbuffer->
max; x++) {
1373 if (!buffer->
init) {
1394 if (local_id >= fb->
size) {
1395 uint32_t old_size = fb->
size;
1396 uint32_t new_size = local_id + 1;
1397 uint32_t grow_by = new_size - old_size;
1398 SCLogDebug(
"size is %u, need %u, so growing by %u", old_size, new_size, grow_by);
1406 SCLogDebug(
"ptr %p to_zero %p", ptr, to_zero);
1409 fb->
size = new_size;
1415 #ifdef DEBUG_VALIDATION
1416 buffer->multi =
true;
1423 memset(buffer, 0,
sizeof(*buffer));
1424 buffer->
buf =
SCCalloc(initial_size,
sizeof(uint8_t));
1425 if (buffer->
buf != NULL) {
1426 buffer->
size = initial_size;
1432 const uint8_t *data,
const uint32_t data_len)
1434 #ifdef DEBUG_VALIDATION
1449 #ifdef DEBUG_VALIDATION
1453 if (buffer->
inspect == NULL) {
1455 if (det_ctx && list_id != -1)
1467 if (buffer->
buf != NULL) {
1470 memset(buffer, 0,
sizeof(*buffer));
1482 uint32_t new_size = (buffer->
size == 0) ? 4096 : buffer->
size;
1483 while (new_size < min_size) {
1490 buffer->
size = new_size;
1499 uint32_t copy_size =
MIN(buf_len, buffer->
size);
1500 memcpy(buffer->
buf, buf, copy_size);
1526 const uint8_t *content, uint16_t content_len,
const char **namestr)
1567 const int size = g_buffer_type_id;
1571 DetectBufferTypeCompareNameFunc, DetectBufferTypeFreeFunc);
1574 HashListTableInit(256, DetectBufferTypeHashIdFunc, DetectBufferTypeCompareIdFunc,
1586 memcpy(copy, map,
sizeof(*copy));
1592 SCLogDebug(
"name %s id %d mpm %s packet %s -- %s. "
1593 "Callbacks: Setup %p Validate %p",
1594 map->
name, map->
id, map->
mpm ?
"true" :
"false", map->
packet ?
"true" :
"false",
1601 DetectAppLayerInspectEngineCopyListToDetectCtx(
de_ctx);
1603 DetectFrameInspectEngineCopyListToDetectCtx(
de_ctx);
1605 DetectPktInspectEngineCopyListToDetectCtx(
de_ctx);
1647 while (framemlist) {
1658 BUG_ON(g_buffer_type_hash == NULL);
1660 g_buffer_type_reg_closed = 1;
1671 SCLogError(
"buffer '%s' does not support transformations", base_map->
name);
1678 memset(&t, 0,
sizeof(t));
1679 for (
int i = 0; i < transform_cnt; i++) {
1682 t.
cnt = transform_cnt;
1685 memset(&lookup_map, 0,
sizeof(lookup_map));
1703 map->
mpm = base_map->
mpm;
1710 }
else if (map->
packet) {
1720 SCLogDebug(
"buffer %s registered with id %d, parent %d", map->name, map->id, map->parent_id);
1724 DetectFrameInspectEngineCopy(
de_ctx, map->parent_id, map->id, &map->transforms);
1725 }
else if (map->packet) {
1726 DetectPktInspectEngineCopy(
de_ctx, map->parent_id, map->id, &map->transforms);
1728 DetectAppLayerInspectEngineCopy(
de_ctx, map->parent_id, map->id, &map->transforms);
1734 static int DetectEngineInspectRulePacketMatches(
1738 Packet *p, uint8_t *_alert_flags)
1746 SCLogDebug(
"running match functions, sm %p", smd);
1764 static int DetectEngineInspectRulePayloadMatches(
1787 SCLogDebug(
"no match in stream, fall back to packet payload");
1809 uint8_t *alert_flags)
1814 if (e->v1.Callback(det_ctx, e, s, p, alert_flags) ==
false) {
1815 SCLogDebug(
"sid %u: e %p Callback returned false", s->
id, e);
1818 SCLogDebug(
"sid %u: e %p Callback returned true", s->
id, e);
1837 e->
sm_list = (uint16_t)list_id;
1846 while (a->
next != NULL) {
1858 if (DetectEnginePktInspectionAppend(
1861 SCLogDebug(
"sid %u: DetectEngineInspectRulePayloadMatches appended", s->
id);
1865 if (DetectEnginePktInspectionAppend(
1868 SCLogDebug(
"sid %u: DetectEngineInspectRulePacketMatches appended", s->
id);
1950 uint8_t
flags,
void *alstate,
void *txv, uint64_t tx_id)
1953 SCLogDebug(
"running match functions, sm %p", smd);
1959 AppLayerTxMatch(det_ctx, f,
flags, alstate, txv, s, smd->
ctx);
1993 void *alstate,
void *txv, uint64_t tx_id)
1995 const int list_id = engine->
sm_list;
1996 SCLogDebug(
"running inspect on %d", list_id);
2010 f,
flags, txv, list_id);
2017 const uint8_t *data = buffer->
inspect;
2022 ci_flags |= buffer->
flags;
2033 (uint8_t *)data, data_len,
offset, ci_flags,
2059 const int list_id = engine->
sm_list;
2060 SCLogDebug(
"running inspect on %d", list_id);
2078 const uint8_t *data = buffer->
inspect;
2079 const uint64_t
offset = 0;
2082 ci_flags |= buffer->
flags;
2093 (uint8_t *)data, data_len,
offset, ci_flags,
2104 static void BreakCapture(
void)
2140 static void InjectPackets(
ThreadVars **detect_tvs,
2142 int no_of_detect_tvs)
2146 for (
int i = 0; i < no_of_detect_tvs; i++) {
2147 if (
SC_ATOMIC_GET(new_det_ctx[i]->so_far_used_by_detect) != 1) {
2148 if (detect_tvs[i]->inq != NULL) {
2185 if (no_of_detect_tvs == 0) {
2195 memset(detect_tvs, 0x00, (no_of_detect_tvs *
sizeof(
ThreadVars *)));
2220 if (new_det_ctx[i] == NULL) {
2222 "failure in live rule swap. Let's get out of here");
2226 SCLogDebug(
"live rule swap created new det_ctx - %p and de_ctx "
2227 "- %p\n", new_det_ctx[i], new_de_ctx);
2232 BUG_ON(i != no_of_detect_tvs);
2245 SCLogDebug(
"swapping new det_ctx - %p with older one - %p",
2256 SCLogDebug(
"Live rule swap has swapped %d old det_ctx's with new ones, "
2257 "along with the new de_ctx", no_of_detect_tvs);
2259 InjectPackets(detect_tvs, new_det_ctx, no_of_detect_tvs);
2261 for (i = 0; i < no_of_detect_tvs; i++) {
2264 while (
SC_ATOMIC_GET(new_det_ctx[i]->so_far_used_by_detect) != 1) {
2275 SCLogDebug(
"new_det_ctx - %p used by detect engine", new_det_ctx[i]);
2283 if (i != no_of_detect_tvs) {
2296 for (i = 0; i < no_of_detect_tvs; i++) {
2297 SCLogDebug(
"Freeing old_det_ctx - %p used by detect",
2307 for (i = 0; i < no_of_detect_tvs; i++) {
2308 if (new_det_ctx[i] != NULL)
2332 if (prefix != NULL) {
2337 SCLogDebug(
"ConfGetBool could not load the value.");
2348 SCLogDebug(
"Unable to alloc SpmGlobalThreadCtx.");
2352 if (DetectEngineCtxLoadConf(
de_ctx) == -1) {
2362 DetectBufferTypeSetupDetectEngine(
de_ctx);
2410 if (prefix == NULL || strlen(prefix) == 0)
2485 DetectEngineCtxFreeThreadKeywordData(
de_ctx);
2487 DetectEngineCtxFreeFailedSigs(
de_ctx);
2507 DetectBufferTypeFreeDetectEngine(
de_ctx);
2525 const char *max_uniq_toclient_groups_str = NULL;
2526 const char *max_uniq_toserver_groups_str = NULL;
2527 const char *sgh_mpm_context = NULL;
2528 const char *de_ctx_profile = NULL;
2530 (void)
ConfGet(
"detect.profile", &de_ctx_profile);
2531 (void)
ConfGet(
"detect.sgh-mpm-context", &sgh_mpm_context);
2536 if (de_ctx_custom != NULL) {
2538 if (de_ctx_profile == NULL) {
2539 if (opt->
val && strcmp(opt->
val,
"profile") == 0) {
2540 de_ctx_profile = opt->head.tqh_first->
val;
2544 if (sgh_mpm_context == NULL) {
2545 if (opt->
val && strcmp(opt->
val,
"sgh-mpm-context") == 0) {
2546 sgh_mpm_context = opt->head.tqh_first->
val;
2552 if (de_ctx_profile != NULL) {
2553 if (strcmp(de_ctx_profile,
"low") == 0 ||
2554 strcmp(de_ctx_profile,
"lowest") == 0) {
2556 }
else if (strcmp(de_ctx_profile,
"medium") == 0) {
2558 }
else if (strcmp(de_ctx_profile,
"high") == 0 ||
2559 strcmp(de_ctx_profile,
"highest") == 0) {
2561 }
else if (strcmp(de_ctx_profile,
"custom") == 0) {
2564 SCLogError(
"invalid value for detect.profile: '%s'. "
2565 "Valid options: low, medium, high and custom.",
2570 SCLogDebug(
"Profile for detection engine groups is \"%s\"", de_ctx_profile);
2572 SCLogDebug(
"Profile for detection engine groups not provided "
2573 "at suricata.yaml. Using default (\"medium\").");
2577 if (sgh_mpm_context == NULL || strcmp(sgh_mpm_context,
"auto") == 0) {
2581 #ifdef BUILD_HYPERSCAN
2590 if (strcmp(sgh_mpm_context,
"single") == 0) {
2592 }
else if (strcmp(sgh_mpm_context,
"full") == 0) {
2596 "invalid conf value for detect-engine.sgh-mpm-context-"
2621 (void)
ConfGet(
"detect.custom-values.toclient-groups",
2622 &max_uniq_toclient_groups_str);
2623 (void)
ConfGet(
"detect.custom-values.toserver-groups",
2624 &max_uniq_toserver_groups_str);
2626 if (de_ctx_custom != NULL) {
2628 if (opt->
val && strcmp(opt->
val,
"custom-values") == 0) {
2629 if (max_uniq_toclient_groups_str == NULL) {
2631 (opt->head.tqh_first,
"toclient-sp-groups");
2633 if (max_uniq_toclient_groups_str == NULL) {
2635 (opt->head.tqh_first,
"toclient-groups");
2637 if (max_uniq_toserver_groups_str == NULL) {
2639 (opt->head.tqh_first,
"toserver-dp-groups");
2641 if (max_uniq_toserver_groups_str == NULL) {
2643 (opt->head.tqh_first,
"toserver-groups");
2648 if (max_uniq_toclient_groups_str != NULL) {
2650 (uint16_t)strlen(max_uniq_toclient_groups_str),
2651 (
const char *)max_uniq_toclient_groups_str) <= 0) {
2655 "toclient-groups failed, using %u",
2663 if (max_uniq_toserver_groups_str != NULL) {
2665 (uint16_t)strlen(max_uniq_toserver_groups_str),
2666 (
const char *)max_uniq_toserver_groups_str) <= 0) {
2670 "toserver-groups failed, using %u",
2689 if (
ConfGetInt(
"detect.inspection-recursion-limit", &value) == 1)
2691 if (value >= 0 && value <= INT_MAX) {
2697 ConfNode *insp_recursion_limit_node = NULL;
2698 char *insp_recursion_limit = NULL;
2700 if (de_ctx_custom != NULL) {
2703 if (opt->
val && strcmp(opt->
val,
"inspection-recursion-limit") != 0)
2707 if (insp_recursion_limit_node == NULL) {
2709 "entry for detect-engine:inspection-recursion-limit");
2712 insp_recursion_limit = insp_recursion_limit_node->
val;
2713 SCLogDebug(
"Found detect-engine.inspection-recursion-limit - %s:%s",
2714 insp_recursion_limit_node->
name, insp_recursion_limit_node->
val);
2718 if (insp_recursion_limit != NULL) {
2720 0, (
const char *)insp_recursion_limit) < 0) {
2722 "detect-engine.inspection-recursion-limit: %s "
2738 SCLogDebug(
"de_ctx->inspection_recursion_limit: %d",
2743 const char *ports = NULL;
2744 (void)
ConfGet(
"detect.grouping.tcp-whitelist", &ports);
2748 ports =
"53, 80, 139, 443, 445, 1433, 3306, 3389, 6666, 6667, 8080";
2749 SCLogConfig(
"grouping: tcp-whitelist (default) %s", ports);
2754 "for detect.grouping.tcp-whitelist",
2758 for ( ; x != NULL; x = x->
next) {
2761 "for detect.grouping.tcp-whitelist: only single ports allowed",
2770 (void)
ConfGet(
"detect.grouping.udp-whitelist", &ports);
2774 ports =
"53, 135, 5060";
2775 SCLogConfig(
"grouping: udp-whitelist (default) %s", ports);
2780 "for detect.grouping.udp-whitelist",
2786 "for detect.grouping.udp-whitelist: only single ports allowed",
2795 const char *pf_setting = NULL;
2796 if (
ConfGet(
"detect.prefilter.default", &pf_setting) == 1 && pf_setting) {
2797 if (strcasecmp(pf_setting,
"mpm") == 0) {
2799 }
else if (strcasecmp(pf_setting,
"auto") == 0) {
2808 SCLogConfig(
"prefilter engines: MPM and keywords");
2837 SCLogError(
"setting up thread local detect ctx");
2846 SCLogError(
"setting up thread local detect ctx "
2847 "for keyword \"%s\" failed",
2885 SCLogError(
"setting up thread local detect ctx");
2899 SCLogError(
"setting up thread local detect ctx "
2900 "for keyword \"%s\" failed",
2930 uint32_t map_array_size = 0;
2931 uint32_t map_cnt = 0;
2932 int max_tenant_id = 0;
2938 "set using multi-detect.selector");
2951 mt_det_ctxs_hash =
HashTableInit(tcnt * 2, TenantIdHash, TenantIdCompare, TenantIdFree);
2952 if (mt_det_ctxs_hash == NULL) {
2957 SCLogInfo(
"no tenants left, or none registered yet");
2968 map_array_size = map_cnt + 1;
2970 map_array =
SCCalloc(map_array_size,
sizeof(*map_array));
2971 if (map_array == NULL)
2978 if (map_cnt >= map_array_size) {
2990 list = master->
list;
2995 if (mt_det_ctx == NULL)
2997 if (
HashTableAdd(mt_det_ctxs_hash, mt_det_ctx, 0) != 0) {
3006 mt_det_ctxs_hash = NULL;
3018 det_ctx->
TenantGetId = DetectEngineTentantGetIdFromVlanId;
3022 det_ctx->
TenantGetId = DetectEngineTentantGetIdFromLivedev;
3026 det_ctx->
TenantGetId = DetectEngineTentantGetIdFromPcap;
3033 if (map_array != NULL)
3035 if (mt_det_ctxs_hash != NULL)
3123 DetectEngineThreadCtxInitKeywords(
de_ctx, det_ctx);
3124 DetectEngineThreadCtxInitGlobalKeywords(det_ctx);
3162 if (det_ctx->
de_ctx == NULL) {
3197 if (DetectEngineThreadCtxInitForMT(
tv, det_ctx) !=
TM_ECODE_OK) {
3204 *data = (
void *)det_ctx;
3229 if (det_ctx->
de_ctx == NULL) {
3261 if (DetectEngineThreadCtxInitForMT(
tv, det_ctx) !=
TM_ECODE_OK) {
3274 SCLogDebug(
"PACKET PKT_STREAM_ADD: %"PRIu64, det_ctx->pkt_stream_add_cnt);
3276 SCLogDebug(
"PAYLOAD MPM %"PRIu64
"/%"PRIu64, det_ctx->payload_mpm_cnt, det_ctx->payload_mpm_size);
3277 SCLogDebug(
"STREAM MPM %"PRIu64
"/%"PRIu64, det_ctx->stream_mpm_cnt, det_ctx->stream_mpm_size);
3279 SCLogDebug(
"PAYLOAD SIG %"PRIu64
"/%"PRIu64, det_ctx->payload_persig_cnt, det_ctx->payload_persig_size);
3280 SCLogDebug(
"STREAM SIG %"PRIu64
"/%"PRIu64, det_ctx->stream_persig_cnt, det_ctx->stream_persig_size);
3298 if (det_ctx->
de_ctx != NULL) {
3340 for (uint32_t x = 0; x < fb->
size; x++) {
3351 DetectEngineThreadCtxDeinitGlobalKeywords(det_ctx);
3352 if (det_ctx->
de_ctx != NULL) {
3353 DetectEngineThreadCtxDeinitKeywords(det_ctx->
de_ctx, det_ctx);
3371 if (det_ctx == NULL) {
3380 DetectEngineThreadCtxFree(det_ctx);
3392 static uint32_t DetectKeywordCtxHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3395 const char *name = ctx->
name;
3396 uint64_t hash =
StringHashDjb2((
const uint8_t *)name, strlen(name)) + (uint64_t)ctx->
data;
3401 static char DetectKeywordCtxCompareFunc(
void *data1, uint16_t len1,
void *data2, uint16_t len2)
3405 const char *name1 = ctx1->
name;
3406 const char *name2 = ctx2->
name;
3407 return (strcmp(name1, name2) == 0 && ctx1->
data == ctx2->
data);
3410 static void DetectKeywordCtxFreeFunc(
void *ptr)
3433 BUG_ON(
de_ctx == NULL || InitFunc == NULL || FreeFunc == NULL);
3437 DetectKeywordCtxHashFunc, DetectKeywordCtxCompareFunc, DetectKeywordCtxFreeFunc);
3522 void *(*InitFunc)(
void *),
void *data,
void (*FreeFunc)(
void *))
3525 BUG_ON(InitFunc == NULL || FreeFunc == NULL);
3531 while (item != NULL) {
3532 if (strcmp(name, item->
name) == 0) {
3582 if (master->
list == NULL) {
3658 static int DetectEngineMultiTenantLoadTenant(uint32_t tenant_id,
const char *filename,
int loader_id)
3663 snprintf(prefix,
sizeof(prefix),
"multi-detect.%u", tenant_id);
3667 if(_stat(filename, &st) != 0) {
3670 if(stat(filename, &st) != 0) {
3672 SCLogError(
"failed to stat file %s", filename);
3678 SCLogError(
"tenant %u already registered", tenant_id);
3685 SCLogError(
"failed to properly setup yaml %s", filename);
3717 static int DetectEngineMultiTenantReloadTenant(uint32_t tenant_id,
const char *filename,
int reload_cnt)
3720 if (old_de_ctx == NULL) {
3721 SCLogError(
"tenant detect engine not found");
3726 snprintf(prefix,
sizeof(prefix),
"multi-detect.%u.reload.%d", tenant_id, reload_cnt);
3737 SCLogError(
"failed to properly setup yaml %s", filename);
3742 if (new_de_ctx == NULL) {
3777 static int DetectLoaderFuncLoadTenant(
void *vctx,
int loader_id)
3782 if (DetectEngineMultiTenantLoadTenant(ctx->
tenant_id, ctx->
yaml, loader_id) != 0) {
3788 static int DetectLoaderSetupLoadTenant(uint32_t tenant_id,
const char *yaml)
3800 static int DetectLoaderFuncReloadTenant(
void *vctx,
int loader_id)
3812 static int DetectLoaderSetupReloadTenant(uint32_t tenant_id,
const char *yaml,
int reload_cnt)
3815 if (old_de_ctx == NULL)
3837 int r = DetectLoaderSetupLoadTenant(tenant_id, yaml);
3851 int r = DetectLoaderSetupReloadTenant(tenant_id, yaml, reload_cnt);
3861 static int DetectEngineMultiTenantSetupLoadLivedevMappings(
const ConfNode *mappings_root_node,
3866 int mapping_cnt = 0;
3867 if (mappings_root_node != NULL) {
3870 if (tenant_id_node == NULL)
3873 if (device_node == NULL)
3876 uint32_t tenant_id = 0;
3878 tenant_id_node->
val) < 0) {
3881 tenant_id_node->
val);
3885 const char *dev = device_node->
val;
3904 SCLogConfig(
"device %s connected to tenant-id %u", dev, tenant_id);
3913 SCLogConfig(
"%d device - tenant-id mappings defined", mapping_cnt);
3920 static int DetectEngineMultiTenantSetupLoadVlanMappings(
const ConfNode *mappings_root_node,
3925 int mapping_cnt = 0;
3926 if (mappings_root_node != NULL) {
3929 if (tenant_id_node == NULL)
3932 if (vlan_id_node == NULL)
3935 uint32_t tenant_id = 0;
3937 tenant_id_node->
val) < 0) {
3940 tenant_id_node->
val);
3944 uint16_t vlan_id = 0;
3946 &vlan_id, 10, (uint16_t)strlen(vlan_id_node->
val), vlan_id_node->
val) < 0) {
3952 if (vlan_id == 0 || vlan_id >= 4095) {
3954 "of %s is invalid. Valid range 1-4094.",
3962 SCLogConfig(
"vlan %u connected to tenant-id %u", vlan_id, tenant_id);
3988 int failure_fatal = 0;
3989 (void)
ConfGetBool(
"engine.init-failure-fatal", &failure_fatal);
3992 (void)
ConfGetBool(
"multi-detect.enabled", &enabled);
4002 const char *handler = NULL;
4003 if (
ConfGet(
"multi-detect.selector", &handler) == 1) {
4004 SCLogConfig(
"multi-tenant selector type %s", handler);
4006 if (strcmp(handler,
"vlan") == 0) {
4010 if ((
ConfGetBool(
"vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) {
4012 "can't use multi-detect selector 'vlan'");
4017 }
else if (strcmp(handler,
"direct") == 0) {
4019 }
else if (strcmp(handler,
"device") == 0) {
4022 SCLogWarning(
"multi-tenant 'device' mode not supported for IPS");
4029 "multi-detect.selector",
4036 SCLogConfig(
"multi-detect is enabled (multi tenancy). Selector: %s", handler);
4042 int mapping_cnt = DetectEngineMultiTenantSetupLoadVlanMappings(mappings_root_node,
4044 if (mapping_cnt == 0) {
4050 SCLogNotice(
"no tenant traffic mappings defined, "
4051 "tenants won't be used until mappings are added");
4053 if (failure_fatal) {
4054 SCLogError(
"no multi-detect mappings defined");
4062 int mapping_cnt = DetectEngineMultiTenantSetupLoadLivedevMappings(mappings_root_node,
4064 if (mapping_cnt == 0) {
4065 if (failure_fatal) {
4066 SCLogError(
"no multi-detect mappings defined");
4078 if (tenants_root_node != NULL) {
4081 if (id_node == NULL) {
4085 if (yaml_node == NULL) {
4089 uint32_t tenant_id = 0;
4091 &tenant_id, 10, (uint16_t)strlen(id_node->
val), id_node->
val) < 0) {
4102 snprintf(prefix,
sizeof(prefix),
"multi-detect.%u", tenant_id);
4108 int r = DetectLoaderSetupLoadTenant(tenant_id, yaml_node->
val);
4129 SCLogDebug(
"multi-detect not enabled (multi tenancy)");
4136 static uint32_t DetectEngineTentantGetIdFromVlanId(
const void *ctx,
const Packet *p)
4140 uint32_t vlan_id = 0;
4160 static uint32_t DetectEngineTentantGetIdFromLivedev(
const void *ctx,
const Packet *p)
4165 if (ld == NULL || det_ctx == NULL)
4173 uint32_t tenant_id, uint32_t traffic_id)
4179 SCLogInfo(
"conflicting selector already set");
4186 if (
m->traffic_id == traffic_id) {
4187 SCLogInfo(
"traffic id already registered");
4208 SCLogDebug(
"tenant handler %u %u %u registered", selector, tenant_id, traffic_id);
4214 uint32_t tenant_id, uint32_t traffic_id)
4237 SCLogInfo(
"tenant handler %u %u %u unregistered", selector, tenant_id, traffic_id);
4256 return DetectEngineTentantRegisterSelector(
TENANT_SELECTOR_VLAN, tenant_id, (uint32_t)vlan_id);
4261 return DetectEngineTentantUnregisterSelector(
TENANT_SELECTOR_VLAN, tenant_id, (uint32_t)vlan_id);
4276 static uint32_t DetectEngineTentantGetIdFromPcap(
const void *ctx,
const Packet *p)
4286 if (master->
list == NULL) {
4309 BUG_ON((*de_ctx)->ref_cnt == 0);
4310 (*de_ctx)->ref_cnt--;
4318 if (instance == NULL)
4321 if (master->
list == NULL) {
4322 master->
list = instance;
4325 master->
list = instance;
4342 r = DetectEngineAddToList(
de_ctx);
4353 if (instance == NULL) {
4359 if (instance ==
de_ctx) {
4363 instance = instance->
next;
4368 if (instance ==
de_ctx) {
4376 if (instance == NULL) {
4383 instance->
next = NULL;
4417 SCLogDebug(
"freeing detect engine %p", instance);
4428 static int reloads = 0;
4443 memset(prefix, 0,
sizeof(prefix));
4448 snprintf(prefix,
sizeof(prefix),
"detect-engine-reloads.%d", reloads++);
4475 if (old_de_ctx == NULL)
4477 SCLogDebug(
"get ref to old_de_ctx %p", old_de_ctx);
4491 if (new_de_ctx == NULL) {
4503 SCLogDebug(
"set up new_de_ctx %p", new_de_ctx);
4512 SCLogDebug(
"going to reload the threads to use new_de_ctx %p", new_de_ctx);
4514 DetectEngineReloadThreads(new_de_ctx);
4515 SCLogDebug(
"threads now run new_de_ctx %p", new_de_ctx);
4524 SCLogDebug(
"old_de_ctx should have been freed");
4530 static uint32_t TenantIdHash(
HashTable *h,
void *data, uint16_t data_len)
4536 static char TenantIdCompare(
void *d1, uint16_t d1_len,
void *d2, uint16_t d2_len)
4543 static void TenantIdFree(
void *d)
4545 DetectEngineThreadCtxFree(d);
4561 for ( ; list != NULL; list = list->
next) {
4572 if (stub_de_ctx == NULL) {
4574 if (stub_de_ctx == NULL) {
4579 if (master->
list == NULL) {
4580 master->
list = stub_de_ctx;
4583 master->
list = stub_de_ctx;
4589 DetectEngineReloadThreads(stub_de_ctx);
4597 SCLogDebug(
"old_de_ctx should have been freed");
4601 static int g_parse_metadata = 0;
4605 g_parse_metadata = 1;
4610 g_parse_metadata = 0;
4615 return g_parse_metadata;
4624 return "packet/stream payload";
4630 return "base64_data";
4633 return "post-match";
4641 return "max (internal)";
4662 if (*event_id == -1) {
4664 "det_ctx's enum map table.",
4678 static int DetectEngineInitYamlConf(
const char *conf)
4685 static void DetectEngineDeInitYamlConf(
void)
4693 static int DetectEngineTest01(
void)
4699 " - profile: medium\n"
4700 " - custom-values:\n"
4701 " toclient_src_groups: 2\n"
4702 " toclient_dst_groups: 2\n"
4703 " toclient_sp_groups: 2\n"
4704 " toclient_dp_groups: 3\n"
4705 " toserver_src_groups: 2\n"
4706 " toserver_dst_groups: 4\n"
4707 " toserver_sp_groups: 2\n"
4708 " toserver_dp_groups: 25\n"
4709 " - inspection-recursion-limit: 0\n";
4711 FAIL_IF(DetectEngineInitYamlConf(conf) == -1);
4720 DetectEngineDeInitYamlConf();
4725 static int DetectEngineTest02(
void)
4731 " - profile: medium\n"
4732 " - custom-values:\n"
4733 " toclient_src_groups: 2\n"
4734 " toclient_dst_groups: 2\n"
4735 " toclient_sp_groups: 2\n"
4736 " toclient_dp_groups: 3\n"
4737 " toserver_src_groups: 2\n"
4738 " toserver_dst_groups: 4\n"
4739 " toserver_sp_groups: 2\n"
4740 " toserver_dp_groups: 25\n"
4741 " - inspection-recursion-limit:\n";
4743 FAIL_IF(DetectEngineInitYamlConf(conf) == -1);
4753 DetectEngineDeInitYamlConf();
4758 static int DetectEngineTest03(
void)
4764 " - profile: medium\n"
4765 " - custom-values:\n"
4766 " toclient_src_groups: 2\n"
4767 " toclient_dst_groups: 2\n"
4768 " toclient_sp_groups: 2\n"
4769 " toclient_dp_groups: 3\n"
4770 " toserver_src_groups: 2\n"
4771 " toserver_dst_groups: 4\n"
4772 " toserver_sp_groups: 2\n"
4773 " toserver_dp_groups: 25\n";
4775 FAIL_IF(DetectEngineInitYamlConf(conf) == -1);
4785 DetectEngineDeInitYamlConf();
4790 static int DetectEngineTest04(
void)
4796 " - profile: medium\n"
4797 " - custom-values:\n"
4798 " toclient_src_groups: 2\n"
4799 " toclient_dst_groups: 2\n"
4800 " toclient_sp_groups: 2\n"
4801 " toclient_dp_groups: 3\n"
4802 " toserver_src_groups: 2\n"
4803 " toserver_dst_groups: 4\n"
4804 " toserver_sp_groups: 2\n"
4805 " toserver_dp_groups: 25\n"
4806 " - inspection-recursion-limit: 10\n";
4808 FAIL_IF(DetectEngineInitYamlConf(conf) == -1);
4817 DetectEngineDeInitYamlConf();
4822 static int DetectEngineTest08(
void)
4828 " - profile: custom\n"
4829 " - custom-values:\n"
4830 " toclient-groups: 23\n"
4831 " toserver-groups: 27\n";
4833 FAIL_IF(DetectEngineInitYamlConf(conf) == -1);
4843 DetectEngineDeInitYamlConf();
4849 static int DetectEngineTest09(
void)
4855 " - profile: custom\n"
4856 " - custom-values:\n"
4857 " toclient-groups: BA\n"
4858 " toserver-groups: BA\n"
4859 " - inspection-recursion-limit: 10\n";
4861 FAIL_IF(DetectEngineInitYamlConf(conf) == -1);
4871 DetectEngineDeInitYamlConf();