protocol

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package protocol contains functions for performing protocol detection.

Confidence scores

All registered detectors in this package shall output a confidence score. If there are multiple matching protocols, the protocol with the highest confidence score will be returned to the caller.

Confidence scores should be between 0 and 0.99, but there is no hard enforcement of this range in this package.

Protocol matching

The first level matching happens with magic strings, as inspired by Go's image.RegisterFormat function. The only addition that this package has made, is that you can also use the '*' character for wildcard matching.

The supported magic strings input is documented in the Match function.

Strict mode

Some parser also allow for strict parsing of the protocol, which results in a higher confidence score, but it also may lead to more false negatives. If Strict mode is enabled, then only the detectors that support strict checking will be used for protocol detections.

Index

Examples

Constants

View Source
const (
	TypeACME        = "ACME"
	TypeCoAP        = "CoAP"
	TypeDNS         = "DNS"
	TypeFTP         = "FTP"
	TypeHTTP        = "HTTP"
	TypeIRC         = "IRC"
	TypeIMAP        = "IMAP"
	TypeJabber      = TypeXMPP
	TypeManageSieve = "ManageSieve"
	TypeMosquitto   = TypeMQTT
	TypeMQTT        = "MQTT"
	TypeMySQL       = "MySQL"
	TypeNNTP        = "NNTP"
	TypePOP3        = "POP3"
	TypePgSQL       = TypePostgreSQL
	TypePostgreSQL  = "PostgreSQL"
	TypeRADIUS      = "RADIUS"
	TypeSamba       = TypeSMB
	TypeSIP         = "SIP"
	TypeSMB         = "SMB"
	TypeSSH         = "SSH"
	TypeSSL         = "SSL"
	TypeSTUN        = "STUN"
	TypeSunRPC      = "SunRPC"
	TypeTLS         = "TLS"
	TypeWebRTC      = "WebRTC"
	TypeXMPP        = "XMPP"
)

Protocols supported by this package.

Variables

View Source
var (
	ErrTimeout = errors.New("timeout")
	ErrUnknown = errors.New("unknown protocol")
)

Common errors.

View Source
var ALPNProtocol = map[string]*Protocol{
	"acme-tls/1":         {Type: TypeACME, Encapsulation: TypeTLS, Version: Version{Major: 1}},
	"co":                 {Type: TypeCoAP, Encapsulation: TypeTLS},
	"coap":               {Type: TypeCoAP, Encapsulation: TypeTLS},
	"c-webrtc":           {Type: TypeWebRTC, Encapsulation: TypeTLS},
	"dot":                {Type: TypeDNS, Encapsulation: TypeTLS},
	"ftp":                {Type: TypeFTP, Encapsulation: TypeTLS},
	"http/0.9":           {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 0, Minor: 9, Patch: -1}},
	"http/1.0":           {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 0, Patch: -1}},
	"http/1.1":           {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 1, Patch: -1}},
	"h2":                 {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 2, Minor: -1, Patch: -1}},
	"h2c":                {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 2, Minor: -1, Patch: -1}},
	"h3":                 {Type: TypeHTTP, Encapsulation: TypeTLS, Version: Version{Major: 3, Minor: -1, Patch: -1}},
	"irc":                {Type: TypeIRC, Encapsulation: TypeTLS},
	"imap":               {Type: TypeIMAP, Encapsulation: TypeTLS},
	"managesieve":        {Type: TypeManageSieve, Encapsulation: TypeTLS},
	"mqtt":               {Type: TypeMQTT, Encapsulation: TypeTLS},
	"nntp":               {Type: TypeNNTP, Encapsulation: TypeTLS},
	"nnsp":               {Type: TypeNNTP, Encapsulation: TypeTLS},
	"postgresql":         {Type: TypePostgreSQL, Encapsulation: TypeTLS},
	"pop3":               {Type: TypePOP3, Encapsulation: TypeTLS},
	"radius/1.0":         {Type: TypeRADIUS, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 0, Patch: -1}},
	"radius/1.1":         {Type: TypeRADIUS, Encapsulation: TypeTLS, Version: Version{Major: 1, Minor: 1, Patch: -1}},
	"smb":                {Type: TypeSMB, Encapsulation: TypeTLS, Version: Version{Major: 2, Minor: -1, Patch: -1}},
	"stun.nat-discovery": {Type: TypeSTUN, Encapsulation: TypeTLS},
	"stun.turn":          {Type: TypeSTUN, Encapsulation: TypeTLS},
	"sunrpc":             {Type: TypeSunRPC, Encapsulation: TypeTLS},
	"webrtc":             {Type: TypeWebRTC, Encapsulation: TypeTLS},
	"xmpp-client":        {Type: TypeXMPP, Encapsulation: TypeTLS},
	"xmpp-server":        {Type: TypeXMPP, Encapsulation: TypeTLS},
}

ALPNProtocol is a map of TLS Application-Layer Protocol Negotiation (ALPN) Protocol identifier to Protocol.

See https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids

View Source
var Dialer net.Dialer

Dialer used by probes to establish a connection.

View Source
var Strict bool

Strict mode requires a full, compliant packet to be captured. This is only implemented by some detectors.

Functions

func Limit

func Limit(conn net.Conn, accept AcceptFunc) net.Conn

