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/Doridian/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 ¶
- type ClusterType
- type Direction
- type Flag
- type NextResult
- type Ring
- func (r *Ring) Close()
- func (r *Ring) Disable() error
- func (r *Ring) Enable() error
- func (r *Ring) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)
- func (r *Ring) ReadPacketDataTo(data []byte) (ci gopacket.CaptureInfo, err error)deprecated
- func (r *Ring) RemoveBPFFilter() error
- func (r *Ring) RemoveFromCluster() error
- func (r *Ring) SetApplicationName(name string) error
- func (r *Ring) SetBPFFilter(bpfFilter string) error
- func (r *Ring) SetCluster(cluster int, typ ClusterType) error
- func (r *Ring) SetDirection(d Direction) error
- func (r *Ring) SetPollDuration(durationMillis uint) error
- func (r *Ring) SetPollWatermark(count uint16) error
- func (r *Ring) SetPriority(cpu uint16)
- func (r *Ring) SetSamplingRate(rate int) error
- func (r *Ring) SetSocketMode(s SocketMode) error
- func (r *Ring) Stats() (s Stats, err error)
- func (r *Ring) WritePacketData(data []byte) error
- func (r *Ring) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error)
- type SocketMode
- type Stats
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 ¶
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 ¶
Disable disables the given ring. After this call, it will no longer receive packets.
func (*Ring) Enable ¶
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 ¶
RemoveBPFFilter removes the BPF filter from the ring.
func (*Ring) RemoveFromCluster ¶
RemoveFromCluster removes the ring from the cluster it was put in with SetCluster.
func (*Ring) SetApplicationName ¶
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 ¶
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 ¶
SetDirection sets which packets should be captured by the ring.
func (*Ring) SetPollDuration ¶
SetPollDuration sets the pfring's poll duration before it yields/returns
func (*Ring) SetPollWatermark ¶
SetPollWatermark sets the pfring's poll watermark packet count
func (*Ring) SetPriority ¶
SetPriority sets the pfring poll threads CPU usage limit
func (*Ring) SetSamplingRate ¶
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) WritePacketData ¶
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 )