Documentation

Overview

Package pcapgo provides some native PCAP support, not requiring C libpcap to be installed.

Overview

This package contains implementations for native PCAP support. Currently supported are

* pcap-files read/write: Reader, Writer
* pcapng-files read/write: NgReader, NgWriter
* raw socket capture (linux only): EthernetHandle

Basic Usage pcapng

Pcapng files can be read and written. Reading supports both big and little endian files, packet blocks, simple packet blocks, enhanced packets blocks, interface blocks, and interface statistics blocks. All the options also by Wireshark are supported. The default reader options match libpcap behaviour. Have a look at NgReaderOptions for more advanced usage. Both ReadPacketData and ZeroCopyReadPacketData is supported (which means PacketDataSource and ZeroCopyPacketDataSource is supported).

f, err := os.Open("somefile.pcapng")
if err != nil {
	...
}
defer f.Close()

r, err := NewNgReader(f, DefaultNgReaderOptions)
if err != nil {
	...
}

data, ci, err := r.ReadPacketData()
...

Write supports only little endian, enhanced packets blocks, interface blocks, and interface statistics blocks. The same options as with writing are supported. Interface timestamp resolution is fixed to 10^-9s to match time.Time. Any other values are ignored. Upon creating a writer, a section, and an interface block is automatically written. Additional interfaces can be added at any time. Since the writer uses a bufio.Writer internally, Flush must be called before closing the file! Have a look at NewNgWriterInterface for more advanced usage.

f, err := os.Create("somefile.pcapng")
if err != nil {
	...
}
defer f.Close()

r, err = NewNgWriter(f, layers.LinkTypeEthernet)
if err != nil {
	...
}
defer r.Flush()

err = r.WritePacket(ci, data)
...
Example (CaptureEthernet)
Output:

Index

Examples

Constants

View Source
const NgNoValue64 = math.MaxUint64

    NgNoValue64 is a placeholder for an empty numeric 64 bit value.

    Variables

    View Source
    var DefaultNgInterface = NgInterface{
    	Name:                "intf0",
    	OS:                  runtime.GOOS,
    	SnapLength:          0,
    	TimestampResolution: 9,
    }

      DefaultNgInterface contains default interface options used by NewWriter

      View Source
      var DefaultNgReaderOptions = NgReaderOptions{}

        DefaultNgReaderOptions provides sane defaults for a pcapng reader.

        View Source
        var DefaultNgWriterOptions = NgWriterOptions{
        	SectionInfo: NgSectionInfo{
        		Hardware:    runtime.GOARCH,
        		OS:          runtime.GOOS,
        		Application: "gopacket",
        	},
        }

          DefaultNgWriterOptions contain defaults for a pcapng writer used by NewWriter

          View Source
          var ErrNgLinkTypeMismatch = errors.New("Link type of current interface is different from first one")

            ErrNgLinkTypeMismatch gets returned if the link type of an interface is not the same as the link type from the first interface. This can only happen if ReaderOptions.ErrorOnMismatchingLinkType == true && ReaderOptions.WantMixedLinkType == false

            View Source
            var ErrNgVersionMismatch = errors.New("Unknown pcapng Version in Section Header")

              ErrNgVersionMismatch gets returned for unknown pcapng section versions. This can only happen if ReaderOptions.SkipUnknownVersion == false

              Functions

              This section is empty.

              Types

              type EthernetHandle

              type EthernetHandle struct {
              	// contains filtered or unexported fields
              }

                EthernetHandle holds shared buffers and file descriptor of af_packet socket

                func NewEthernetHandle

                func NewEthernetHandle(ifname string) (*EthernetHandle, error)

                  NewEthernetHandle implements pcap.OpenLive for network devices. If you want better performance have a look at github.com/google/gopacket/afpacket. SetCaptureLength can be used to limit the maximum capture length.

                  func (*EthernetHandle) Close

                  func (h *EthernetHandle) Close()

                    Close closes the underlying socket

                    func (*EthernetHandle) GetCaptureLength

                    func (h *EthernetHandle) GetCaptureLength() int

                      GetCaptureLength returns the maximum capture length

                      func (*EthernetHandle) LocalAddr

                      func (h *EthernetHandle) LocalAddr() net.HardwareAddr

                        LocalAddr returns the local network address

                        func (*EthernetHandle) ReadPacketData

                        func (h *EthernetHandle) ReadPacketData() ([]byte, gopacket.CaptureInfo, error)

                          ReadPacketData implements gopacket.PacketDataSource. If this was captured on a vlan, the vlan id will be in the AncillaryData[0]

                          func (*EthernetHandle) SetBPF

                          func (h *EthernetHandle) SetBPF(filter []bpf.RawInstruction) error

                            SetBPF attaches the given BPF filter to the socket. After this, only the packets for which the filter returns a value greater than zero are received. If a filter was already attached, it will be overwritten. To remove the filter, provide an empty slice.

                            func (*EthernetHandle) SetCaptureLength

                            func (h *EthernetHandle) SetCaptureLength(len int) error

                              SetCaptureLength sets the maximum capture length to the given value

                              func (*EthernetHandle) SetPromiscuous

                              func (h *EthernetHandle) SetPromiscuous(b bool) error

                                SetPromiscuous sets promiscous mode to the required value. If it is enabled, traffic not destined for the interface will also be captured.

                                func (*EthernetHandle) Stats

                                func (h *EthernetHandle) Stats() (*unix.TpacketStats, error)

                                  Stats returns number of packets and dropped packets. This will be the number of packets/dropped packets since the last call to stats (not the cummulative sum!).

                                  func (*EthernetHandle) ZeroCopyReadPacketData

                                  func (h *EthernetHandle) ZeroCopyReadPacketData() ([]byte, gopacket.CaptureInfo, error)

                                    ZeroCopyReadPacketData implements gopacket.ZeroCopyPacketDataSource. If this was captured on a vlan, the vlan id will be in the AncillaryData[0]. This function does not allocate memory. Beware that the next call to ZeroCopyReadPacketData will overwrite existing slices (returned data AND AncillaryData)! Due to shared buffers this must not be called concurrently

                                    type NgInterface

                                    type NgInterface struct {
                                    	// Name is the name of the interface. This value might be empty if this option is missing.
                                    	Name string
                                    	// Comment can be an arbitrary comment. This value might be empty if this option is missing.
                                    	Comment string
                                    	// Description is a description of the interface. This value might be empty if this option is missing.
                                    	Description string
                                    	// Filter is the filter used during packet capture. This value might be empty if this option is missing.
                                    	Filter string
                                    	// OS is the operating system this interface was controlled by. This value might be empty if this option is missing.
                                    	OS string
                                    	// LinkType is the linktype of the interface.
                                    	LinkType layers.LinkType
                                    	// TimestampResolution is the timestamp resolution of the packets in the pcapng file belonging to this interface.
                                    	TimestampResolution NgResolution
                                    	// TimestampResolution is the timestamp offset in seconds of the packets in the pcapng file belonging to this interface.
                                    	TimestampOffset uint64
                                    	// SnapLength is the maximum packet length captured by this interface. 0 for unlimited
                                    	SnapLength uint32
                                    	// Statistics holds the interface statistics
                                    	Statistics NgInterfaceStatistics
                                    	// contains filtered or unexported fields
                                    }

                                      NgInterface holds all the information of a pcapng interface.

                                      func (NgInterface) Resolution

                                      func (i NgInterface) Resolution() gopacket.TimestampResolution

                                        Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution.

                                        type NgInterfaceStatistics

                                        type NgInterfaceStatistics struct {
                                        	// LastUpdate is the last time the statistics were updated.
                                        	LastUpdate time.Time
                                        	// StartTime is the time packet capture started on this interface. This value might be zero if this option is missing.
                                        	StartTime time.Time
                                        	// EndTime is the time packet capture ended on this interface This value might be zero if this option is missing.
                                        	EndTime time.Time
                                        	// Comment can be an arbitrary comment. This value might be empty if this option is missing.
                                        	Comment string
                                        	// PacketsReceived are the number of received packets. This value might be NoValue64 if this option is missing.
                                        	PacketsReceived uint64
                                        	// PacketsReceived are the number of received packets. This value might be NoValue64 if this option is missing.
                                        	PacketsDropped uint64
                                        }

                                          NgInterfaceStatistics hold the statistic for an interface at a single point in time. These values are already supposed to be accumulated. Most pcapng files contain this information at the end of the file/section.

                                          type NgReader

                                          type NgReader struct {
                                          	// contains filtered or unexported fields
                                          }

                                            NgReader wraps an underlying bufio.NgReader to read packet data in pcapng.

                                            func NewNgReader

                                            func NewNgReader(r io.Reader, options NgReaderOptions) (*NgReader, error)

                                              NewNgReader initializes a new writer, reads the first section header, and if necessary according to the options the first interface.

                                              func (*NgReader) Interface

                                              func (r *NgReader) Interface(i int) (NgInterface, error)

                                                Interface returns interface information and statistics of interface with the given id.

                                                func (*NgReader) LinkType

                                                func (r *NgReader) LinkType() layers.LinkType

                                                  LinkType returns the link type of the first interface, as a layers.LinkType. This is only valid, if WantMixedLinkType is false.

                                                  func (*NgReader) NInterfaces

                                                  func (r *NgReader) NInterfaces() int

                                                    NInterfaces returns the current number of interfaces.

                                                    func (*NgReader) ReadPacketData

                                                    func (r *NgReader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

                                                      ReadPacketData returns the next packet available from this data source. If WantMixedLinkType is true, ci.AncillaryData[0] contains the link type.

                                                      func (*NgReader) Resolution

                                                      func (r *NgReader) Resolution() gopacket.TimestampResolution

                                                        Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution.

                                                        func (*NgReader) SectionInfo

                                                        func (r *NgReader) SectionInfo() NgSectionInfo

                                                          SectionInfo returns information about the current section.

                                                          func (*NgReader) SkipSection

                                                          func (r *NgReader) SkipSection() error

                                                            SkipSection skips the contents of the rest of the current section and reads the next section header.

                                                            func (*NgReader) ZeroCopyReadPacketData

                                                            func (r *NgReader) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

                                                              ZeroCopyReadPacketData returns the next packet available from this data source. If WantMixedLinkType is true, ci.AncillaryData[0] contains the link type. Warning: Like data, ci.AncillaryData is also reused and overwritten on the next call to ZeroCopyReadPacketData.

                                                              It is not true zero copy, as data is still copied from the underlying reader. However, this method avoids allocating heap memory for every packet.

                                                              type NgReaderOptions

                                                              type NgReaderOptions struct {
                                                              	// WantMixedLinkType enables reading a pcapng file containing multiple interfaces with varying link types. If false all link types must match, which is the libpcap behaviour and LinkType returns the link type of the first interface.
                                                              	// If true the link type of the packet is also exposed via ci.AncillaryData[0].
                                                              	WantMixedLinkType bool
                                                              	// ErrorOnMismatchingLinkType enables returning an error if a packet with a link type not matching the first interface is encountered and WantMixedLinkType == false.
                                                              	// If false packets those packets are just silently ignored, which is the libpcap behaviour.
                                                              	ErrorOnMismatchingLinkType bool
                                                              	// SkipUnknownVersion enables automatically skipping sections with an unknown version, which is recommended by the pcapng standard. Otherwise ErrVersionMismatch is returned.
                                                              	SkipUnknownVersion bool
                                                              	// SectionEndCallback gets called at the end of a section (execept for the last section, which is ends on EOF). The current list of interfaces and additional section information is provided.
                                                              	// This is a good way to read interface statistics.
                                                              	SectionEndCallback func([]NgInterface, NgSectionInfo)
                                                              	// StatisticsCallback is called when a interface statistics block is read. The interface id and the read statistics are provided.
                                                              	StatisticsCallback func(int, NgInterfaceStatistics)
                                                              }

                                                                NgReaderOptions holds options for reading a pcapng file

                                                                type NgResolution

                                                                type NgResolution uint8

                                                                  NgResolution represents a pcapng timestamp resolution

                                                                  func (NgResolution) Binary

                                                                  func (r NgResolution) Binary() bool

                                                                    Binary returns true if the timestamp resolution is a negative power of two. Otherwise NgResolution is a negative power of 10.

                                                                    func (NgResolution) Exponent

                                                                    func (r NgResolution) Exponent() uint8

                                                                      Exponent returns the negative exponent of the resolution.

                                                                      func (NgResolution) ToTimestampResolution

                                                                      func (r NgResolution) ToTimestampResolution() (ret gopacket.TimestampResolution)

                                                                        ToTimestampResolution converts an NgResolution to a gopaket.TimestampResolution

                                                                        type NgSectionInfo

                                                                        type NgSectionInfo struct {
                                                                        	// Hardware is the hardware this file was generated on. This value might be empty if this option is missing.
                                                                        	Hardware string
                                                                        	// OS is the operating system this file was generated on. This value might be empty if this option is missing.
                                                                        	OS string
                                                                        	// Application is the user space application this file was generated with. This value might be empty if this option is missing.
                                                                        	Application string
                                                                        	// Comment can be an arbitrary comment. This value might be empty if this option is missing.
                                                                        	Comment string
                                                                        }

                                                                          NgSectionInfo contains additional information of a pcapng section

                                                                          type NgWriter

                                                                          type NgWriter struct {
                                                                          	// contains filtered or unexported fields
                                                                          }

                                                                            NgWriter holds the internal state of a pcapng file writer. Internally a bufio.NgWriter is used, therefore Flush must be called before closing the underlying file.

                                                                            func NewNgWriter

                                                                            func NewNgWriter(w io.Writer, linkType layers.LinkType) (*NgWriter, error)

                                                                              NewNgWriter initializes and returns a new writer. Additionally, one section and one interface (without statistics) is written to the file. Interface and section options are used from DefaultNgInterface and DefaultNgWriterOptions. Flush must be called before the file is closed, or if eventual unwritten information should be written out to the storage device.

                                                                              Written files are in little endian format. Interface timestamp resolution is fixed to 9 (to match time.Time).

                                                                              func NewNgWriterInterface

                                                                              func NewNgWriterInterface(w io.Writer, intf NgInterface, options NgWriterOptions) (*NgWriter, error)

                                                                                NewNgWriterInterface initializes and returns a new writer. Additionally, one section and one interface (without statistics) is written to the file. Flush must be called before the file is closed, or if eventual unwritten information should be written out to the storage device.

                                                                                Written files are in little endian format. Interface timestamp resolution is fixed to 9 (to match time.Time).

                                                                                func (*NgWriter) AddInterface

                                                                                func (w *NgWriter) AddInterface(intf NgInterface) (id int, err error)

                                                                                  AddInterface adds the specified interface to the file, excluding statistics. Interface timestamp resolution is fixed to 9 (to match time.Time). Empty values are not written.

                                                                                  func (*NgWriter) Flush

                                                                                  func (w *NgWriter) Flush() error

                                                                                    Flush writes out buffered data to the storage media. Must be called before closing the underlying file.

                                                                                    func (*NgWriter) WriteInterfaceStats

                                                                                    func (w *NgWriter) WriteInterfaceStats(intf int, stats NgInterfaceStatistics) error

                                                                                      WriteInterfaceStats writes the given interface statistics for the given interface id to the file. Empty values are not written.

                                                                                      func (*NgWriter) WritePacket

                                                                                      func (w *NgWriter) WritePacket(ci gopacket.CaptureInfo, data []byte) error

                                                                                        WritePacket writes out packet with the given data and capture info. The given InterfaceIndex must already be added to the file. InterfaceIndex 0 is automatically added by the NewWriter* methods.

                                                                                        type NgWriterOptions

                                                                                        type NgWriterOptions struct {
                                                                                        	// SectionInfo will be written to the section header
                                                                                        	SectionInfo NgSectionInfo
                                                                                        }

                                                                                          NgWriterOptions holds options for creating a pcapng file

                                                                                          type Reader

                                                                                          type Reader struct {
                                                                                          	// contains filtered or unexported fields
                                                                                          }

                                                                                            Reader wraps an underlying io.Reader to read packet data in PCAP format. See http://wiki.wireshark.org/Development/LibpcapFileFormat for information on the file format.

                                                                                            We currenty read v2.4 file format with nanosecond and microsecdond timestamp resolution in little-endian and big-endian encoding.

                                                                                            If the PCAP data is gzip compressed it is transparently uncompressed by wrapping the given io.Reader with a gzip.Reader.

                                                                                            func NewReader

                                                                                            func NewReader(r io.Reader) (*Reader, error)

                                                                                              NewReader returns a new reader object, for reading packet data from the given reader. The reader must be open and header data is read from it at this point. If the file format is not supported an error is returned

                                                                                              // Create new reader:
                                                                                              f, _ := os.Open("/tmp/file.pcap")
                                                                                              defer f.Close()
                                                                                              r, err := NewReader(f)
                                                                                              data, ci, err := r.ReadPacketData()
                                                                                              

                                                                                              func (*Reader) LinkType

                                                                                              func (r *Reader) LinkType() layers.LinkType

                                                                                                LinkType returns network, as a layers.LinkType.

                                                                                                func (*Reader) ReadPacketData

                                                                                                func (r *Reader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

                                                                                                  ReadPacketData reads next packet from file.

                                                                                                  func (*Reader) Resolution

                                                                                                  func (r *Reader) Resolution() gopacket.TimestampResolution

                                                                                                    Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution.

                                                                                                    func (*Reader) SetSnaplen

                                                                                                    func (r *Reader) SetSnaplen(newSnaplen uint32)

                                                                                                      SetSnaplen sets the snapshot length of the capture file.

                                                                                                      This is useful when a pcap file contains packets bigger than then snaplen. Pcapgo will error when reading packets bigger than snaplen, then it dumps those packets and reads the next 16 bytes, which are part of the "faulty" packet's payload, but pcapgo thinks it's the next header, which is probably also faulty because it's not really a packet header. This can lead to a lot of faulty reads.

                                                                                                      The SetSnaplen function can be used to set a bigger snaplen to prevent those read errors.

                                                                                                      This snaplen situation can happen when a pcap writer doesn't truncate packets to the snaplen size while writing packets to file. E.g. In Python, dpkt.pcap.Writer sets snaplen by default to 1500 (https://dpkt.readthedocs.io/en/latest/api/api_auto.html#dpkt.pcap.Writer) but doesn't enforce this when writing packets (https://dpkt.readthedocs.io/en/latest/_modules/dpkt/pcap.html#Writer.writepkt). When reading, tools like tcpdump, tcpslice, mergecap and wireshark ignore the snaplen and use their own defined snaplen. E.g. When reading packets, tcpdump defines MAXIMUM_SNAPLEN (https://github.com/the-tcpdump-group/tcpdump/blob/6e80fcdbe9c41366df3fa244ffe4ac8cce2ab597/netdissect.h#L290) and uses it (https://github.com/the-tcpdump-group/tcpdump/blob/66384fa15b04b47ad08c063d4728df3b9c1c0677/print.c#L343-L358).

                                                                                                      For further reading:

                                                                                                      - https://github.com/the-tcpdump-group/tcpdump/issues/389
                                                                                                      - https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8808
                                                                                                      - https://www.wireshark.org/lists/wireshark-dev/201307/msg00061.html
                                                                                                      - https://github.com/wireshark/wireshark/blob/bfd51199e707c1d5c28732be34b44a9ee8a91cd8/wiretap/pcap-common.c#L723-L742
                                                                                                        - https://github.com/wireshark/wireshark/blob/f07fb6cdfc0904905627707b88450054e921f092/wiretap/libpcap.c#L592-L598
                                                                                                        - https://github.com/wireshark/wireshark/blob/f07fb6cdfc0904905627707b88450054e921f092/wiretap/libpcap.c#L714-L727
                                                                                                      - https://github.com/the-tcpdump-group/tcpdump/commit/d033c1bc381c76d13e4aface97a4f4ec8c3beca2
                                                                                                      - https://github.com/the-tcpdump-group/tcpdump/blob/88e87cb2cb74c5f939792171379acd9e0efd8b9a/netdissect.h#L263-L290
                                                                                                      

                                                                                                      func (*Reader) Snaplen

                                                                                                      func (r *Reader) Snaplen() uint32

                                                                                                        Snaplen returns the snapshot length of the capture file.

                                                                                                        func (*Reader) String

                                                                                                        func (r *Reader) String() string

                                                                                                          Reader formater

                                                                                                          func (*Reader) ZeroCopyReadPacketData

                                                                                                          func (r *Reader) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

                                                                                                            ZeroCopyReadPacketData reads next packet from file. The data buffer is owned by the Reader, and each call to ZeroCopyReadPacketData invalidates data returned by the previous one.

                                                                                                            It is not true zero copy, as data is still copied from the underlying reader. However, this method avoids allocating heap memory for every packet.

                                                                                                            type SnoopReader

                                                                                                            type SnoopReader struct {
                                                                                                            	// contains filtered or unexported fields
                                                                                                            }

                                                                                                              SnoopReader wraps an underlying io.SnoopReader to read packet data in SNOOP format. See https://tools.ietf.org/html/rfc1761 for information on the file format. We currenty read v2 file format and convert microsecond to nanoseconds byte order in big-endian encoding.

                                                                                                              func NewSnoopReader

                                                                                                              func NewSnoopReader(r io.Reader) (*SnoopReader, error)

                                                                                                                NewSnoopReader returns a new SnoopReader object, for reading packet data from the given SnoopReader. The SnoopReader must be open and header data is read from it at this point. If the file format is not supported an error is returned

                                                                                                                func (*SnoopReader) LinkType

                                                                                                                func (r *SnoopReader) LinkType() (*layers.LinkType, error)

                                                                                                                  LinkType return the mapped gopacket LinkType

                                                                                                                  func (*SnoopReader) ReadPacketData

                                                                                                                  func (r *SnoopReader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

                                                                                                                    ReadPacketData reads next packet data.

                                                                                                                    func (*SnoopReader) ZeroCopyReadPacketData

                                                                                                                    func (r *SnoopReader) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)

                                                                                                                      ZeroCopyReadPacketData reads next packet data. The data buffer is owned by the SnoopReader, and each call to ZeroCopyReadPacketData invalidates data returned by the previous one.

                                                                                                                      It is not true zero copy, as data is still copied from the underlying SnoopReader. However, this method avoids allocating heap memory for every packet.

                                                                                                                      type Writer

                                                                                                                      type Writer struct {
                                                                                                                      	// contains filtered or unexported fields
                                                                                                                      }

                                                                                                                        Writer wraps an underlying io.Writer to write packet data in PCAP format. See http://wiki.wireshark.org/Development/LibpcapFileFormat for information on the file format.

                                                                                                                        For those that care, we currently write v2.4 files with nanosecond or microsecond timestamp resolution and little-endian encoding.

                                                                                                                        func NewWriter

                                                                                                                        func NewWriter(w io.Writer) *Writer

                                                                                                                          NewWriter returns a new writer object, for writing packet data out to the given writer. If this is a new empty writer (as opposed to an append), you must call WriteFileHeader before WritePacket. Packet timestamps are written witn microsecond precision.

                                                                                                                          // Write a new file:
                                                                                                                          f, _ := os.Create("/tmp/file.pcap")
                                                                                                                          w := pcapgo.NewWriter(f)
                                                                                                                          w.WriteFileHeader(65536, layers.LinkTypeEthernet)  // new file, must do this.
                                                                                                                          w.WritePacket(gopacket.CaptureInfo{...}, data1)
                                                                                                                          f.Close()
                                                                                                                          // Append to existing file (must have same snaplen and linktype)
                                                                                                                          f2, _ := os.OpenFile("/tmp/file.pcap", os.O_APPEND, 0700)
                                                                                                                          w2 := pcapgo.NewWriter(f2)
                                                                                                                          // no need for file header, it's already written.
                                                                                                                          w2.WritePacket(gopacket.CaptureInfo{...}, data2)
                                                                                                                          f2.Close()
                                                                                                                          

                                                                                                                          func NewWriterNanos

                                                                                                                          func NewWriterNanos(w io.Writer) *Writer

                                                                                                                            NewWriterNanos returns a new writer object, for writing packet data out to the given writer. If this is a new empty writer (as opposed to an append), you must call WriteFileHeader before WritePacket. Packet timestamps are written with nanosecond precision.

                                                                                                                            // Write a new file:
                                                                                                                            f, _ := os.Create("/tmp/file.pcap")
                                                                                                                            w := pcapgo.NewWriterNanos(f)
                                                                                                                            w.WriteFileHeader(65536, layers.LinkTypeEthernet)  // new file, must do this.
                                                                                                                            w.WritePacket(gopacket.CaptureInfo{...}, data1)
                                                                                                                            f.Close()
                                                                                                                            // Append to existing file (must have same snaplen and linktype)
                                                                                                                            f2, _ := os.OpenFile("/tmp/fileNano.pcap", os.O_APPEND, 0700)
                                                                                                                            w2 := pcapgo.NewWriter(f2)
                                                                                                                            // no need for file header, it's already written.
                                                                                                                            w2.WritePacket(gopacket.CaptureInfo{...}, data2)
                                                                                                                            f2.Close()
                                                                                                                            

                                                                                                                            func (*Writer) WriteFileHeader

                                                                                                                            func (w *Writer) WriteFileHeader(snaplen uint32, linktype layers.LinkType) error

                                                                                                                              WriteFileHeader writes a file header out to the writer. This must be called exactly once per output.

                                                                                                                              func (*Writer) WritePacket

                                                                                                                              func (w *Writer) WritePacket(ci gopacket.CaptureInfo, data []byte) error

                                                                                                                                WritePacket writes the given packet data out to the file.