Limit the connection protocol, by running a detection after either side sends a banner within timeout.

If no protocol could be detected, the accept function is called with a nil argument to check if we should proceed.

If the accept function returns an error, all future reads and writes on the returned connection will return that error.

func Match

func Match(magic string, input []byte) bool

Match the input against the magic string pattern.

  • '?' matches any single character
  • '*' matches zero or more characters
  • '\' escapes special characters ('?', '*', '\')
  • all other characters must match exactly

Returns true if all magic bytes are matched, even if the input has extra bytes.

Example
package main

import (
	"fmt"

	"git.maze.io/go/dpi/protocol"
)

func main() {
	fmt.Println(protocol.Match("t?s?", []byte("test")))
	fmt.Println(protocol.Match("t?s?", []byte("test with more data")))
	fmt.Println(protocol.Match("t?s?", []byte("text with more data")))
	fmt.Println(protocol.Match("select * from user", []byte("select an apple from user")))
	fmt.Println(protocol.Match("select * from user", []byte("select an apple from the user")))
}
Output:

true
true
false
true
false

func Register

func Register(dir Direction, magic string, detect DetectFunc)

Register a new protocol detector.

The direction indicates in what direction we'll inspect the []byte slice passed to the Detect function. Passing an invalid direction or None will be discarded.

The magic string is used to quickly analyze if the []byte slice passed to Detect qualifies for further inspection by the DetectFunc. See the Match function documentation for how magic strings are matched against the input.

Types

type AcceptFunc

type AcceptFunc func(Direction, *Protocol) error

AcceptFunc receives a direction and a detected protocol.

type DetectFunc

type DetectFunc func(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64)

DetectFunc is a function which runs the in-depth protcol detection logic.

The confidence score should be between 0 and 0.99. Score boundaries are not hard enforced by this library.

type Direction

type Direction int

Direction indicates the communcation direction.

const (
	// Unknown direction is the default value and is not a valid Direction.
	Unknown Direction = iota

	// Client initiated.
	Client

	// Server initiated.
	Server

	// Both is either client or server initiated.
	Both
)

Directions supported by this package.

func (Direction) Contains

func (dir Direction) Contains(other Direction) bool

Contains checks if the provided other direction is included in this direction.

func (Direction) IsValid

func (dir Direction) IsValid() bool

IsValid checks if dir has a value recognized by this library.

Also Unknown direction is not considered valid.

func (Direction) String

func (dir Direction) String() string

type Intercepted

type Intercepted struct {
	Direction  Direction
	Protocol   *Protocol
	Confidence float64
	Error      error
}

Intercepted is the result returned by Interceptor.Detect.

type Interceptor

type Interceptor struct {
	// contains filtered or unexported fields
}

Interceptor intercepts reads from client or server.

func NewInterceptor

func NewInterceptor() *Interceptor

NewInterceptor creates a new (transparent) protocol interceptor.

func (*Interceptor) Client

func (i *Interceptor) Client(c net.Conn) net.Conn

Client binds the client connection to the interceptor.

func (*Interceptor) Detect

func (i *Interceptor) Detect(timeout time.Duration) <-chan *Intercepted

Detect runs protocol detection on the previously bound Client and Server connection.

It waits until either the client or the server performs a read operation, which is then used for running protocol detection. If the read operation takes longer than timeout, an error is returned.

The returned channel always yields one result and is then closed.

func (*Interceptor) Server

func (i *Interceptor) Server(c net.Conn) net.Conn

Server binds the server connection to the interceptor.

type Protocol

type Protocol struct {
	// Type of protocol, usually one of the constants defined in this package.
	Type string

	// Encapsulation type, usually one of the constants defined in this package.
	//
	// Empty if there is no encapsulation.
	Encapsulation string

	// Version of the protocol. Unknown versions are marked with [UnknownVersion].
	Version Version
}

Protocol description.

func Detect

func Detect(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64, err error)

Detect a protocol based on the provided data.

func Probe

func Probe(network, address string) (proto *Protocol, confidence float64, err error)

Probe a network service by reading its banner and running protocol detection.

func ProbeContext

func ProbeContext(ctx context.Context, network, address string) (proto *Protocol, confidence float64, err error)

ProbeContext is like Probe with a context.Context.

func ProbeTLS

func ProbeTLS(network, address string, tlsConfig *tls.Config) (proto *Protocol, confidence float64, err error)

ProbeTLS is like Probe but first establishes a TLS connection.

func ProbeTLSContext

func ProbeTLSContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (proto *Protocol, confidence float64, err error)

ProbeTLSContext is like ProbeTLS with a context.Context.

func ProbeTLSTimeout

func ProbeTLSTimeout(network, address string, tlsConfig *tls.Config, timeout time.Duration) (proto *Protocol, confidence float64, err error)

ProbeTLSTimeout is like ProbeTLS but with a fixed timeout.

func ProbeTimeout

func ProbeTimeout(network, address string, timeout time.Duration) (proto *Protocol, confidence float64, err error)

ProbeTimeout is like Probe but with a fixed timeout.

func (Protocol) String

func (proto Protocol) String() string

type Version

type Version struct {
	Major int
	Minor int
	Patch int
	Extra string
}

Version of a protocol.

var UnknownVersion Version

UnknownVersion

func (Version) String

func (v Version) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL