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 ¶
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.
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) 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.