pcap

package
v0.0.0-...-d09d505 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2020 License: BSD-3-Clause Imports: 14 Imported by: 0

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/tsg/gopacket, although it can also be used independently if you just want to get packet data from the wire.

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".

if handle, err := pcap.OpenLive("eth0", 1600, true, 0); 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.

Index

Examples

Constants

View Source
const BlockForever = -time.Millisecond * 10

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

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 NewPacketPoll

func NewPacketPoll(ptr *C.pcap_t, timeout C.int) *packetPoll

NewPacketPoll returns a new packetPoller if the pcap handle requires it in order to timeout effectively when no packets are received. This is only necessary when TPACKET_V3 interface is used to receive packets.

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
handle, err := OpenOffline("test_ethernet.pcap")
if err != nil {
	log.Fatal(err)
}
synack, err := handle.NewBPF("tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)")
if err != nil {
	log.Fatal(err)
}
syn, err := handle.NewBPF("tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn")
if err != nil {
	log.Fatal(err)
}
for {
	data, ci, err := handle.ReadPacketData()
	switch {
	case err == io.EOF:
		return
	case err != nil:
		log.Fatal(err)
	case synack.Matches(ci, data):
		fmt.Println("SYN/ACK packet")
	case syn.Matches(ci, data):
		fmt.Println("SYN packet")
	default:
		fmt.Println("SYN flag not set")
	}
}
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
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 (*BPF) BPF

func (b *BPF) BPF() C.struct_bpf_program

BPF returns the compiled BPF program.

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 Datalink struct {
	Name        string
	Description string
}

Datalink describes the datalink

type Direction

type Direction uint8

Direction is used by Handle.SetDirection.

const (
	DirectionIn    Direction = C.PCAP_D_IN
	DirectionOut   Direction = C.PCAP_D_OUT
	DirectionInOut Direction = C.PCAP_D_INOUT
)

type Dumper

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

Dumper can be used to write packet data to a file.

func (*Dumper) Close

func (d *Dumper) Close() (err error)

Closes the underling file.

func (*Dumper) Flush

func (d *Dumper) Flush() (err error)

Flushes the underling file to disk.

func (*Dumper) WritePacketData

func (d *Dumper) WritePacketData(data []byte, ci gopacket.CaptureInfo) (err error)

Writes a packet to the file. The return values of ReadPacketData can be passed to this function as arguments.

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 OpenDead

func OpenDead(linktype layers.LinkType, snaplen int32) (handle *Handle, _ error)

OpenDead creates a Pcap handle without having it attached to a device or to a file. It is typically used when just using the pcap package for compiling BPF code.

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.

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.

func (*Handle) Close

func (p *Handle) Close()

Close closes the underlying 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)

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) NewDumper

func (h *Handle) NewDumper(file string) (dumper *Dumper, err error)

Returns a Dumper read to write packets from the given pcap handler in the file given as parameter.

func (*Handle) ReadPacketData

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

NextError 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) SetBPFFilter

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

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

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) 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) 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
	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.

}

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
)

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 C.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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL