Documentation

Overview

Package pcap allows users of gopacket to read packets off the wire or from pcap files.

This package is meant to be used with its parent, http://github.com/google/gopacket, although it can also be used independently if you just want to get packet data from the wire.

Depending on libpcap version, os support, or file timestamp resolution, nanosecond resolution is used for the internal timestamps. Returned timestamps are always scaled to nanosecond resolution due to the usage of time.Time. libpcap must be at least version 1.5 to support nanosecond timestamps. OpenLive supports only microsecond resolution.

Reading PCAP Files

The following code can be used to read in data from a pcap file.

if handle, err := pcap.OpenOffline("/path/to/my/file"); err != nil {
  panic(err)
} else {
  packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
  for packet := range packetSource.Packets() {
    handlePacket(packet)  // Do something with a packet here.
  }
}

Reading Live Packets

The following code can be used to read in data from a live device, in this case "eth0". Be aware, that OpenLive only supports microsecond resolution.

if handle, err := pcap.OpenLive("eth0", 1600, true, pcap.BlockForever); err != nil {
  panic(err)
} else if err := handle.SetBPFFilter("tcp and port 80"); err != nil {  // optional
  panic(err)
} else {
  packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
  for packet := range packetSource.Packets() {
    handlePacket(packet)  // Do something with a packet here.
  }
}

Inactive Handles

Newer PCAP functionality requires the concept of an 'inactive' PCAP handle. Instead of constantly adding new arguments to pcap_open_live, users now call pcap_create to create a handle, set it up with a bunch of optional function calls, then call pcap_activate to activate it. This library mirrors that mechanism, for those that want to expose/use these new features:

inactive, err := pcap.NewInactiveHandle(deviceName)
if err != nil {
  log.Fatal(err)
}
defer inactive.CleanUp()

// Call various functions on inactive to set it up the way you'd like:
if err = inactive.SetTimeout(time.Minute); err != nil {
  log.Fatal(err)
} else if err = inactive.SetTimestampSource("foo"); err != nil {
  log.Fatal(err)
}

// Finally, create the actual handle by calling Activate:
handle, err := inactive.Activate()  // after this, inactive is no longer valid
if err != nil {
  log.Fatal(err)
}
defer handle.Close()

// Now use your handle as you see fit.

PCAP Timeouts

pcap.OpenLive and pcap.SetTimeout both take timeouts. If you don't care about timeouts, just pass in BlockForever, which should do what you expect with minimal fuss.

