2024-08-09 03:11:50 +00:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
|
|
|
|
package vnet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/google/gopacket"
|
|
|
|
"github.com/google/gopacket/pcapgo"
|
|
|
|
)
|
|
|
|
|
2024-08-09 04:29:09 +00:00
|
|
|
// pcapWriter is a pcapgo.NgWriter that writes to a file.
|
|
|
|
// It is safe for concurrent use. The nil value is a no-op.
|
2024-08-09 03:11:50 +00:00
|
|
|
type pcapWriter struct {
|
|
|
|
f *os.File
|
|
|
|
|
|
|
|
mu sync.Mutex
|
|
|
|
w *pcapgo.NgWriter
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *pcapWriter) WritePacket(ci gopacket.CaptureInfo, data []byte) error {
|
2024-08-09 04:29:09 +00:00
|
|
|
if p == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2024-08-09 03:11:50 +00:00
|
|
|
p.mu.Lock()
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
if p.w == nil {
|
|
|
|
return io.ErrClosedPipe
|
|
|
|
}
|
|
|
|
return p.w.WritePacket(ci, data)
|
|
|
|
}
|
|
|
|
|
2024-08-09 04:29:09 +00:00
|
|
|
func (p *pcapWriter) AddInterface(i pcapgo.NgInterface) (int, error) {
|
|
|
|
if p == nil {
|
|
|
|
return 0, nil
|
|
|
|
}
|
|
|
|
p.mu.Lock()
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
return p.w.AddInterface(i)
|
|
|
|
}
|
|
|
|
|
2024-08-09 03:11:50 +00:00
|
|
|
func (p *pcapWriter) Close() error {
|
2024-08-09 04:29:09 +00:00
|
|
|
if p == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2024-08-09 03:11:50 +00:00
|
|
|
p.mu.Lock()
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
if p.w != nil {
|
|
|
|
p.w.Flush()
|
|
|
|
p.w = nil
|
|
|
|
}
|
|
|
|
return p.f.Close()
|
|
|
|
}
|