bcap/analyzer.go

74 lines
1.4 KiB
Go
Raw Normal View History

2026-03-24 23:39:55 +08:00
package bcap
import (
"sync"
"time"
"github.com/gopacket/gopacket"
)
type Analyzer struct {
decoder *Decoder
tracker *Tracker
mu sync.Mutex
firstPacketTS time.Time
}
func NewAnalyzer() *Analyzer {
return NewAnalyzerWithConfig(nil)
}
func NewAnalyzerWithConfig(config *PacketsConfig) *Analyzer {
return &Analyzer{
decoder: NewDecoder(),
tracker: NewTrackerWithConfig(config),
}
}
func (a *Analyzer) Stop() {
if a.tracker != nil {
a.tracker.Stop()
}
}
func (a *Analyzer) Decoder() *Decoder {
return a.decoder
}
func (a *Analyzer) Tracker() *Tracker {
return a.tracker
}
func (a *Analyzer) ObservePacket(packet gopacket.Packet) (Observation, error) {
return a.ObservePacketWithOptions(packet, DecodeOptions{})
}
func (a *Analyzer) ObservePacketWithOptions(packet gopacket.Packet, opts DecodeOptions) (Observation, error) {
if opts.BaseTime.IsZero() {
opts.BaseTime = a.ensureBaseTime(packet)
}
decoded, err := a.decoder.DecodeWithOptions(packet, opts)
if err != nil {
return Observation{}, err
}
return a.tracker.Observe(decoded)
}
func (a *Analyzer) ensureBaseTime(packet gopacket.Packet) time.Time {
a.mu.Lock()
defer a.mu.Unlock()
if packet == nil {
return time.Time{}
}
metadata := packet.Metadata()
if metadata == nil || metadata.Timestamp.IsZero() {
return time.Time{}
}
if a.firstPacketTS.IsZero() {
a.firstPacketTS = metadata.Timestamp
}
return a.firstPacketTS
}