Plugin types
Every plugin has aPlugType that determines its role in the pipeline:
PT_CODEC
Decodes raw packets layer by layer (Ethernet, IP, TCP, custom protocols).
PT_INSPECTOR
Analyzes traffic between decode and detection — the workhorse of Snort preprocessing.
PT_IPS_OPTION
Implements rule keywords used in detection (e.g.
content, pcre, custom matchers).PT_IPS_ACTION
Specifies the verdict action taken when a rule fires (e.g.
react, reject, rewrite).PT_LOGGER
Logs packets and IPS events after thresholding.
PT_SEARCH_ENGINE
Pluggable multi-pattern search engine (MPSE) for fast pattern matching.
PT_SO_RULE
Shared-object rules — compiled detection logic loaded at runtime.
PT_CONNECTOR
Side-channel connectors for inter-process or inter-host communication.
PlugType enum in framework/base_api.h.
The BaseApi structure
Every plugin API starts with aBaseApi as its first member. This common header gives Snort the information it needs to manage any plugin regardless of type:
BASE_API_VERSION 25. Each plugin type also has its own version constant that is ORed into api_version:
| Plugin type | Version constant |
|---|---|
PT_INSPECTOR | INSAPI_VERSION |
PT_CODEC | CDAPI_VERSION |
PT_IPS_OPTION | IPSAPI_VERSION |
PT_LOGGER | LOGAPI_VERSION |
BaseApi is the first member of every plugin API struct, a pointer to any plugin API can be safely cast to BaseApi*, enabling uniform plugin management.
The snort_plugins[] symbol
A dynamic library exposes its plugins through a single exported symbol — a null-terminated array ofBaseApi pointers:
A single
.so library can contain multiple plugins. Add all their BaseApi pointers to the snort_plugins[] array before the terminating nullptr.Static vs dynamic plugins
There is no functional difference between a static plugin (compiled into Snort) and a dynamic plugin (loaded from a shared library at runtime). Both use the same API and the samesnort_plugins[] registration pattern.
Dynamic plugins are loaded using --plugin-path:
The Module system
Each plugin can have an associatedModule that handles Lua configuration. When Snort processes a Lua table whose name matches a module, it instantiates that module, calls its configuration methods, then passes the module to the plugin constructor.
For example, a plugin called gadget would be configured in snort.lua as:
gadget module, instantiates GadgetModule, sets brain and claw, then passes the configured module to the GadgetInspector constructor.
Module virtual methods
Three methods control the configuration lifecycle:begin()
Called when Snort starts processing the associated Lua table. Allocate any required data and set defaults here.
Snort sets all parameter defaults immediately after
begin() returns, so you should not set defaults inside begin() itself.There is at most one instance of a given Module at any time, even when multiple plugin instances (via binding) use it.
Module capabilities
Beyond configuration, a module can expose:| Method | Purpose |
|---|---|
get_rules() / get_gid() | Declare builtin GID/SID rules emitted by the plugin |
get_pegs() / get_counts() | Expose peg counters for --stats output |
get_profile() | Expose profiling stats for --profile output |
get_commands() | Register CLI control commands |
get_parameters() | Declare accepted Lua parameters with types and defaults |
Module usage types
A module’sUsage controls where and how many times it can appear in configuration:
GLOBAL
GLOBAL
Configured at most once, outside any policy. Applies process-wide.
CONTEXT
CONTEXT
Configured at most once per network policy. Example:
event_queue.INSPECT
INSPECT
Configured in an inspection policy (NAP). Stream and service inspectors (
stream_tcp, smtp) are multitons — they may appear more than once per policy. Others like binder are singletons.DETECT
DETECT
Configured at most once per IPS policy. Example:
ips.Building plugins
Plugins are built as ordinary shared libraries that link against the Snort headers. A minimalCMakeLists.txt:

