pfring

package
v0.0.0-...-abc4995 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2024 License: BSD-3-Clause Imports: 10 Imported by: 0

Documentation

Overview

Package pfring wraps the PF_RING C library for Go.

PF_RING is a high-performance packet capture library written by ntop.org (see http://www.ntop.org/products/pf_ring/). This library allows you to utilize the PF_RING library with gopacket to read packet data and decode it.

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.

Simple Example

This is probably the simplest code you can use to start getting packets through pfring:

 if ring, err := pfring.NewRing("eth0", 65536, pfring.FlagPromisc); err != nil {
   panic(err)
 } else if err := ring.SetBPFFilter("tcp and port 80"); err != nil {  // optional
   panic(err)
 } else if err := ring.Enable(); err != nil { // Must do this!, or you get no packets!
   panic(err)
 } else {
   packetSource := gopacket.NewPacketSource(ring, layers.LinkTypeEthernet)
	 for packet := range packetSource.Packets() {
     handlePacket(packet)  // Do something with a packet here.
   }
 }

Pfring Tweaks

PF_RING has a ton of optimizations and tweaks to make sure you get just the packets you want. For example, if you're only using pfring to read packets, consider running:

ring.SetSocketMode(pfring.ReadOnly)

If you only care about packets received on your interface (not those transmitted by the interface), you can run:

ring.SetDirection(pfring.ReceiveOnly)

Pfring Clusters

PF_RING has an idea of 'clusters', where multiple applications can all read from the same cluster, and PF_RING will multiplex packets over that cluster such that only one application receives each packet. We won't discuss this mechanism in too much more detail (see the ntop.org docs for more info), but here's how to utilize this with the pfring go library:

ring.SetCluster(1, pfring.ClusterPerFlow5Tuple)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ClusterType

type ClusterType C.cluster_type

ClusterType is a type of clustering used when balancing across multiple rings.

const (
	// ClusterPerFlow clusters by <src ip, src port, dst ip, dst port, proto,
	// vlan>
	ClusterPerFlow ClusterType = C.cluster_per_flow
	// ClusterRoundRobin round-robins packets between applications, ignoring
	// packet information.
	ClusterRoundRobin ClusterType = C.cluster_round_robin
	// ClusterPerFlow2Tuple clusters by <src ip, dst ip>
	ClusterPerFlow2Tuple ClusterType = C.cluster_per_flow_2_tuple
	// ClusterPerFlow4Tuple clusters by <src ip, src port, dst ip, dst port>
	ClusterPerFlow4Tuple ClusterType = C.cluster_per_flow_4_tuple
	// ClusterPerFlow5Tuple clusters by <src ip, src port, dst ip, dst port,
	// proto>
	ClusterPerFlow5Tuple ClusterType = C.cluster_per_flow_5_tuple
	// ClusterPerFlowTCP5Tuple acts like ClusterPerFlow5Tuple for TCP packets and
	// like ClusterPerFlow2Tuple for all other packets.
	ClusterPerFlowTCP5Tuple ClusterType = C.cluster_per_flow_tcp_5_tuple
)

type Direction

type Direction C.packet_direction

Direction is a simple enum to set which packets (TX, RX, or both) a ring captures.

const (
	// TransmitOnly will only capture packets transmitted by the ring's
	// interface(s).
	TransmitOnly Direction = C.tx_only_direction
	// ReceiveOnly will only capture packets received by the ring's
	// interface(s).
	ReceiveOnly Direction = C.rx_only_direction
	// ReceiveAndTransmit will capture both received and transmitted packets on
	// the ring's interface(s).
	ReceiveAndTransmit Direction = C.rx_and_tx_direction
)

type Flag

type Flag uint32

Flag provides a set of boolean flags to use when creating a new ring.

const (
	FlagReentrant       Flag = C.PF_RING_REENTRANT
	FlagLongHeader      Flag = C.PF_RING_LONG_HEADER
	FlagPromisc         Flag = C.PF_RING_PROMISC
	FlagDNASymmetricRSS Flag = C.PF_RING_DNA_SYMMETRIC_RSS
	FlagTimestamp       Flag = C.PF_RING_TIMESTAMP
	FlagHWTimestamp     Flag = C.PF_RING_HW_TIMESTAMP
)

Set of flags that can be passed (OR'd together) to NewRing.

type NextResult

type NextResult int32

NextResult is the return code from a call to Next.

const (
	NextNoPacketNonblocking NextResult = 0
	NextError               NextResult = -1
	NextOk                  NextResult = 1
	NextNotEnabled          NextResult = -7
)

Set of results that could be returned from a call to get another packet.

func (NextResult) Error

func (n NextResult) Error() string

NextResult implements the error interface.

type Ring

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

Ring provides a handle to a pf_ring.

func NewRing

func NewRing(device string, snaplen uint32, flags Flag) (ring *Ring, _ error)

NewRing creates a new PFRing. Note that when the ring is initially created, it is disabled. The caller must call Enable to start receiving packets. The caller should call Close on the given ring when finished with it.

func (*Ring) Close

func (r *Ring) Close()

Close closes the given Ring. After this call, the Ring should no longer be used.

func (*Ring) Disable

func (r *Ring) Disable() error

Disable disables the given ring. After this call, it will no longer receive packets.

func (*Ring) Enable

func (r *Ring) Enable() error

Enable enables the given ring. This function MUST be called on each new ring after it has been set up, or that ring will NOT receive packets.

func (*Ring) ReadPacketData

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

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

func (*Ring) ReadPacketDataTo deprecated

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

ReadPacketDataTo reads packet data into a user-supplied buffer.

Deprecated: This function is provided for legacy code only. Use ReadPacketData or ZeroCopyReadPacketData This function does an additional copy, and is therefore slower than ZeroCopyReadPacketData. The old implementation did the same inside the pf_ring library.

func (*Ring) RemoveBPFFilter

func (r *Ring) RemoveBPFFilter() error

RemoveBPFFilter removes the BPF filter from the ring.

func (*Ring) RemoveFromCluster

func (r *Ring) RemoveFromCluster() error

RemoveFromCluster removes the ring from the cluster it was put in with SetCluster.

func (*Ring) SetApplicationName

func (r *Ring) SetApplicationName(name string) error

SetApplicationName sets a string name to the ring. This name is available in /proc stats for pf_ring. By default, NewRing automatically calls this with argv[0].

func (*Ring) SetBPFFilter

func (r *Ring) SetBPFFilter(bpfFilter string) error

SetBPFFilter sets the BPF filter for the ring.

func (*Ring) SetCluster

func (r *Ring) SetCluster(cluster int, typ ClusterType) error

SetCluster sets which cluster the ring should be part of, and the cluster type to use.

func (*Ring) SetDirection

func (r *Ring) SetDirection(d Direction) error

SetDirection sets which packets should be captured by the ring.

func (*Ring) SetPollDuration

func (r *Ring) SetPollDuration(durationMillis uint) error

SetPollDuration sets the pfring's poll duration before it yields/returns

func (*Ring) SetPollWatermark

func (r *Ring) SetPollWatermark(count uint16) error

SetPollWatermark sets the pfring's poll watermark packet count

func (*Ring) SetPriority

func (r *Ring) SetPriority(cpu uint16)

SetPriority sets the pfring poll threads CPU usage limit

func (*Ring) SetSamplingRate

func (r *Ring) SetSamplingRate(rate int) error

SetSamplingRate sets the sampling rate to 1/<rate>.

func (*Ring) SetSocketMode

func (r *Ring) SetSocketMode(s SocketMode) error

SetSocketMode sets the mode of the ring socket to send, receive, or both.

func (*Ring) Stats

func (r *Ring) Stats() (s Stats, err error)

Stats returns statistsics for the ring.

func (*Ring) WritePacketData

func (r *Ring) WritePacketData(data []byte) error

WritePacketData uses the ring to send raw packet data to the interface.

func (*Ring) ZeroCopyReadPacketData

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

ZeroCopyReadPacketData returns the next packet read from pf_ring, along with an error code associated with that packet. The slice returned by ZeroCopyReadPacketData points to bytes inside a pf_ring ring. Each call to ZeroCopyReadPacketData might invalidate 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 SocketMode

type SocketMode C.socket_mode

SocketMode is an enum for setting whether a ring should read, write, or both.

const (
	// WriteOnly sets up the ring to only send packets (Inject), not read them.
	WriteOnly SocketMode = C.send_only_mode
	// ReadOnly sets up the ring to only receive packets (ReadPacketData), not
	// send them.
	ReadOnly SocketMode = C.recv_only_mode
	// WriteAndRead sets up the ring to both send and receive packets.
	WriteAndRead SocketMode = C.send_and_recv_mode
)

type Stats

type Stats struct {
	Received, Dropped uint64
}

Stats provides simple statistics on a ring.

Jump to

Keyboard shortcuts

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