capture

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package capture turns bytes off the wire (or off disk) into decoded model.Packet values.

Everything here is pure Go. There is no libpcap/Npcap dependency and no cgo, which means `CGO_ENABLED=0 go build` produces a single static binary that runs in a scratch container and cross-compiles from any host. File replay works on every platform; live capture uses Linux AF_PACKET and is compiled out elsewhere.

Index

Constants

This section is empty.

Variables

View Source
var ErrDone = errors.New("capture: source exhausted")

ErrDone is returned by Source.Next when the source is exhausted (end of a capture file, or a closed handle).

Functions

This section is empty.

Types

type FileSource

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

FileSource replays a PCAP or PCAPNG file.

Replay is the backbone of the project's testing story: detections are deterministic functions of a capture file, so every detector has a regression test that is just "run this PCAP, expect these alerts". It is also what makes the demo runnable by someone with no network to sniff.

func OpenFile

func OpenFile(path string) (*FileSource, error)

OpenFile opens a capture file, sniffing the container format from its magic bytes rather than trusting the extension.

func (*FileSource) Close

func (s *FileSource) Close() error

Close implements Source.

func (*FileSource) LinkType

func (s *FileSource) LinkType() string

LinkType implements Source.

func (*FileSource) Next

func (s *FileSource) Next() (model.Packet, error)

Next implements Source.

func (*FileSource) Stats

func (s *FileSource) Stats() Stats

Stats implements Source.

type LiveSource

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

LiveSource captures from a network interface using AF_PACKET.

This is gopacket's pure-Go capture path, not a libpcap binding, which is what lets the whole binary build with CGO_ENABLED=0 and ship in a scratch container. The tradeoff is that it is Linux-only — which is the right tradeoff for a sensor, since that is where sensors run.

Capturing requires CAP_NET_RAW. Grant it narrowly rather than running as root: setcap cap_net_raw,cap_net_admin=eip ./tracehound

func OpenLive

func OpenLive(iface string, promiscuous bool) (*LiveSource, error)

OpenLive begins capturing on iface.

func (*LiveSource) Close

func (s *LiveSource) Close() error

Close implements Source.

func (*LiveSource) LinkType

func (s *LiveSource) LinkType() string

LinkType implements Source.

func (*LiveSource) Next

func (s *LiveSource) Next() (model.Packet, error)

Next implements Source.

func (*LiveSource) Stats

func (s *LiveSource) Stats() Stats

Stats implements Source, folding in the kernel's drop counter so that a sensor which cannot keep up says so rather than silently under-reporting.

AF_PACKET's TPACKET_GET_STATS is destructive: each call returns the counts *since the previous call* and resets them. Assigning the result would therefore report "0 dropped" on any call that happens to follow another closely, so the deltas are accumulated instead.

type Source

type Source interface {
	// Next returns the next decoded packet, or ErrDone when exhausted.
	// Packets that cannot be decoded are skipped internally rather than
	// surfaced as errors, so a single malformed frame never stops a capture.
	Next() (model.Packet, error)

	// LinkType describes the link layer of the source, for diagnostics.
	LinkType() string

	// Stats returns counters accumulated so far.
	Stats() Stats

	// Close releases the underlying handle.
	Close() error
}

Source yields decoded packets.

Next returns packets by value, but Packet.Payload aliases an internal read buffer that is reused on the following call. Consumers that need the bytes after the next Next must copy them. This is the standard zero-copy contract for packet sources and is what keeps the hot path allocation-free.

type Stats

type Stats struct {
	Packets  uint64 `json:"packets"`
	Bytes    uint64 `json:"bytes"`
	Dropped  uint64 `json:"dropped"`
	Decoded  uint64 `json:"decoded"`
	Undecode uint64 `json:"undecodable"`
}

Stats reports what a source has read so far.

Jump to

Keyboard shortcuts

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