Skip to content

Commit 12d6239

Browse files
committed
netstack: write pcap header on new file capture
1 parent 84e2bbb commit 12d6239

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

intra/netstack/netstack.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const useIPTablesForICMP = false
2929
// enable forwarding of packets on the interface
3030
const nicfwd = false
3131

32+
const SnapLen uint32 = 2048 // in bytes; some sufficient value
33+
3234
type sniff struct {
3335
stack.LinkEndpoint
3436
Swapper
@@ -53,14 +55,15 @@ func NewEndpoint(dev, mtu int, sink io.WriteCloser) (ep SeamlessEndpoint, err er
5355
return nil, err
5456
}
5557
// ref: github.com/google/gvisor/blob/aeabb785278/pkg/tcpip/link/sniffer/sniffer.go#L111-L131
56-
return asSniffer(ep, sink, umtu)
58+
return asSniffer(ep, sink)
5759
}
5860

59-
func asSniffer(ep SeamlessEndpoint, sink io.WriteCloser, mtu uint32) (SeamlessEndpoint, error) {
61+
func asSniffer(ep SeamlessEndpoint, sink io.WriteCloser) (SeamlessEndpoint, error) {
6062
if sink == nil {
6163
return ep, nil
6264
}
63-
if link, err := sniffer.NewWithWriter(ep, sink, mtu); err != nil {
65+
// TODO: MTU instead of SnapLen? Must match pcapsink.begin()
66+
if link, err := sniffer.NewWithWriter(ep, sink, SnapLen); err != nil {
6467
return nil, err
6568
} else {
6669
return sniff{link, ep}, nil

intra/tunnel.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ type Tunnel interface {
7676
// to which a PCAP file will be written to.
7777
// If len(fpcap) is 0, no PCAP file will be written.
7878
// If len(fpcap) is 1, PCAP be written to stdout.
79+
// Must be called on a background thread.
7980
SetPcap(fpcap string) error
8081
// Set DNSMode, BlockMode, PtMode.
8182
SetTunMode(dnsmode, blockmode, ptmode int)

tunnel/tunnel.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424
package tunnel
2525

2626
import (
27+
"encoding/binary"
2728
"errors"
2829
"io"
2930
"os"
3031
"sync"
3132
"sync/atomic"
33+
"time"
3234

35+
"github.com/celzero/firestack/intra/core"
3336
"github.com/celzero/firestack/intra/log"
3437
"github.com/celzero/firestack/intra/netstack"
3538
"github.com/celzero/firestack/intra/settings"
@@ -102,17 +105,35 @@ func (p *pcapsink) Close() error {
102105
return err
103106
}
104107

108+
// from: github.com/google/gvisor/blob/596e8d22/pkg/tcpip/link/sniffer/sniffer.go#L93
109+
func (p *pcapsink) begin() error {
110+
_, offset := time.Date(0, 0, 0, 0, 0, 0, 0, time.Local).Zone()
111+
return binary.Write(p.sink, binary.LittleEndian, core.PcapHeader{
112+
MagicNumber: 0xa1b2c3d4,
113+
VersionMajor: 2,
114+
VersionMinor: 4,
115+
Thiszone: int32(offset),
116+
Sigfigs: 0,
117+
Snaplen: netstack.SnapLen, // must match netstack.asSniffer()
118+
Network: 101, // LINKTYPE_RAW
119+
})
120+
}
121+
105122
func (p *pcapsink) file(f io.WriteCloser) (err error) {
106123
p.Lock()
107124
w := p.sink
108125
p.sink = f
109126
p.Unlock()
110127

111128
if w != nil {
112-
err = w.Close()
129+
_ = w.Close()
113130
}
114131
y := f != nil
115-
netstack.FilePcap(y)
132+
if y {
133+
err = p.begin() // write pcap header before any packets
134+
log.I("tun: pcap: begin: writeHeader; err(%v)", err)
135+
}
136+
netstack.FilePcap(y) // signal netstack to write packets
116137
return
117138
}
118139

0 commit comments

Comments
 (0)