Files
gurix 0f15d9fca4 docs(04-01): complete BPF/pcap-reader plan summary and state updates
- Create 04-01-SUMMARY.md for BPF validation, pcap reading, timestamp aggregation
- Update STATE.md: advance plan, record metrics, add decisions, update session
- Update ROADMAP.md: phase 4 progress to 1/2 plans complete
- Mark CAPT-05, CAPT-06 requirements complete in REQUIREMENTS.md
2026-03-26 14:36:07 +01:00

95 lines
4.5 KiB
Markdown

---
phase: 04-power-user-features
plan: "01"
subsystem: capture/aggregate/classify
tags: [bpf, pcap-reader, timestamp, aggregation, gap-filling]
dependency_graph:
requires: [03-02]
provides: [ValidateBPFFilter, CompileSoftwareBPF, ReadPcapFile, AggregatePcap, ClassifiedPacket.Timestamp]
affects: [capture, aggregate, classify, cmd/netsynth]
tech_stack:
added: []
patterns:
- software BPF VM (golang.org/x/net/bpf) for user-space packet filtering
- pcapgo.NewReader for pcap file parsing without live socket
- timestamp-based window assignment replacing wall-clock ticker
key_files:
created:
- capture/bpf.go
- capture/bpf_test.go
- capture/pcap_reader.go
- capture/pcap_reader_test.go
modified:
- classify/types.go
- capture/capture.go
- aggregate/window.go
- aggregate/window_test.go
- cmd/netsynth/main.go
decisions:
- OpenCapture/StartCapture accept filter string; empty string = no filter (backward compatible)
- Software BPF via golang.org/x/net/bpf.VM for pcap file filtering (kernel BPF unavailable for files)
- AggregatePcap drains entire channel synchronously then assigns to windows (vs streaming)
- Gap windows initialized with make(map) at creation time to avoid nil map panics
metrics:
duration: "3 minutes"
completed_date: "2026-03-26"
tasks_completed: 2
files_changed: 9
---
# Phase 04 Plan 01: BPF validation, pcap reading, and timestamp-based aggregation
**One-liner:** Core library functions for BPF filter validation, pcap file reading with software BPF, Timestamp field on ClassifiedPacket, and offline timestamp-based windowing with gap-filling silence.
## What Was Built
### classify/types.go
Added `Timestamp time.Time` field to `ClassifiedPacket`. This is a backward-compatible addition — live mode leaves it zero-valued (no behavior change). Pcap mode sets it from packet metadata for window assignment.
### capture/bpf.go
Two exported functions:
- `ValidateBPFFilter(expr string) error` — validates BPF expressions without a live socket using go-pcap's filter package; empty strings return nil (no filter)
- `CompileSoftwareBPF(expr string) (*bpf.VM, error)` — compiles BPF to user-space VM for pcap file filtering where kernel BPF is unavailable
### capture/pcap_reader.go
`ReadPcapFile(path, filter string) (<-chan gopacket.Packet, error)` — opens a pcap file via `pcapgo.NewReader`, optionally applies a software BPF VM filter, emits packets on a buffered channel, closes channel when done. Sets `NoCopy = false` per Pitfall 3 (pcapgo requires owned buffers).
### capture/capture.go
Updated `OpenCapture` and `StartCapture` to accept a `filter string` parameter. `OpenCapture` calls `handle.SetBPFFilter(filter)` if filter is non-empty, returning a wrapped error on failure.
### aggregate/window.go
Added `AggregatePcap` — synchronously drains the events channel, assigns packets to time windows using `Timestamp.Sub(minTimestamp).Milliseconds()/windowMs`, fills gaps with empty snapshots (TotalPackets=0), fires `onSnapshot` callback per window for `--verbose` support. Returns `[]WindowSnapshot`.
## Tests Added
| File | Tests |
|------|-------|
| capture/bpf_test.go | TestValidateBPFFilter, TestValidateBPFFilterEmpty, TestValidateBPFFilterWhitespace, TestValidateBPFFilterInvalid, TestCompileSoftwareBPF, TestCompileSoftwareBPFInvalid |
| capture/pcap_reader_test.go | TestReadPcapFile, TestReadPcapFileNotFound, TestReadPcapFileInvalid, TestReadPcapFileWithFilter, TestClassifiedPacketTimestamp |
| aggregate/window_test.go | TestAggregatePcapBasic, TestAggregatePcapMultipleWindows, TestAggregatePcapGaps, TestAggregatePcapEmpty, TestAggregatePcapWindowIndex, TestAggregatePcapClassCounts, TestAggregatePcapOnSnapshot |
## Commits
| Task | Commit | Description |
|------|--------|-------------|
| Task 1 | 52c6010 | feat(04-01): BPF validation, pcap reading, Timestamp field, filter support |
| Task 2 | d13844f | feat(04-01): AggregatePcap with timestamp-based windowing and gap-filling |
## Deviations from Plan
None — plan executed exactly as written.
## Known Stubs
None. All functions are fully wired and functional. Plan 02 will wire them into the CLI (--filter and --read flags).
## Self-Check: PASSED
Files exist:
- /home/dev/workspace/yoloyolo/capture/bpf.go: FOUND
- /home/dev/workspace/yoloyolo/capture/pcap_reader.go: FOUND
- /home/dev/workspace/yoloyolo/aggregate/window.go: FOUND (AggregatePcap added)
- /home/dev/workspace/yoloyolo/classify/types.go: FOUND (Timestamp field added)
Commits verified: 52c6010, d13844f in git log.