45 static int rule_warnings_only = 0;
46 static FILE *rule_engine_analysis_FD = NULL;
47 static FILE *fp_engine_analysis_FD = NULL;
48 static pcre2_code *percent_re = NULL;
49 static pcre2_match_data *percent_re_match = NULL;
50 static char log_path[PATH_MAX];
77 { 0,
false,
false,
true,
"http_uri",
"http uri" },
78 { 0,
false,
false,
false,
"http_raw_uri",
"http raw uri" },
79 { 0,
false,
true,
false,
"http_method",
"http method" },
80 { 0,
false,
false,
false,
"http_request_line",
"http request line" },
81 { 0,
false,
false,
false,
"http_client_body",
"http client body" },
82 { 0,
false,
false,
true,
"http_header",
"http header" },
83 { 0,
false,
false,
false,
"http_raw_header",
"http raw header" },
84 { 0,
false,
false,
true,
"http_cookie",
"http cookie" },
85 { 0,
false,
false,
false,
"http_user_agent",
"http user agent" },
86 { 0,
false,
false,
false,
"http_host",
"http host" },
87 { 0,
false,
false,
false,
"http_raw_host",
"http raw host" },
88 { 0,
false,
false,
false,
"http_accept_enc",
"http accept enc" },
89 { 0,
false,
false,
false,
"http_referer",
"http referer" },
90 { 0,
false,
false,
false,
"http_content_type",
"http content type" },
91 { 0,
false,
false,
false,
"http_header_names",
"http header names" },
94 { 0,
false,
false,
false,
"http_stat_msg",
"http stat msg" },
95 { 0,
false,
false,
false,
"http_stat_code",
"http stat code" },
96 { 0,
false,
true,
false,
"file_data",
"http server body"},
99 { 0,
false,
false,
false,
"http_request_line",
"http request line" },
100 { 0,
false,
false,
false,
"http_accept",
"http accept" },
101 { 0,
false,
false,
false,
"http_accept_lang",
"http accept lang" },
102 { 0,
false,
false,
false,
"http_connection",
"http connection" },
103 { 0,
false,
false,
false,
"http_content_len",
"http content len" },
104 { 0,
false,
false,
false,
"http_protocol",
"http protocol" },
105 { 0,
false,
false,
false,
"http_start",
"http start" },
108 { 0,
false,
false,
false,
"http_response_line",
"http response line" },
109 { 0,
false,
false,
false,
"http.server",
"http server" },
110 { 0,
false,
false,
false,
"http.location",
"http location" },
130 { .bufname =
"file_data"}
135 static void FpPatternStatsAdd(
int list, uint16_t patlen)
144 else if (patlen < f->min)
156 int fast_pattern_set = 0;
157 int fast_pattern_only_set = 0;
158 int fast_pattern_chop_set = 0;
163 if (mpm_sm != NULL) {
166 fast_pattern_set = 1;
168 fast_pattern_only_set = 1;
170 fast_pattern_chop_set = 1;
175 fprintf(fp_engine_analysis_FD,
"== Sid: %u ==\n", s->
id);
176 fprintf(fp_engine_analysis_FD,
"%s\n", line);
178 fprintf(fp_engine_analysis_FD,
" Fast Pattern analysis:\n");
180 fprintf(fp_engine_analysis_FD,
" Prefilter on: %s\n",
182 fprintf(fp_engine_analysis_FD,
"\n");
187 fprintf(fp_engine_analysis_FD,
" No content present\n");
188 fprintf(fp_engine_analysis_FD,
"\n");
192 fprintf(fp_engine_analysis_FD,
" Fast pattern matcher: ");
193 int list_type = mpm_sm_list;
195 fprintf(fp_engine_analysis_FD,
"content\n");
200 fprintf(fp_engine_analysis_FD,
"%s (%s)\n", desc, name);
205 fprintf(fp_engine_analysis_FD,
" Flags:");
207 fprintf(fp_engine_analysis_FD,
" Offset");
210 fprintf(fp_engine_analysis_FD,
" Depth");
214 fprintf(fp_engine_analysis_FD,
" Within");
218 fprintf(fp_engine_analysis_FD,
" Distance");
222 fprintf(fp_engine_analysis_FD,
" Nocase");
226 fprintf(fp_engine_analysis_FD,
" Negated");
230 fprintf(fp_engine_analysis_FD,
" None");
231 fprintf(fp_engine_analysis_FD,
"\n");
233 fprintf(fp_engine_analysis_FD,
" Fast pattern set: %s\n", fast_pattern_set ?
"yes" :
"no");
234 fprintf(fp_engine_analysis_FD,
" Fast pattern only set: %s\n",
235 fast_pattern_only_set ?
"yes" :
"no");
236 fprintf(fp_engine_analysis_FD,
" Fast pattern chop set: %s\n",
237 fast_pattern_chop_set ?
"yes" :
"no");
238 if (fast_pattern_chop_set) {
239 fprintf(fp_engine_analysis_FD,
" Fast pattern offset, length: %u, %u\n",
250 fprintf(fp_engine_analysis_FD,
" Original content: ");
252 fprintf(fp_engine_analysis_FD,
"\n");
254 if (fast_pattern_chop_set) {
263 fprintf(fp_engine_analysis_FD,
" Final content: ");
265 fprintf(fp_engine_analysis_FD,
"\n");
267 FpPatternStatsAdd(list_type, patlen);
269 fprintf(fp_engine_analysis_FD,
" Final content: ");
271 fprintf(fp_engine_analysis_FD,
"\n");
273 FpPatternStatsAdd(list_type, patlen);
277 fprintf(fp_engine_analysis_FD,
"\n");
289 int fp_engine_analysis_set = 0;
291 if ((
ConfGetBool(
"engine-analysis.rules-fast-pattern",
292 &fp_engine_analysis_set)) == 0) {
296 if (fp_engine_analysis_set == 0)
301 snprintf(log_path,
sizeof(log_path),
"%s/%s", log_dir,
302 "rules_fast_pattern.txt");
304 fp_engine_analysis_FD = fopen(log_path,
"w");
305 if (fp_engine_analysis_FD == NULL) {
306 SCLogError(
"failed to open %s: %s", log_path, strerror(errno));
310 SCLogInfo(
"Engine-Analysis for fast_pattern printed to file - %s",
315 gettimeofday(&tval, NULL);
318 fprintf(fp_engine_analysis_FD,
"----------------------------------------------"
319 "---------------------\n");
320 fprintf(fp_engine_analysis_FD,
"Date: %" PRId32
"/%" PRId32
"/%04d -- "
322 tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour,
323 tms->tm_min, tms->tm_sec);
324 fprintf(fp_engine_analysis_FD,
"----------------------------------------------"
325 "---------------------\n");
327 memset(&fp_pattern_stats, 0,
sizeof(fp_pattern_stats));
344 }
else if (value && strcasecmp(value,
"warnings-only") == 0) {
346 rule_warnings_only = 1;
351 snprintf(log_path,
sizeof(log_path),
"%s/%s", log_dir,
"rules_analysis.txt");
352 rule_engine_analysis_FD = fopen(log_path,
"w");
353 if (rule_engine_analysis_FD == NULL) {
354 SCLogError(
"failed to open %s: %s", log_path, strerror(errno));
358 SCLogInfo(
"Engine-Analysis for rules printed to file - %s",
363 gettimeofday(&tval, NULL);
366 fprintf(rule_engine_analysis_FD,
"----------------------------------------------"
367 "---------------------\n");
368 fprintf(rule_engine_analysis_FD,
"Date: %" PRId32
"/%" PRId32
"/%04d -- "
370 tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour,
371 tms->tm_min, tms->tm_sec);
372 fprintf(rule_engine_analysis_FD,
"----------------------------------------------"
373 "---------------------\n");
377 fprintf(rule_engine_analysis_FD,
"Error compiling regex; can't check for percent encoding in normalized http content.\n");
382 SCLogInfo(
"Conf parameter \"engine-analysis.rules\" not found. "
383 "Defaulting to not printing the rules analysis report.");
386 SCLogInfo(
"Engine-Analysis for rules disabled in conf file.");
394 fprintf(fp_engine_analysis_FD,
"============\n"
395 "Summary:\n============\n");
402 fprintf(fp_engine_analysis_FD,
403 "%s, smallest pattern %u byte(s), longest pattern %u byte(s), number of patterns %u, avg pattern len %.2f byte(s)\n",
407 if (fp_engine_analysis_FD != NULL) {
408 fclose(fp_engine_analysis_FD);
409 fp_engine_analysis_FD = NULL;
418 if (rule_engine_analysis_FD != NULL) {
419 SCLogInfo(
"Engine-Analysis for rules printed to file - %s", log_path);
420 fclose(rule_engine_analysis_FD);
421 rule_engine_analysis_FD = NULL;
423 if (percent_re != NULL) {
424 pcre2_code_free(percent_re);
426 pcre2_match_data_free(percent_re_match);
436 #define DETECT_PERCENT_ENCODING_REGEX "%[0-9|a-f|A-F]{2}"
442 opts, &en, &eo, NULL);
443 if (percent_re == NULL) {
444 PCRE2_UCHAR errbuffer[256];
445 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
451 percent_re_match = pcre2_match_data_create_from_pattern(percent_re, NULL);
462 static int PerCentEncodingMatch(uint8_t *content, uint16_t content_len)
466 ret = pcre2_match(percent_re, (PCRE2_SPTR8)content, content_len, 0, 0, percent_re_match, NULL);
471 SCLogError(
"Error parsing content - %s; error code is %d", content, ret);
483 if (mpm_sm != NULL) {
508 fprintf(rule_engine_analysis_FD,
" Fast Pattern \"");
511 fprintf(rule_engine_analysis_FD,
" Fast Pattern \"");
516 fprintf(rule_engine_analysis_FD,
"\" on \"");
518 const int list_type = mpm_sm_list;
526 fprintf(rule_engine_analysis_FD,
"%s",
527 payload ? (stream ?
"payload and reassembled stream" :
"payload") :
"reassembled stream");
533 fprintf(rule_engine_analysis_FD,
"%s (%s)", desc, name);
534 }
else if (desc || name) {
535 fprintf(rule_engine_analysis_FD,
"%s", desc ? desc : name);
540 fprintf(rule_engine_analysis_FD,
"\" ");
543 fprintf(rule_engine_analysis_FD,
"(with %d transform(s)) ", bt->
transforms.
cnt);
545 fprintf(rule_engine_analysis_FD,
"buffer.\n");
553 fprintf(rule_engine_analysis_FD,
"== Sid: UNKNOWN ==\n");
554 fprintf(rule_engine_analysis_FD,
"%s\n", line);
555 fprintf(rule_engine_analysis_FD,
" FAILURE: invalid rule.\n");
556 fprintf(rule_engine_analysis_FD,
" File: %s.\n", file);
557 fprintf(rule_engine_analysis_FD,
" Line: %d.\n", lineno);
558 fprintf(rule_engine_analysis_FD,
"\n");
574 vsnprintf(
str,
sizeof(
str), fmt, ap);
578 ctx->js_notes = jb_new_array();
580 jb_append_string(ctx->js_notes,
str);
589 vsnprintf(
str,
sizeof(
str), fmt, ap);
592 if (!ctx->js_warnings)
593 ctx->js_warnings = jb_new_array();
594 if (ctx->js_warnings)
595 jb_append_string(ctx->js_warnings,
str);
598 #define CHECK(pat) if (strlen((pat)) <= len && memcmp((pat), buf, MIN(len, strlen((pat)))) == 0) return true;
600 static bool LooksLikeHTTPMethod(
const uint8_t *buf, uint16_t
len)
609 static bool LooksLikeHTTPUA(
const uint8_t *buf, uint16_t
len)
611 CHECK(
"User-Agent: ");
612 CHECK(
"\nUser-Agent: ");
618 char pattern_str[1024] =
"";
621 jb_set_string(js,
"pattern", pattern_str);
630 jb_set_uint(js,
"offset", cd->
offset);
633 jb_set_uint(js,
"depth", cd->
depth);
636 jb_set_uint(js,
"distance", cd->
distance);
639 jb_set_uint(js,
"within", cd->
within);
649 jb_open_array(js,
"matches");
653 jb_set_string(js,
"name", mname);
659 jb_open_object(js,
"content");
662 AnalyzerNote(ctx, (
char *)
"'fast_pattern:only' option is silently ignored and "
663 "is interpreted as regular 'fast_pattern'");
667 (
char *)
"pattern looks like it inspects HTTP, use http.request_line or "
668 "http.method and http.uri instead for improved performance");
672 (
char *)
"pattern looks like it inspects HTTP, use http.user_agent "
673 "or http.header for improved performance");
695 ctx.
js = jb_new_object();
699 jb_set_string(ctx.
js,
"raw", s->
sig_str);
700 jb_set_uint(ctx.
js,
"id", s->
id);
701 jb_set_uint(ctx.
js,
"gid", s->
gid);
702 jb_set_uint(ctx.
js,
"rev", s->
rev);
703 jb_set_string(ctx.
js,
"msg", s->
msg);
706 jb_set_string(ctx.
js,
"app_proto", alproto);
708 jb_open_array(ctx.
js,
"requirements");
710 jb_append_string(ctx.
js,
"payload");
713 jb_append_string(ctx.
js,
"no_payload");
716 jb_append_string(ctx.
js,
"flow");
719 jb_append_string(ctx.
js,
"tcp_flags_init_deinit");
722 jb_append_string(ctx.
js,
"tcp_flags_unusual");
725 jb_append_string(ctx.
js,
"dcerpc");
728 jb_append_string(ctx.
js,
"engine_event");
732 jb_open_array(ctx.
js,
"flags");
734 jb_append_string(ctx.
js,
"src_any");
737 jb_append_string(ctx.
js,
"dst_any");
740 jb_append_string(ctx.
js,
"sp_any");
743 jb_append_string(ctx.
js,
"dp_any");
746 jb_append_string(ctx.
js,
"noalert");
749 jb_append_string(ctx.
js,
"dsize");
752 jb_append_string(ctx.
js,
"applayer");
755 jb_append_string(ctx.
js,
"ip_only");
758 jb_append_string(ctx.
js,
"need_packet");
761 jb_append_string(ctx.
js,
"need_stream");
764 jb_append_string(ctx.
js,
"negated_mpm");
767 jb_append_string(ctx.
js,
"flush");
770 jb_append_string(ctx.
js,
"need_flowvar");
773 jb_append_string(ctx.
js,
"filestore");
776 jb_append_string(ctx.
js,
"toserver");
779 jb_append_string(ctx.
js,
"toclient");
782 jb_append_string(ctx.
js,
"tlsstore");
785 jb_append_string(ctx.
js,
"bypass");
788 jb_append_string(ctx.
js,
"prefilter");
791 jb_append_string(ctx.
js,
"proto_detect_only");
794 jb_append_string(ctx.
js,
"src_is_target");
797 jb_append_string(ctx.
js,
"dst_is_target");
804 jb_open_array(ctx.
js,
"pkt_engines");
806 for ( ; pkt != NULL; pkt = pkt->
next) {
821 jb_start_object(ctx.
js);
822 jb_set_string(ctx.
js,
"name", name);
823 jb_set_bool(ctx.
js,
"is_mpm", pkt->
mpm);
824 DumpMatches(&ctx, ctx.
js, pkt->
smd);
831 jb_open_array(ctx.
js,
"frame_engines");
833 for (; frame != NULL; frame = frame->
next) {
835 jb_start_object(ctx.
js);
836 jb_set_string(ctx.
js,
"name", name);
837 jb_set_bool(ctx.
js,
"is_mpm", frame->
mpm);
838 DumpMatches(&ctx, ctx.
js, frame->
smd);
844 bool has_stream =
false;
845 bool has_client_body_mpm =
false;
846 bool has_file_data_mpm =
false;
848 jb_open_array(ctx.
js,
"engines");
850 for ( ; app != NULL; app = app->
next) {
865 }
else if (app->
mpm && strcmp(name,
"http_client_body") == 0) {
866 has_client_body_mpm =
true;
867 }
else if (app->
mpm && strcmp(name,
"file_data") == 0) {
868 has_file_data_mpm =
true;
871 jb_start_object(ctx.
js);
872 jb_set_string(ctx.
js,
"name", name);
873 const char *direction = app->
dir == 0 ?
"toserver" :
"toclient";
874 jb_set_string(ctx.
js,
"direction", direction);
875 jb_set_bool(ctx.
js,
"is_mpm", app->
mpm);
877 jb_set_uint(ctx.
js,
"progress", app->
progress);
878 DumpMatches(&ctx, ctx.
js, app->
smd);
886 if (has_stream && has_client_body_mpm)
887 AnalyzerNote(&ctx, (
char *)
"mpm in http_client_body combined with stream match leads to stream buffering");
888 if (has_stream && has_file_data_mpm)
889 AnalyzerNote(&ctx, (
char *)
"mpm in file_data combined with stream match leads to stream buffering");
892 jb_open_object(ctx.
js,
"lists");
902 if (pkt_mpm || app_mpm) {
903 jb_open_object(ctx.
js,
"mpm");
911 jb_set_string(ctx.
js,
"buffer", name);
922 DumpContent(ctx.
js, cd);
934 jb_open_object(ctx.
js,
"prefilter");
941 jb_set_string(ctx.
js,
"buffer", name);
943 jb_set_string(ctx.
js,
"name", mname);
961 const char *filename =
"rules.json";
963 char json_path[PATH_MAX] =
"";
964 snprintf(json_path,
sizeof(json_path),
"%s/%s", log_dir, filename);
967 FILE *fp = fopen(json_path,
"a");
969 fwrite(jb_ptr(ctx.
js), jb_len(ctx.
js), 1, fp);
983 JsonBuilder *root_jb = jb_new_object();
987 jb_open_array(root_jb,
"buffers");
995 JsonBuilder *jb = arrays[p->
sm_list];
996 if (arrays[p->
sm_list] == NULL) {
997 jb = arrays[p->
sm_list] = jb_new_object();
1003 jb_set_string(jb,
"name", name);
1004 jb_set_uint(jb,
"list_id", p->
sm_list);
1006 jb_open_array(jb,
"patterns");
1009 jb_start_object(jb);
1010 jb_set_string(jb,
"pattern",
str);
1012 jb_set_uint(jb,
"cnt", p->
cnt);
1013 jb_set_uint(jb,
"mpm", p->
mpm);
1014 jb_open_object(jb,
"flags");
1025 JsonBuilder *jb = arrays[i];
1032 jb_append_object(root_jb, jb);
1038 const char *filename =
"patterns.json";
1040 char json_path[PATH_MAX] =
"";
1041 snprintf(json_path,
sizeof(json_path),
"%s/%s", log_dir, filename);
1044 FILE *fp = fopen(json_path,
"a");
1046 fwrite(jb_ptr(root_jb), jb_len(root_jb), 1, fp);
1057 static void EngineAnalysisItemsReset(
void)
1064 static void EngineAnalysisItemsInit(
void)
1066 static bool analyzer_init =
false;
1068 if (analyzer_init) {
1069 EngineAnalysisItemsReset();
1080 analyzer_item->
item_id = (uint16_t)item_id;
1081 if (analyzer_item->
item_id == -1) {
1083 FatalError(
"unable to initialize engine-analysis table: detect buffer \"%s\" not "
1099 analyzer_init =
true;
1116 uint32_t rule_bidirectional = 0;
1117 uint32_t rule_pcre = 0;
1118 uint32_t rule_pcre_http = 0;
1119 uint32_t rule_content = 0;
1120 uint32_t rule_flow = 0;
1121 uint32_t rule_flags = 0;
1122 uint32_t rule_flow_toserver = 0;
1123 uint32_t rule_flow_toclient = 0;
1124 uint32_t rule_flow_nostream = 0;
1125 uint32_t rule_ipv4_only = 0;
1126 uint32_t rule_ipv6_only = 0;
1127 uint32_t rule_flowbits = 0;
1128 uint32_t rule_flowint = 0;
1129 uint32_t rule_content_http = 0;
1130 uint32_t rule_content_offset_depth = 0;
1131 int32_t list_id = 0;
1132 uint32_t rule_warning = 0;
1133 uint32_t stream_buf = 0;
1134 uint32_t packet_buf = 0;
1135 uint32_t file_store = 0;
1136 uint32_t warn_pcre_no_content = 0;
1137 uint32_t warn_pcre_http_content = 0;
1138 uint32_t warn_pcre_http = 0;
1139 uint32_t warn_content_http_content = 0;
1140 uint32_t warn_content_http = 0;
1141 uint32_t warn_tcp_no_flow = 0;
1142 uint32_t warn_client_ports = 0;
1143 uint32_t warn_direction = 0;
1144 uint32_t warn_method_toclient = 0;
1145 uint32_t warn_method_serverbody = 0;
1146 uint32_t warn_pcre_method = 0;
1147 uint32_t warn_encoding_norm_http_buf = 0;
1148 uint32_t warn_file_store_not_present = 0;
1149 uint32_t warn_offset_depth_pkt_stream = 0;
1150 uint32_t warn_offset_depth_alproto = 0;
1151 uint32_t warn_non_alproto_fp_for_alproto_sig = 0;
1152 uint32_t warn_no_direction = 0;
1153 uint32_t warn_both_direction = 0;
1155 EngineAnalysisItemsInit();
1161 rule_bidirectional = 1;
1175 rule_ipv4_only += 1;
1178 rule_ipv6_only += 1;
1186 if (item_slot == -1) {
1194 if (item_slot == -1) {
1199 rule_content_offset_depth++;
1205 rule_content_http++;
1211 warn_encoding_norm_http_buf += 1;
1218 rule_flow_toserver = 1;
1221 rule_flow_toclient = 1;
1226 rule_flow_nostream = 1;
1252 warn_file_store_not_present = 1;
1255 if (rule_pcre > 0 && rule_content == 0 && rule_content_http == 0) {
1257 warn_pcre_no_content = 1;
1260 if (rule_content_http > 0 && rule_pcre > 0 && rule_pcre_http == 0) {
1262 warn_pcre_http_content = 1;
1268 if (rule_content > 0 && rule_content_http > 0) {
1270 warn_content_http_content = 1;
1274 warn_content_http = 1;
1276 if (rule_content == 1) {
1281 (rule_content || rule_content_http || rule_pcre || rule_pcre_http || rule_flowbits ||
1284 warn_tcp_no_flow = 1;
1286 if (rule_flow && !rule_bidirectional && (rule_flow_toserver || rule_flow_toclient)
1291 warn_client_ports = 1;
1294 if (rule_flow && rule_bidirectional && (rule_flow_toserver || rule_flow_toclient)) {
1299 if (*http_method_item_seen_ptr) {
1300 if (rule_flow && rule_flow_toclient) {
1302 warn_method_toclient = 1;
1304 if (*http_server_body_item_seen_ptr) {
1306 warn_method_serverbody = 1;
1308 if (rule_content == 0 && rule_content_http == 0 && (rule_pcre > 0 || rule_pcre_http > 0)) {
1310 warn_pcre_method = 1;
1313 if (rule_content_offset_depth > 0 && stream_buf && packet_buf) {
1315 warn_offset_depth_pkt_stream = 1;
1319 warn_offset_depth_alproto = 1;
1324 warn_non_alproto_fp_for_alproto_sig = 1;
1328 warn_no_direction += 1;
1335 warn_both_direction += 1;
1340 if (!rule_warnings_only || (rule_warnings_only && rule_warning > 0)) {
1341 fprintf(rule_engine_analysis_FD,
"== Sid: %u ==\n", s->
id);
1342 fprintf(rule_engine_analysis_FD,
"%s\n", line);
1346 if (rule_ipv6_only) fprintf(rule_engine_analysis_FD,
" Rule is IPv6 only.\n");
1347 if (rule_ipv4_only) fprintf(rule_engine_analysis_FD,
" Rule is IPv4 only.\n");
1348 if (packet_buf) fprintf(rule_engine_analysis_FD,
" Rule matches on packets.\n");
1349 if (!rule_flow_nostream && stream_buf &&
1350 (rule_flow || rule_flowbits || rule_flowint || rule_content || rule_pcre)) {
1351 fprintf(rule_engine_analysis_FD,
" Rule matches on reassembled stream.\n");
1356 fprintf(rule_engine_analysis_FD,
" Rule matches on %s buffer.\n", ai->
display_name);
1362 if (rule_content || rule_content_http || rule_pcre || rule_pcre_http) {
1363 fprintf(rule_engine_analysis_FD,
1364 " Rule contains %u content options, %u http content options, %u pcre "
1365 "options, and %u pcre options with http modifiers.\n",
1366 rule_content, rule_content_http, rule_pcre, rule_pcre_http);
1371 fprintf(rule_engine_analysis_FD,
" Prefilter on: %s.\n",
1374 EngineAnalysisRulesPrintFP(
de_ctx, s);
1378 if (warn_pcre_no_content ) {
1379 fprintf(rule_engine_analysis_FD,
" Warning: Rule uses pcre without a content option present.\n"
1380 " -Consider adding a content to improve performance of this rule.\n");
1382 if (warn_pcre_http_content ) {
1383 fprintf(rule_engine_analysis_FD,
" Warning: Rule uses content options with http_* and pcre options without http modifiers.\n"
1384 " -Consider adding http pcre modifier.\n");
1386 else if (warn_pcre_http ) {
1387 fprintf(rule_engine_analysis_FD,
" Warning: Rule app layer protocol is http, but pcre options do not have http modifiers.\n"
1388 " -Consider adding http pcre modifiers.\n");
1390 if (warn_content_http_content ) {
1391 fprintf(rule_engine_analysis_FD,
" Warning: Rule contains content with http_* and content without http_*.\n"
1392 " -Consider adding http content modifiers.\n");
1394 if (warn_content_http ) {
1395 fprintf(rule_engine_analysis_FD,
" Warning: Rule app layer protocol is http, but content options do not have http_* modifiers.\n"
1396 " -Consider adding http content modifiers.\n");
1398 if (rule_content == 1) {
1401 if (warn_encoding_norm_http_buf) {
1402 fprintf(rule_engine_analysis_FD,
" Warning: Rule may contain percent encoded content for a normalized http buffer match.\n");
1404 if (warn_tcp_no_flow
1406 fprintf(rule_engine_analysis_FD,
" Warning: TCP rule without a flow or flags option.\n"
1407 " -Consider adding flow or flags to improve performance of this rule.\n");
1409 if (warn_client_ports
1413 fprintf(rule_engine_analysis_FD,
" Warning: Rule contains ports or port variables only on the client side.\n"
1414 " -Flow direction possibly inconsistent with rule.\n");
1416 if (warn_direction ) {
1417 fprintf(rule_engine_analysis_FD,
" Warning: Rule is bidirectional and has a flow option with a specific direction.\n");
1419 if (warn_method_toclient ) {
1420 fprintf(rule_engine_analysis_FD,
" Warning: Rule uses content or pcre for http_method with flow:to_client or from_server\n");
1422 if (warn_method_serverbody ) {
1423 fprintf(rule_engine_analysis_FD,
" Warning: Rule uses content or pcre for http_method with content or pcre for http_server_body.\n");
1425 if (warn_pcre_method
1427 fprintf(rule_engine_analysis_FD,
" Warning: Rule uses pcre with only a http_method content; possible performance issue.\n");
1429 if (warn_offset_depth_pkt_stream) {
1430 fprintf(rule_engine_analysis_FD,
" Warning: Rule has depth"
1431 "/offset with raw content keywords. Please note the "
1432 "offset/depth will be checked against both packet "
1433 "payloads and stream. If you meant to have the offset/"
1434 "depth checked against just the payload, you can update "
1435 "the signature as \"alert tcp-pkt...\"\n");
1437 if (warn_offset_depth_alproto) {
1438 fprintf(rule_engine_analysis_FD,
" Warning: Rule has "
1439 "offset/depth set along with a match on a specific "
1440 "app layer protocol - %d. This can lead to FNs if we "
1441 "have a offset/depth content match on a packet payload "
1442 "before we can detect the app layer protocol for the "
1445 if (warn_non_alproto_fp_for_alproto_sig) {
1446 fprintf(rule_engine_analysis_FD,
" Warning: Rule app layer "
1447 "protocol is http, but the fast_pattern is set on the raw "
1448 "stream. Consider adding fast_pattern over a http "
1449 "buffer for increased performance.");
1451 if (warn_no_direction) {
1452 fprintf(rule_engine_analysis_FD,
" Warning: Rule has no direction indicator.\n");
1454 if (warn_both_direction) {
1455 fprintf(rule_engine_analysis_FD,
" Warning: Rule is inspecting both the request and the response.\n");
1457 if (warn_file_store_not_present) {
1458 fprintf(rule_engine_analysis_FD,
" Warning: Rule requires file-store but the output file-store is not enabled.\n");
1460 if (rule_warning == 0) {
1461 fprintf(rule_engine_analysis_FD,
" No warnings for this rule.\n");
1463 fprintf(rule_engine_analysis_FD,
"\n");