Documentation
¶
Index ¶
- Constants
- type Confidence
- type ConnectionError
- type DetectError
- type Engine
- func (e *Engine) Detect(ctx context.Context, target Target) Result
- func (e *Engine) DetectAll(ctx context.Context, target Target) []Result
- func (e *Engine) DetectProtocol(ctx context.Context, target Target, protocol Protocol) (Result, error)
- func (e *Engine) Scan(ctx context.Context, target Target) ScanReport
- type EngineConfig
- type Exchange
- type Fingerprint
- type Fingerprinter
- type InvalidResponseError
- type Observer
- type Protocol
- type ProtocolNotFoundError
- type Registry
- type Result
- type ScanReport
- type Target
- type TimeoutError
Constants ¶
const DefaultTimeout = 5 * time.Second
DefaultTimeout is used when Target.Timeout is zero.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Confidence ¶
type Confidence float64
Confidence represents a detection certainty score between 0.0 and 1.0. Using a named type prevents accidental misuse and makes domain logic explicit.
func (Confidence) IsHigh ¶
func (c Confidence) IsHigh(threshold float64) bool
IsHigh reports whether c meets or exceeds the given threshold.
func (Confidence) Valid ¶
func (c Confidence) Valid() bool
Valid reports whether c is within the allowed range [0.0, 1.0].
type ConnectionError ¶
ConnectionError indicates a transport-level failure (refused, unreachable, etc.).
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
func (*ConnectionError) Unwrap ¶
func (e *ConnectionError) Unwrap() error
type DetectError ¶
type DetectError struct {
Protocol Protocol
Op string // short operation name, e.g. "dial", "send", "receive"
Err error
}
DetectError wraps an error that occurred during protocol detection. Callers can inspect Protocol and Op for structured logging and metrics.
func (*DetectError) Error ¶
func (e *DetectError) Error() string
func (*DetectError) Unwrap ¶
func (e *DetectError) Unwrap() error
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine orchestrates protocol detection using registered fingerprinters.
func NewEngine ¶
func NewEngine(registry *Registry, config EngineConfig) *Engine
NewEngine creates a new detection engine with the given registry and config.
func (*Engine) Detect ¶
Detect runs all fingerprinters and returns the best match. If no protocol is detected, it returns a Result with Protocol=ProtocolUnknown.
func (*Engine) DetectAll ¶
DetectAll runs all registered fingerprinters against the target and returns all results sorted by confidence (highest first).
type EngineConfig ¶
type EngineConfig struct {
// Parallel enables parallel protocol detection.
// When false, protocols are tested sequentially.
Parallel bool
// EarlyStop causes the engine to stop after the first high-confidence match
// (Confidence >= HighConfidenceThreshold).
EarlyStop bool
// HighConfidenceThreshold is the minimum confidence to trigger early stop.
// Default: 0.9
HighConfidenceThreshold Confidence
// MaxConcurrency limits the number of in-flight goroutines when Parallel
// is true. Zero or negative means unbounded.
MaxConcurrency int
// MinInterval enforces a minimum delay between sequential protocol
// attempts (or between goroutine launches in parallel mode).
// In ICS environments, burst scanning may trigger IDS alerts.
// Zero means no delay.
MinInterval time.Duration
// Observer receives callbacks during detection for metrics, tracing,
// or audit logging. Nil disables observation.
Observer Observer
}
EngineConfig configures the detection engine behavior.
func DefaultEngineConfig ¶
func DefaultEngineConfig() EngineConfig
DefaultEngineConfig returns sensible default engine configuration. Parallel is disabled by default because protocol detection always targets a single endpoint, and many industrial devices cannot handle concurrent TCP connections reliably — leading to non-deterministic results.
func SafeEngineConfig ¶
func SafeEngineConfig() EngineConfig
SafeEngineConfig returns a conservative configuration suitable for production OT environments where minimising network impact is critical.
type Exchange ¶
type Exchange struct {
// Label describes this exchange phase (e.g. "phase1", "probe").
Label string `json:"label"`
// Probe is the raw bytes sent to the target.
Probe []byte `json:"probe"`
// Response is the raw bytes received from the target.
Response []byte `json:"response"`
}
Exchange records the raw bytes of a single probe/response round-trip. Populated when debug tracing is desired; nil otherwise.
type Fingerprint ¶
type Fingerprint struct {
// ID is a dot-separated identifier, e.g. "modbus.fc43".
ID string `json:"id"`
// Signature is a compact machine-parseable string of key observations.
Signature string `json:"signature"`
// Metadata holds protocol-specific key-value pairs.
Metadata map[string]string `json:"metadata,omitempty"`
}
Fingerprint holds structured identification data from a detection. It provides machine-readable fields suitable for SIEM integration, asset fingerprint databases, and security product embedding.
func (*Fingerprint) String ¶
func (f *Fingerprint) String() string
String returns a compact representation of the fingerprint.
type Fingerprinter ¶
type Fingerprinter interface {
// Name returns the protocol identifier this fingerprinter detects.
Name() Protocol
// Priority returns the detection order priority (lower = tested first).
// Priorities are conventionally spaced in increments of 10 to allow
// insertion without renumbering.
Priority() int
// Detect attempts to identify the protocol on the given target.
// It must respect context cancellation and target timeout.
// It must never panic, even on malformed or unexpected responses.
Detect(ctx context.Context, target Target) (Result, error)
}
Fingerprinter is the interface that each protocol detector must implement. Implementations must be safe for concurrent use.
type InvalidResponseError ¶
InvalidResponseError indicates the target responded, but the response was malformed or did not conform to the expected protocol framing. Useful for distinguishing "wrong protocol" from "broken implementation".
func (*InvalidResponseError) Error ¶
func (e *InvalidResponseError) Error() string
type Observer ¶
type Observer interface {
// OnStart is called before each protocol detection attempt begins.
OnStart(protocol Protocol, target Target)
// OnResult is called after each detection attempt completes.
OnResult(result Result)
}
Observer receives callbacks during protocol detection for instrumentation. Implementations must be safe for concurrent use when Parallel is true. All methods must be non-blocking.
type Protocol ¶
type Protocol uint8
Protocol represents a named OT protocol identifier as an efficient integer type. String representations are maintained via a lookup table. Protocol values are stable across versions and must not be reordered.
const ( ProtocolUnknown Protocol = 0 ProtocolModbus Protocol = 1 ProtocolMMS Protocol = 2 ProtocolS7 Protocol = 3 ProtocolOPCUA Protocol = 4 ProtocolBACnet Protocol = 5 ProtocolCAN Protocol = 6 ProtocolPROFINET Protocol = 7 ProtocolDNP3 Protocol = 8 ProtocolIEC104 Protocol = 9 ProtocolENIP Protocol = 10 )
Known protocol identifiers.
func AllProtocols ¶
func AllProtocols() []Protocol
AllProtocols returns every known protocol in recommended detection order. The order prioritises ISO-based protocols, then progressively moves to lighter-weight probes and niche gateways.
func ParseProtocol ¶
ParseProtocol converts a protocol name string to its typed constant. Returns an error if the name does not match any known protocol.
type ProtocolNotFoundError ¶
type ProtocolNotFoundError struct {
Protocol Protocol
}
ProtocolNotFoundError is returned when a requested protocol is not registered.
func (*ProtocolNotFoundError) Error ¶
func (e *ProtocolNotFoundError) Error() string
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds registered protocol fingerprinters. It is safe for concurrent use.
func (*Registry) All ¶
func (r *Registry) All() []Fingerprinter
All returns all registered fingerprinters sorted by priority (lowest first).
func (*Registry) Get ¶
func (r *Registry) Get(protocol Protocol) Fingerprinter
Get returns the fingerprinter for the given protocol, or nil if not found.
func (*Registry) Register ¶
func (r *Registry) Register(fp Fingerprinter) error
Register adds a fingerprinter to the registry. Returns an error if a fingerprinter with the same name is already registered.
type Result ¶
type Result struct {
// Protocol identifies the protocol this result relates to.
Protocol Protocol
// Matched is true if the protocol was positively identified.
Matched bool
// Confidence is a score between 0.0 and 1.0 indicating detection certainty.
Confidence Confidence
// Details provides additional human-readable information about the detection.
Details string
// Error records the underlying error when detection fails.
// A non-nil Error with Matched==false allows callers to distinguish
// "no match" from "could not reach host".
Error error
// Fingerprint holds structured identification data.
// Nil when no fingerprint is available.
Fingerprint *Fingerprint
// DetectionID is a unique identifier for this detection attempt,
// useful for correlating log entries and audit trails.
DetectionID string
// Timestamp records when this result was created.
Timestamp time.Time
// Exchanges records raw probe/response byte pairs for debug tracing.
// Nil when tracing is not enabled.
Exchanges []Exchange `json:"exchanges,omitempty"`
}
Result holds the outcome of a fingerprint detection attempt.
Detection semantics:
Scenario Matched Error Confidence Positive match true nil > 0 No match false nil 0 Timeout false *TimeoutError 0 Connection refused false *ConnectionError 0 Invalid response false *InvalidRespError 0
func ErrorResult ¶
ErrorResult returns a Result recording a detection error. Matched is false and the error is preserved for inspection.
func Match ¶
func Match(protocol Protocol, confidence Confidence, details string) Result
Match returns a Result indicating a successful protocol detection.
func (Result) WithExchange ¶
WithExchange appends a probe/response exchange to the result for debug tracing.
func (Result) WithFingerprint ¶
func (r Result) WithFingerprint(fp *Fingerprint) Result
WithFingerprint returns a copy of r with the given fingerprint set.
type ScanReport ¶
type ScanReport struct {
// Target is the endpoint that was scanned.
Target Target
// StartedAt records when the scan began.
StartedAt time.Time
// FinishedAt records when the scan completed.
FinishedAt time.Time
// Duration is the wall-clock time of the scan.
Duration time.Duration
// Results holds all individual detection outcomes, sorted by
// confidence descending.
Results []Result
// BestMatch is the highest-confidence matched result, or a
// ProtocolUnknown result if nothing matched.
BestMatch Result
}
ScanReport is a structured summary of a complete detection run.
type Target ¶
type Target struct {
// IP is the target IP address.
IP string
// Port is the target TCP port.
Port int
// Timeout is the maximum duration for the fingerprint operation.
// If zero, a default timeout of 5 seconds is used.
Timeout time.Duration
}
Target represents a network endpoint to fingerprint.
func (Target) EffectiveTimeout ¶
EffectiveTimeout returns the configured timeout or DefaultTimeout if zero.
type TimeoutError ¶
TimeoutError indicates a detection attempt exceeded its deadline.
func (*TimeoutError) Error ¶
func (e *TimeoutError) Error() string
func (*TimeoutError) Unwrap ¶
func (e *TimeoutError) Unwrap() error