A timeout of 0 is not recommended. Some platforms, like Macs (http://www.manpages.info/macosx/pcap.3.html) say:

The read timeout is used to arrange that the read not necessarily return
immediately when a packet is seen, but that it wait for some amount of time
to allow more packets to arrive and to read multiple packets from the OS
kernel in one operation.

This means that if you only capture one packet, the kernel might decide to wait 'timeout' for more packets to batch with it before returning. A timeout of 0, then, means 'wait forever for more packets', which is... not good.

To get around this, we've introduced the following behavior: if a negative timeout is passed in, we set the positive timeout in the handle, then loop internally in ReadPacketData/ZeroCopyReadPacketData when we see timeout errors.

PCAP File Writing

This package does not implement PCAP file writing. However, gopacket/pcapgo does! Look there if you'd like to write PCAP files.

Note For Windows Users

gopacket can use winpcap or npcap. If both are installed at the same time, npcap is preferred. Make sure the right windows service is loaded (npcap for npcap and npf for winpcap).

Index

Examples

Constants

View Source
const (
	DirectionIn    = Direction(pcapDIN)
	DirectionOut   = Direction(pcapDOUT)
	DirectionInOut = Direction(pcapDINOUT)
)

    Direction values for Handle.SetDirection.

    View Source
    const BlockForever = -time.Millisecond * 10

      BlockForever causes it to block forever waiting for packets, when passed into SetTimeout or OpenLive, while still returning incoming packets to userland relatively quickly.

      View Source
      const ErrNotActive = pcapErrorNotActivated

        ErrNotActive is returned if handle is not activated

        View Source
        const MaxBpfInstructions = 4096

          MaxBpfInstructions is the maximum number of BPF instructions supported (BPF_MAXINSNS), taken from Linux kernel: include/uapi/linux/bpf_common.h

          https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf_common.h

          Variables

          View Source
          var CannotSetRFMon = errors.New("Cannot set rfmon for this handle")

            CannotSetRFMon is returned by SetRFMon if the handle does not allow setting RFMon because pcap_can_set_rfmon returns 0.

            Functions

            func DatalinkNameToVal

            func DatalinkNameToVal(name string) int

              DatalinkNameToVal returns pcap_datalink_name_to_val as int

              func DatalinkValToDescription

              func DatalinkValToDescription(dlt int) string

                DatalinkValToDescription returns pcap_datalink_val_to_description as string

                func DatalinkValToName

                func DatalinkValToName(dlt int) string

                  DatalinkValToName returns pcap_datalink_val_to_name as string

                  func Version

                  func Version() string

                    Version returns pcap_lib_version.

                    Types

                    type BPF

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

                      BPF is a compiled filter program, useful for offline packet matching.

                      Example
                      Output:
                      
                      SYN packet
                      SYN/ACK packet
                      SYN flag not set
                      SYN flag not set
                      SYN flag not set
                      SYN flag not set
                      SYN flag not set
                      SYN flag not set
                      SYN flag not set
                      SYN flag not set
                      

                      func NewBPF

                      func NewBPF(linkType layers.LinkType, captureLength int, expr string) (*BPF, error)

                        NewBPF allows to create a BPF without requiring an existing handle. This allows to match packets obtained from a-non GoPacket capture source to be matched.

                        buf := make([]byte, MaxFrameSize)
                        bpfi, _ := pcap.NewBPF(layers.LinkTypeEthernet, MaxFrameSize, "icmp")
                        n, _ := someIO.Read(buf)
                        ci := gopacket.CaptureInfo{CaptureLength: n, Length: n}
                        if bpfi.Matches(ci, buf) {
                        	doSomething()
                        }
                        

                        func (*BPF) Matches

                        func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool

                          Matches returns true if the given packet data matches this filter.

                          func (*BPF) String

                          func (b *BPF) String() string

                            String returns the original string this BPF filter was compiled from.

                            type BPFInstruction

                            type BPFInstruction struct {
                            	Code uint16
                            	Jt   uint8
                            	Jf   uint8
                            	K    uint32
                            }

                              BPFInstruction is a byte encoded structure holding a BPF instruction

                              func CompileBPFFilter

                              func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) ([]BPFInstruction, error)

                                CompileBPFFilter compiles and returns a BPF filter with given a link type and capture length.

                                type Datalink struct {
                                	Name        string
                                	Description string
                                }

                                  Datalink describes the datalink

                                  type Direction

                                  type Direction uint8

                                    Direction is used by Handle.SetDirection.

                                    type Handle

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

                                      Handle provides a connection to a pcap handle, allowing users to read packets off the wire (Next), inject packets onto the wire (Inject), and perform a number of other functions to affect and understand packet output.

                                      Handles are already pcap_activate'd

                                      func OpenLive

                                      func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error)

                                        OpenLive opens a device and returns a *Handle. It takes as arguments the name of the device ("eth0"), the maximum size to read for each packet (snaplen), whether to put the interface in promiscuous mode, and a timeout. Warning: this function supports only microsecond timestamps. For nanosecond resolution use an InactiveHandle.

                                        See the package documentation for important details regarding 'timeout'.

                                        func OpenOffline

                                        func OpenOffline(file string) (handle *Handle, err error)

                                          OpenOffline opens a file and returns its contents as a *Handle. Depending on libpcap support and on the timestamp resolution used in the file, nanosecond or microsecond resolution is used internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used to query the actual resolution used.

                                          func OpenOfflineFile

                                          func OpenOfflineFile(file *os.File) (handle *Handle, err error)

                                            OpenOfflineFile returns contents of input file as a *Handle. Depending on libpcap support and on the timestamp resolution used in the file, nanosecond or microsecond resolution is used internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used to query the actual resolution used.

                                            func (*Handle) Close

                                            func (p *Handle) Close()

                                              Close closes the underlying pcap handle.

                                              func (*Handle) CompileBPFFilter

                                              func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error)

                                                CompileBPFFilter compiles and returns a BPF filter for the pcap handle.

                                                func (*Handle) Error

                                                func (p *Handle) Error() error

                                                  Error returns the current error associated with a pcap handle (pcap_geterr).

                                                  func (*Handle) LinkType

                                                  func (p *Handle) LinkType() layers.LinkType

                                                    LinkType returns pcap_datalink, as a layers.LinkType.

                                                    func (p *Handle) ListDataLinks() (datalinks []Datalink, err error)

                                                      ListDataLinks obtains a list of all possible data link types supported for an interface.

                                                      func (*Handle) NewBPF

                                                      func (p *Handle) NewBPF(expr string) (*BPF, error)

                                                        NewBPF compiles the given string into a new filter program.

                                                        BPF filters need to be created from activated handles, because they need to know the underlying link type to correctly compile their offsets.

                                                        func (*Handle) NewBPFInstructionFilter

                                                        func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error)

                                                        NewBPFInstructionFilter sets the given BPFInstructions as new filter program.

                                                        More details see func SetBPFInstructionFilter

                                                        BPF filters need to be created from activated handles, because they need to know the underlying link type to correctly compile their offsets.

                                                        func (*Handle) ReadPacketData

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

                                                          ReadPacketData returns the next packet read from the pcap handle, along with an error code associated with that packet. If the packet is read successfully, the returned error is nil.

                                                          func (*Handle) Resolution

                                                          func (p *Handle) Resolution() gopacket.TimestampResolution

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

                                                            func (*Handle) SetBPFFilter

                                                            func (p *Handle) SetBPFFilter(expr string) (err error)

                                                              SetBPFFilter compiles and sets a BPF filter for the pcap handle.

                                                              func (*Handle) SetBPFInstructionFilter

                                                              func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err error)

                                                                SetBPFInstructionFilter may be used to apply a filter in BPF asm byte code format.

                                                                Simplest way to generate BPF asm byte code is with tcpdump:

                                                                tcpdump -dd 'udp'
                                                                

                                                                The output may be used directly to add a filter, e.g.:

                                                                    bpfInstructions := []pcap.BpfInstruction{
                                                                			{0x28, 0, 0, 0x0000000c},
                                                                			{0x15, 0, 9, 0x00000800},
                                                                			{0x30, 0, 0, 0x00000017},
                                                                			{0x15, 0, 7, 0x00000006},
                                                                			{0x28, 0, 0, 0x00000014},
                                                                			{0x45, 5, 0, 0x00001fff},
                                                                			{0xb1, 0, 0, 0x0000000e},
                                                                			{0x50, 0, 0, 0x0000001b},
                                                                			{0x54, 0, 0, 0x00000012},
                                                                			{0x15, 0, 1, 0x00000012},
                                                                			{0x6, 0, 0, 0x0000ffff},
                                                                			{0x6, 0, 0, 0x00000000},
                                                                		}
                                                                

                                                                An other posibility is to write the bpf code in bpf asm. Documentation: https://www.kernel.org/doc/Documentation/networking/filter.txt

                                                                To compile the code use bpf_asm from https://github.com/torvalds/linux/tree/master/tools/net

                                                                The following command may be used to convert bpf_asm output to c/go struct, usable for SetBPFFilterByte: bpf_asm -c tcp.bpf

                                                                func (*Handle) SetDirection

                                                                func (p *Handle) SetDirection(direction Direction) error

                                                                  SetDirection sets the direction for which packets will be captured.

                                                                  func (*Handle) SetLinkType

                                                                  func (p *Handle) SetLinkType(dlt layers.LinkType) error

                                                                    SetLinkType calls pcap_set_datalink on the pcap handle.

                                                                    func (*Handle) SnapLen

                                                                    func (p *Handle) SnapLen() int

                                                                      SnapLen returns the snapshot length

                                                                      func (*Handle) Stats

                                                                      func (p *Handle) Stats() (stat *Stats, err error)

                                                                        Stats returns statistics on the underlying pcap handle.

                                                                        func (*Handle) WritePacketData

                                                                        func (p *Handle) WritePacketData(data []byte) (err error)

                                                                          WritePacketData calls pcap_sendpacket, injecting the given data into the pcap handle.

                                                                          func (*Handle) ZeroCopyReadPacketData

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

                                                                            ZeroCopyReadPacketData reads the next packet off the wire, and returns its data. The slice returned by ZeroCopyReadPacketData points to bytes owned by the the Handle. Each call to ZeroCopyReadPacketData invalidates any data previously returned by ZeroCopyReadPacketData. Care must be taken not to keep pointers to old bytes when using ZeroCopyReadPacketData... if you need to keep data past the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies the bytes into a new buffer for you.

                                                                            data1, _, _ := handle.ZeroCopyReadPacketData()
                                                                            // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around.
                                                                            data2, _, _ := handle.ZeroCopyReadPacketData()  // invalidates bytes in data1
                                                                            

                                                                            type InactiveHandle

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

                                                                              InactiveHandle allows you to call pre-pcap_activate functions on your pcap handle to set it up just the way you'd like.

                                                                              func NewInactiveHandle

                                                                              func NewInactiveHandle(device string) (*InactiveHandle, error)

                                                                                NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle. Callers of NewInactiveHandle should immediately defer 'CleanUp', as in:

                                                                                inactive := NewInactiveHandle("eth0")
                                                                                defer inactive.CleanUp()
                                                                                

                                                                                func (*InactiveHandle) Activate

                                                                                func (p *InactiveHandle) Activate() (*Handle, error)

                                                                                  Activate activates the handle. The current InactiveHandle becomes invalid and all future function calls on it will fail.

                                                                                  func (*InactiveHandle) CleanUp

                                                                                  func (p *InactiveHandle) CleanUp()

                                                                                    CleanUp cleans up any stuff left over from a successful or failed building of a handle.

                                                                                    func (*InactiveHandle) Error

                                                                                    func (p *InactiveHandle) Error() error

                                                                                      Error returns the current error associated with a pcap handle (pcap_geterr).

                                                                                      func (*InactiveHandle) SetBufferSize

                                                                                      func (p *InactiveHandle) SetBufferSize(bufferSize int) error

                                                                                        SetBufferSize sets the buffer size (in bytes) of the handle.

                                                                                        func (*InactiveHandle) SetImmediateMode

                                                                                        func (p *InactiveHandle) SetImmediateMode(mode bool) error

                                                                                          SetImmediateMode sets (or unsets) the immediate mode of the handle. In immediate mode, packets are delivered to the application as soon as they arrive. In other words, this overrides SetTimeout.

                                                                                          func (*InactiveHandle) SetPromisc

                                                                                          func (p *InactiveHandle) SetPromisc(promisc bool) error

                                                                                            SetPromisc sets the handle to either be promiscuous (capture packets unrelated to this host) or not.

                                                                                            func (*InactiveHandle) SetRFMon

                                                                                            func (p *InactiveHandle) SetRFMon(monitor bool) error

                                                                                              SetRFMon turns on radio monitoring mode, similar to promiscuous mode but for wireless networks. If this mode is enabled, the interface will not need to associate with an access point before it can receive traffic.

                                                                                              func (*InactiveHandle) SetSnapLen

                                                                                              func (p *InactiveHandle) SetSnapLen(snaplen int) error

                                                                                                SetSnapLen sets the snap length (max bytes per packet to capture).

                                                                                                func (*InactiveHandle) SetTimeout

                                                                                                func (p *InactiveHandle) SetTimeout(timeout time.Duration) error

                                                                                                  SetTimeout sets the read timeout for the handle.

                                                                                                  See the package documentation for important details regarding 'timeout'.

                                                                                                  func (*InactiveHandle) SetTimestampSource

                                                                                                  func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error

                                                                                                    SetTimestampSource sets the type of timestamp generator PCAP uses when attaching timestamps to packets.

                                                                                                    func (*InactiveHandle) SupportedTimestamps

                                                                                                    func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource)

                                                                                                      SupportedTimestamps returns a list of supported timstamp types for this handle.

                                                                                                      type Interface

                                                                                                      type Interface struct {
                                                                                                      	Name        string
                                                                                                      	Description string
                                                                                                      	Flags       uint32
                                                                                                      	Addresses   []InterfaceAddress
                                                                                                      }

                                                                                                        Interface describes a single network interface on a machine.

                                                                                                        func FindAllDevs

                                                                                                        func FindAllDevs() (ifs []Interface, err error)

                                                                                                          FindAllDevs attempts to enumerate all interfaces on the current machine.

                                                                                                          type InterfaceAddress

                                                                                                          type InterfaceAddress struct {
                                                                                                          	IP        net.IP
                                                                                                          	Netmask   net.IPMask // Netmask may be nil if we were unable to retrieve it.
                                                                                                          	Broadaddr net.IP     // Broadcast address for this IP may be nil
                                                                                                          	P2P       net.IP     // P2P destination address for this IP may be nil
                                                                                                          }

                                                                                                            InterfaceAddress describes an address associated with an Interface. Currently, it's IPv4/6 specific.

                                                                                                            type NextError

                                                                                                            type NextError int32

                                                                                                              NextError is the return code from a call to Next.

                                                                                                              const (
                                                                                                              	NextErrorOk             NextError = 1
                                                                                                              	NextErrorTimeoutExpired NextError = 0
                                                                                                              	NextErrorReadError      NextError = -1
                                                                                                              	// NextErrorNoMorePackets is returned when reading from a file (OpenOffline) and
                                                                                                              	// EOF is reached.  When this happens, Next() returns io.EOF instead of this.
                                                                                                              	NextErrorNoMorePackets NextError = -2
                                                                                                              	NextErrorNotActivated  NextError = -3
                                                                                                              )

                                                                                                                NextError values.

                                                                                                                func (NextError) Error

                                                                                                                func (n NextError) Error() string

                                                                                                                  NextError implements the error interface.

                                                                                                                  type Stats

                                                                                                                  type Stats struct {
                                                                                                                  	PacketsReceived  int
                                                                                                                  	PacketsDropped   int
                                                                                                                  	PacketsIfDropped int
                                                                                                                  }

                                                                                                                    Stats contains statistics on how many packets were handled by a pcap handle, and what was done with those packets.

                                                                                                                    type TimestampSource

                                                                                                                    type TimestampSource int

                                                                                                                      TimestampSource tells PCAP which type of timestamp to use for packets.

                                                                                                                      func TimestampSourceFromString

                                                                                                                      func TimestampSourceFromString(s string) (TimestampSource, error)

                                                                                                                        TimestampSourceFromString translates a string into a timestamp type, case insensitive.

                                                                                                                        func (TimestampSource) String

                                                                                                                        func (t TimestampSource) String() string

                                                                                                                          String returns the timestamp type as a human-readable string.

                                                                                                                          Directories

                                                                                                                          Path Synopsis
                                                                                                                          This benchmark reads in file <tempdir>/gopacket_benchmark.pcap and measures the time it takes to decode all packets from that file.
                                                                                                                          This benchmark reads in file <tempdir>/gopacket_benchmark.pcap and measures the time it takes to decode all packets from that file.