diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-07-28 22:43:52 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-07-28 22:46:06 -0700 |
commit | 095b0d8348531b96f1b40885c00d6cd7f07ecf80 (patch) | |
tree | f3429ef1d1a77f83e5a6907d6a501a5c606aebc9 /pkg/tcpip/link/sniffer/pcap.go | |
parent | 72c2b74ac3c145818e994326775d503d6ba0e368 (diff) |
Explicitly encode the pcap packet headers to reduce CPU cost of pcap generation.
PiperOrigin-RevId: 387513118
Diffstat (limited to 'pkg/tcpip/link/sniffer/pcap.go')
-rw-r--r-- | pkg/tcpip/link/sniffer/pcap.go | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go index 3bb864ed2..d3edede63 100644 --- a/pkg/tcpip/link/sniffer/pcap.go +++ b/pkg/tcpip/link/sniffer/pcap.go @@ -14,7 +14,14 @@ package sniffer -import "time" +import ( + "encoding" + "encoding/binary" + "time" + + "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/stack" +) type pcapHeader struct { // MagicNumber is the file magic number. @@ -39,25 +46,38 @@ type pcapHeader struct { Network uint32 } -type pcapPacketHeader struct { - // Seconds is the timestamp seconds. - Seconds uint32 - - // Microseconds is the timestamp microseconds. - Microseconds uint32 +var _ encoding.BinaryMarshaler = (*pcapPacket)(nil) - // IncludedLength is the number of octets of packet saved in file. - IncludedLength uint32 - - // OriginalLength is the actual length of packet. - OriginalLength uint32 +type pcapPacket struct { + timestamp time.Time + packet *stack.PacketBuffer + maxCaptureLen int } -func newPCAPPacketHeader(now time.Time, incLen, orgLen uint32) pcapPacketHeader { - return pcapPacketHeader{ - Seconds: uint32(now.Unix()), - Microseconds: uint32(now.Nanosecond() / 1000), - IncludedLength: incLen, - OriginalLength: orgLen, +func (p *pcapPacket) MarshalBinary() ([]byte, error) { + packetSize := p.packet.Size() + captureLen := p.maxCaptureLen + if packetSize < captureLen { + captureLen = packetSize + } + b := make([]byte, 16+captureLen) + binary.BigEndian.PutUint32(b[0:4], uint32(p.timestamp.Unix())) + binary.BigEndian.PutUint32(b[4:8], uint32(p.timestamp.Nanosecond()/1000)) + binary.BigEndian.PutUint32(b[8:12], uint32(captureLen)) + binary.BigEndian.PutUint32(b[12:16], uint32(packetSize)) + w := tcpip.SliceWriter(b[16:]) + for _, v := range p.packet.Views() { + if captureLen == 0 { + break + } + if len(v) > captureLen { + v = v[:captureLen] + } + n, err := w.Write(v) + if err != nil { + panic(err) + } + captureLen -= n } + return b, nil } |