Skip to content

Commit

Permalink
detect/profile: convert rule grouping dump to json builder
Browse files Browse the repository at this point in the history
  • Loading branch information
victorjulien committed Feb 15, 2025
1 parent 668be7a commit fa40d83
Showing 1 changed file with 106 additions and 106 deletions.
212 changes: 106 additions & 106 deletions src/detect-engine-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ static bool RuleMpmIsNegated(const Signature *s)
return (cd->flags & DETECT_CONTENT_NEGATED) ? true : false;
}

static json_t *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigGroupHead *sgh,
static JsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigGroupHead *sgh,
const int add_rules, const int add_mpm_stats)
{
uint32_t prefilter_cnt = 0;
Expand Down Expand Up @@ -636,14 +636,13 @@ static json_t *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigG
if (sgh->init == NULL)
return NULL;

json_t *js = json_object();
JsonBuilder *js = jb_new_object();
if (unlikely(js == NULL))
return NULL;

json_object_set_new(js, "id", json_integer(sgh->id));

json_t *js_array = json_array();
jb_set_uint(js, "id", sgh->id);

jb_open_array(js, "rules");
for (uint32_t x = 0; x < sgh->init->sig_cnt; x++) {
const Signature *s = sgh->init->match_array[x];
if (s == NULL)
Expand Down Expand Up @@ -766,35 +765,37 @@ static json_t *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigG
alstats[s->alproto]++;

if (add_rules) {
json_t *js_sig = json_object();
if (unlikely(js == NULL))
continue;
json_object_set_new(js_sig, "sig_id", json_integer(s->id));
json_array_append_new(js_array, js_sig);
JsonBuilder *e = jb_new_object();
if (e != NULL) {
jb_set_uint(e, "sig_id", s->id);
jb_close(e);
jb_append_object(js, e);
jb_free(e);
}
}
}
jb_close(js);

json_object_set_new(js, "rules", js_array);
jb_open_object(js, "stats");
jb_set_uint(js, "total", sgh->init->sig_cnt);

json_t *stats = json_object();
json_object_set_new(stats, "total", json_integer(sgh->init->sig_cnt));

json_t *types = json_object();
json_object_set_new(types, "mpm", json_integer(mpm_cnt));
json_object_set_new(types, "non_mpm", json_integer(nonmpm_cnt));
json_object_set_new(types, "mpm_depth", json_integer(mpm_depth_cnt));
json_object_set_new(types, "mpm_endswith", json_integer(mpm_endswith_cnt));
json_object_set_new(types, "negated_mpm", json_integer(negmpm_cnt));
json_object_set_new(types, "payload_but_no_mpm", json_integer(payload_no_mpm_cnt));
json_object_set_new(types, "prefilter", json_integer(prefilter_cnt));
json_object_set_new(types, "syn", json_integer(syn_cnt));
json_object_set_new(types, "any5", json_integer(any5_cnt));
json_object_set_new(stats, "types", types);
jb_open_object(js, "types");
jb_set_uint(js, "mpm", mpm_cnt);
jb_set_uint(js, "non_mpm", nonmpm_cnt);
jb_set_uint(js, "mpm_depth", mpm_depth_cnt);
jb_set_uint(js, "mpm_endswith", mpm_endswith_cnt);
jb_set_uint(js, "negated_mpm", negmpm_cnt);
jb_set_uint(js, "payload_but_no_mpm", payload_no_mpm_cnt);
jb_set_uint(js, "prefilter", prefilter_cnt);
jb_set_uint(js, "syn", syn_cnt);
jb_set_uint(js, "any5", any5_cnt);
jb_close(js);

for (AppProto i = 0; i < g_alproto_max; i++) {
if (alstats[i] > 0) {
json_t *app = json_object();
json_object_set_new(app, "total", json_integer(alstats[i]));
const char *proto_name = (i == ALPROTO_UNKNOWN) ? "payload" : AppProtoToString(i);
jb_open_object(js, proto_name);
jb_set_uint(js, "total", alstats[i]);

for (int y = 0; y < max_buffer_type_id; y++) {
if (alproto_mpm_bufs[i][y] == 0)
Expand All @@ -806,127 +807,138 @@ static json_t *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigG
else
name = DetectEngineBufferTypeGetNameById(de_ctx, y);

json_object_set_new(app, name, json_integer(alproto_mpm_bufs[i][y]));
jb_set_uint(js, name, alproto_mpm_bufs[i][y]);
}

const char *proto_name = (i == ALPROTO_UNKNOWN) ? "payload" : AppProtoToString(i);
json_object_set_new(stats, proto_name, app);
jb_close(js);
}
}

if (add_mpm_stats) {
json_t *mpm_js = json_object();
jb_open_object(js, "mpm");

for (int i = 0; i < max_buffer_type_id; i++) {
if (mpm_stats[i].cnt > 0) {
const char *name;
if (i < DETECT_SM_LIST_DYNAMIC_START)
name = DetectListToHumanString(i);
else
name = DetectEngineBufferTypeGetNameById(de_ctx, i);

jb_open_array(js, name);

json_t *mpm_sizes_array = json_array();
for (int y = 0; y < 256; y++) {
if (mpm_sizes[i][y] == 0)
continue;

json_t *e = json_object();
json_object_set_new(e, "size", json_integer(y));
json_object_set_new(e, "count", json_integer(mpm_sizes[i][y]));
json_array_append_new(mpm_sizes_array, e);
JsonBuilder *e = jb_new_object();
if (e != NULL) {
jb_set_uint(e, "size", y);
jb_set_uint(e, "count", mpm_sizes[i][y]);
jb_close(e);
jb_append_object(js, e);
jb_free(e);
}
}

json_t *buf = json_object();
json_object_set_new(buf, "total", json_integer(mpm_stats[i].cnt));
json_object_set_new(buf, "avg_strength", json_integer(mpm_stats[i].total / mpm_stats[i].cnt));
json_object_set_new(buf, "min_strength", json_integer(mpm_stats[i].min));
json_object_set_new(buf, "max_strength", json_integer(mpm_stats[i].max));

json_object_set_new(buf, "sizes", mpm_sizes_array);

const char *name;
if (i < DETECT_SM_LIST_DYNAMIC_START)
name = DetectListToHumanString(i);
else
name = DetectEngineBufferTypeGetNameById(de_ctx, i);
JsonBuilder *e = jb_new_object();
if (e != NULL) {
jb_set_uint(e, "total", mpm_stats[i].cnt);
jb_set_uint(e, "avg_strength", mpm_stats[i].total / mpm_stats[i].cnt);
jb_set_uint(e, "min_strength", mpm_stats[i].min);
jb_set_uint(e, "max_strength", mpm_stats[i].max);
jb_close(e);
jb_append_object(js, e);
jb_free(e);
}

json_object_set_new(mpm_js, name, buf);
jb_close(js);
}
}

json_object_set_new(stats, "mpm", mpm_js);
jb_close(js);
}
json_object_set_new(js, "stats", stats);
jb_close(js);

json_object_set_new(js, "score", json_integer(sgh->init->score));
jb_set_uint(js, "score", sgh->init->score);
jb_close(js);

return js;
}

static void RulesDumpGrouping(const DetectEngineCtx *de_ctx,
const int add_rules, const int add_mpm_stats)
{
json_t *js = json_object();
JsonBuilder *js = jb_new_object();
if (unlikely(js == NULL))
return;

int p;
for (p = 0; p < 256; p++) {
for (int p = 0; p < 256; p++) {
if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
const char *name = (p == IPPROTO_TCP) ? "tcp" : "udp";

json_t *tcp = json_object();

json_t *ts_array = json_array();
DetectPort *list = (p == IPPROTO_TCP) ? de_ctx->flow_gh[1].tcp :
de_ctx->flow_gh[1].udp;
jb_open_object(js, name);
jb_open_array(js, "toserver");
const DetectPort *list =
(p == IPPROTO_TCP) ? de_ctx->flow_gh[1].tcp : de_ctx->flow_gh[1].udp;
while (list != NULL) {
json_t *port = json_object();
json_object_set_new(port, "port", json_integer(list->port));
json_object_set_new(port, "port2", json_integer(list->port2));
JsonBuilder *port = jb_new_object();
jb_set_uint(port, "port", list->port);
jb_set_uint(port, "port2", list->port2);

json_t *tcp_ts =
JsonBuilder *stats =
RulesGroupPrintSghStats(de_ctx, list->sh, add_rules, add_mpm_stats);
json_object_set_new(port, "rulegroup", tcp_ts);
json_array_append_new(ts_array, port);
jb_set_object(port, "rulegroup", stats);
jb_free(stats);
jb_close(port);
jb_append_object(js, port);
jb_free(port);

list = list->next;
}
json_object_set_new(tcp, "toserver", ts_array);
jb_close(js); // toserver array

json_t *tc_array = json_array();
jb_open_array(js, "toclient");
list = (p == IPPROTO_TCP) ? de_ctx->flow_gh[0].tcp :
de_ctx->flow_gh[0].udp;
while (list != NULL) {
json_t *port = json_object();
json_object_set_new(port, "port", json_integer(list->port));
json_object_set_new(port, "port2", json_integer(list->port2));
JsonBuilder *port = jb_new_object();
jb_set_uint(port, "port", list->port);
jb_set_uint(port, "port2", list->port2);

json_t *tcp_tc =
JsonBuilder *stats =
RulesGroupPrintSghStats(de_ctx, list->sh, add_rules, add_mpm_stats);
json_object_set_new(port, "rulegroup", tcp_tc);
json_array_append_new(tc_array, port);
jb_set_object(port, "rulegroup", stats);
jb_free(stats);
jb_close(port);
jb_append_object(js, port);
jb_free(port);

list = list->next;
}
json_object_set_new(tcp, "toclient", tc_array);

json_object_set_new(js, name, tcp);
jb_close(js); // toclient array
jb_close(js);
} else if (p == IPPROTO_ICMP || p == IPPROTO_ICMPV6) {
const char *name = (p == IPPROTO_ICMP) ? "icmpv4" : "icmpv6";
json_t *o = json_object();
jb_open_object(js, name);
if (de_ctx->flow_gh[1].sgh[p]) {
json_t *ts = json_object();
json_t *group_ts = RulesGroupPrintSghStats(
jb_open_object(js, "toserver");
JsonBuilder *stats = RulesGroupPrintSghStats(
de_ctx, de_ctx->flow_gh[1].sgh[p], add_rules, add_mpm_stats);
json_object_set_new(ts, "rulegroup", group_ts);
json_object_set_new(o, "toserver", ts);
jb_set_object(js, "rulegroup", stats);
jb_free(stats);
jb_close(js);
}
if (de_ctx->flow_gh[0].sgh[p]) {
json_t *tc = json_object();
json_t *group_tc = RulesGroupPrintSghStats(
jb_open_object(js, "toclient");
JsonBuilder *stats = RulesGroupPrintSghStats(
de_ctx, de_ctx->flow_gh[0].sgh[p], add_rules, add_mpm_stats);
json_object_set_new(tc, "rulegroup", group_tc);
json_object_set_new(o, "toclient", tc);
jb_set_object(js, "rulegroup", stats);
jb_free(stats);
jb_close(js);
}
json_object_set_new(js, name, o);
jb_close(js);
}
}
jb_close(js);

const char *filename = "rule_group.json";
const char *log_dir = ConfigGetLogDirectory();
Expand All @@ -935,23 +947,11 @@ static void RulesDumpGrouping(const DetectEngineCtx *de_ctx,
snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, filename);

FILE *fp = fopen(log_path, "w");
if (fp == NULL) {
return;
}

char *js_s = json_dumps(js,
JSON_PRESERVE_ORDER|JSON_ESCAPE_SLASH);
if (unlikely(js_s == NULL)) {
fclose(fp);
return;
if (fp != NULL) {
fwrite(jb_ptr(js), jb_len(js), 1, fp);
}

json_object_clear(js);
json_decref(js);

fprintf(fp, "%s\n", js_s);
free(js_s);
fclose(fp);
(void)fclose(fp);
jb_free(js);
}

static int RulesGroupByIPProto(DetectEngineCtx *de_ctx)
Expand Down

0 comments on commit fa40d83

Please sign in to comment.