diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index c77864dcb8..d4ccc2cb11 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -1526,6 +1526,10 @@ jobs: env: LLVM_PROFILE_FILE: "/tmp/lah.profraw" - run: llvm-profdata-19 merge -o lah.profdata /tmp/lah.profraw + - run: ./src/suricata --list-rule-protos -l /tmp + env: + LLVM_PROFILE_FILE: "/tmp/lah.profraw" + - run: llvm-profdata-19 merge -o lah.profdata /tmp/lah.profraw - run: ./src/suricata --dump-features -c suricata.yaml -l /tmp env: LLVM_PROFILE_FILE: "/tmp/dumpfeatures.profraw" diff --git a/doc/userguide/rules/intro.rst b/doc/userguide/rules/intro.rst index 7b765d6b90..212c2485e7 100644 --- a/doc/userguide/rules/intro.rst +++ b/doc/userguide/rules/intro.rst @@ -125,6 +125,8 @@ you can pick from. These are: * websocket * pgsql +This list of protocols can be obtained via ``suricata --list-rule-protos``. + The availability of these protocols depends on whether the protocol is enabled in the configuration file, suricata.yaml. diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index b4e24106cc..fed5b460b7 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -883,6 +883,9 @@ extern "C" { default_enabled: bool, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn AppProtoDetectListNames(); +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct AppLayerParserState_ { diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index e00b4d2dd1..91f0d7bc92 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -1696,6 +1696,22 @@ int AppLayerProtoDetectSetup(void) SCReturnInt(0); } +void AppProtoDetectListNames(void) +{ + if (alpd_ctx.alproto_names[ALPROTO_HTTP1] || alpd_ctx.alproto_names[ALPROTO_HTTP2]) { + printf("http\n"); + } + for (size_t i = 0; i < alpd_ctx.alproto_names_len; i++) { + if (alpd_ctx.alproto_names[i]) { + if (i == ALPROTO_HTTP1) { + printf("http1\n"); + } else { + printf("%s\n", alpd_ctx.alproto_names[i]); + } + } + } +} + /** * \todo incomplete. Need more work. */ diff --git a/src/app-layer-detect-proto.h b/src/app-layer-detect-proto.h index 0c68d0dcd7..52737e9c25 100644 --- a/src/app-layer-detect-proto.h +++ b/src/app-layer-detect-proto.h @@ -193,6 +193,8 @@ void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos); void AppLayerRegisterExpectationProto(uint8_t proto, AppProto alproto); +void AppProtoDetectListNames(void); + /***** Unittests *****/ #ifdef UNITTESTS diff --git a/src/detect-engine-proto.c b/src/detect-engine-proto.c index 4e7ab9ff07..18cb3c4358 100644 --- a/src/detect-engine-proto.c +++ b/src/detect-engine-proto.c @@ -66,6 +66,13 @@ struct { { "pkthdr", 0, 0, DETECT_PROTO_ANY }, }; +void DetectEngineProtoList(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(proto_table); i++) { + printf("%s\n", proto_table[i].name); + } +} + /** * \brief Parses a protocol sent as a string. * diff --git a/src/detect-engine-proto.h b/src/detect-engine-proto.h index 95089a23e7..81a06cf49c 100644 --- a/src/detect-engine-proto.h +++ b/src/detect-engine-proto.h @@ -40,6 +40,7 @@ typedef struct DetectProto_ { /* prototypes */ int DetectProtoParse(DetectProto *dp, const char *str); int DetectProtoContainsProto(const DetectProto *, int); +void DetectEngineProtoList(void); void DetectProtoTests(void); diff --git a/src/detect-parse.c b/src/detect-parse.c index 7dab386a02..ee98977600 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1365,6 +1365,13 @@ static int SigParseProtoHookApp(Signature *s, const char *proto_hook, const char return 0; } +void DetectListSupportedProtocols(void) +{ + printf("=========Supported Rule Protocols=========\n"); + DetectEngineProtoList(); + AppProtoDetectListNames(); +} + /** * \brief Parses the protocol supplied by the Signature. * diff --git a/src/detect-parse.h b/src/detect-parse.h index 5406972994..706f2eae8d 100644 --- a/src/detect-parse.h +++ b/src/detect-parse.h @@ -113,5 +113,6 @@ int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UC #endif void DetectRegisterAppLayerHookLists(void); +void DetectListSupportedProtocols(void); #endif /* SURICATA_DETECT_PARSE_H */ diff --git a/src/runmodes.h b/src/runmodes.h index 1c8a659e4e..4eab059987 100644 --- a/src/runmodes.h +++ b/src/runmodes.h @@ -45,6 +45,7 @@ typedef enum SCRunModes { RUNMODE_USER_MAX, /* Last standard running mode */ RUNMODE_LIST_KEYWORDS, RUNMODE_LIST_APP_LAYERS, + RUNMODE_LIST_RULE_PROTOS, RUNMODE_LIST_APP_LAYER_HOOKS, RUNMODE_LIST_RUNMODES, RUNMODE_PRINT_VERSION, diff --git a/src/suricata.c b/src/suricata.c index 161b7b9ca9..941a9049d8 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -717,6 +717,7 @@ static void PrintUsage(const char *progname) printf("\t--list-keywords[=all|csv|] : list keywords implemented by the engine\n"); printf("\t--list-runmodes : list supported runmodes\n"); printf("\t--list-app-layer-protos : list supported app layer protocols\n"); + printf("\t--list-rule-protos : list supported rule protocols\n"); printf("\t--list-app-layer-hooks : list supported app layer hooks for use in " "rules\n"); printf("\t--dump-config : show the running configuration\n"); @@ -1374,6 +1375,7 @@ TmEcode SCParseCommandLine(int argc, char **argv) int dump_config = 0; int dump_features = 0; int list_app_layer_protocols = 0; + int list_rule_protocols = 0; int list_app_layer_hooks = 0; int list_unittests = 0; int list_runmodes = 0; @@ -1423,6 +1425,7 @@ TmEcode SCParseCommandLine(int argc, char **argv) {"pcap-buffer-size", required_argument, 0, 0}, {"unittest-filter", required_argument, 0, 'U'}, {"list-app-layer-protos", 0, &list_app_layer_protocols, 1}, + {"list-rule-protos", 0, &list_rule_protocols, 1}, {"list-app-layer-hooks", 0, &list_app_layer_hooks, 1}, {"list-unittests", 0, &list_unittests, 1}, {"list-runmodes", 0, &list_runmodes, 1}, @@ -2121,6 +2124,8 @@ TmEcode SCParseCommandLine(int argc, char **argv) if (list_app_layer_protocols) suri->run_mode = RUNMODE_LIST_APP_LAYERS; + if (list_rule_protocols) + suri->run_mode = RUNMODE_LIST_RULE_PROTOS; if (list_app_layer_hooks) suri->run_mode = RUNMODE_LIST_APP_LAYER_HOOKS; if (list_keywords) @@ -2393,6 +2398,12 @@ int SCStartInternalRunMode(int argc, char **argv) switch (suri->run_mode) { case RUNMODE_LIST_KEYWORDS: return ListKeywords(suri->keyword_info); + case RUNMODE_LIST_RULE_PROTOS: + if (suri->conf_filename != NULL) { + return ListRuleProtocols(suri->conf_filename); + } else { + return ListRuleProtocols(DEFAULT_CONF_FILE); + } case RUNMODE_LIST_APP_LAYERS: if (suri->conf_filename != NULL) { return ListAppLayerProtocols(suri->conf_filename); diff --git a/src/util-running-modes.c b/src/util-running-modes.c index defe81ac51..14f22dede9 100644 --- a/src/util-running-modes.c +++ b/src/util-running-modes.c @@ -25,6 +25,7 @@ #include "app-layer.h" #include "app-layer-parser.h" #include "detect-engine.h" +#include "detect-parse.h" #include "util-unittest.h" #include "util-debug.h" #include "conf-yaml-loader.h" @@ -55,6 +56,19 @@ int ListAppLayerProtocols(const char *conf_filename) return TM_ECODE_DONE; } +int ListRuleProtocols(const char *conf_filename) +{ + EngineModeSetIDS(); + if (SCConfYamlLoadFile(conf_filename) != -1) + SCLogLoadConfig(0, 0, 0, 0); + MpmTableSetup(); + SpmTableSetup(); + AppLayerSetup(); + DetectListSupportedProtocols(); + + return TM_ECODE_DONE; +} + static bool IsBuiltIn(const char *n) { if (strcmp(n, "request_started") == 0 || strcmp(n, "response_started") == 0) { diff --git a/src/util-running-modes.h b/src/util-running-modes.h index 781c58a72d..62623ccc16 100644 --- a/src/util-running-modes.h +++ b/src/util-running-modes.h @@ -25,6 +25,7 @@ int ListKeywords(const char *keyword_info); int ListAppLayerProtocols(const char *conf_filename); +int ListRuleProtocols(const char *conf_filename); int ListAppLayerHooks(const char *conf_filename); #endif /* SURICATA_UTIL_RUNNING_MODES_H */