packet

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2021 License: MIT Imports: 14 Imported by: 0

README

packet Go Reference

Package packet provides basic APIs for linux packet socket. MIT licensed.

It can be easily extended and (presumably) integrated with Go rutime poller.

go get github.com/urbanishimwe/packet
Usage

The easiest way to use this library,

read packets,

import "github.com/urbanishimwe/packet"
   .............
   ...........
// create a handler
handler, err := packet.NewHander("", nil)
if err != nil {
    // handle errors
}

// read from handler
for {
    raw, info, err := handler.Read(true)
    if err == nil {
        usePacket(raw, info)
        continue
    }
    // check if error is recoverable
    if packet.Temporary(err) || packet.Timeout(err) {
        continue
    }
    // may be break!
}

send packets,

handler.Write([]byte, nil, packet.ProtoIP)

you can also use BPF filters and configurations to control the handler.

PCAP

save packets in pcap file format

go build ./cmd/pcap

if you want to link with libpcap BPF expressions compiler use,

go build -tags=bpf ./cmd/pcap
Stability

It is very unlikely that signatures and types exposed by this package will change but new APIs might be added. It is recommended to read documentation in order to use this library appropriately.

Documentation

Overview

Package packet provides basic APIs for linux packet socket.

This package uses memory mapping to increase performance and reduce system calls during packets reading. Most errors returned by this package are of type syscall.Errno, *os.SyscallError, or others documented by this package.

Handler.Fd() is there to help users of this package to implement functionalities that are not provided by this package. It should be used with great care.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotImplemented = errors.New("not implemented")

ErrNotImplemented requested functionality is not implemented for the host operating system.

Functions

func IsOSSupported

func IsOSSupported() bool

IsOSSupported returns true if the calling OS is supported by this library

func KernelVersion

func KernelVersion() (major int32, minor int32)

KernelVersion returns linux kernel major and minor version since the first check. these values will be -1 on error.

func Temporary

func Temporary(err error) bool

Temporary checks if this error is a temporary error and return true or false otherwise. timeout errors should also be temporary errors.

func Timeout

func Timeout(err error) bool

Timeout checks if this error is a timeout error and return true or false otherwise.

func TstampValid

func TstampValid(status uint32) int8

TstampValid returns

0: for timestamp generated by the kernel,

1: for timestamp generated by network adapter, and

-1: timestamp is invalid or something else.

status should be the value from (*Info).Status

func VlanValid

func VlanValid(status uint32) bool

VlanValid returns true if all values in VLAN struct are valid and false otherwise. status should be the value from (*Info).Status

Types

type Config

type Config struct {
	// the duration in milliseconds, if socket is not in non-blocking mode,
	//
	//  read will return ETIMEDOUT after waiting socket readiness for this long.
	//
	// zero or negative timeout = don't timeout(default).
	ReadTimeout int64
	// Packets that arrive for a capture are stored in a buffer, so that they do not have to be read by the application as soon as they arrive.
	// a size that's too small could mean that, if too many packets are being captured,
	// packets could be dropped if the buffer fills up before the application can read packets from it,
	// while a size that's too large could use more non-pageable operating system memory than is necessary to prevent packets from being dropped.
	// custom value may be increased for buffer alignment.
	//
	// zero or negative bytes size = chose the default value(2MBs).
	ReadBufferSize int64
	// the duration in milliseconds, if socket is not in immediate mode,
	//
	// we wait for a block of buffer to become full so we can read many packets on a single poll.
	//
	// zero timeout means don't timeout(default); negative timeout = let the kernel decides the buffer timeout.
	ReadBufferTimeout int64
	// pre-attach an assembled BPF program to the socket.
	Filter []bpf.RawInstruction
	// deliver packets as soon as they arrive, with no buffering. unless there is a special reason for this,
	// callers should not enable this feature. it many cause huge unused memory, truncating some packets and relatively higher CPU usages.
	ImmediateMode bool
	// enable promiscuous mode on an interface.
	Promiscuous bool
	// enable non-blocking mode. read/write will return immediately with EAGAIN  if the operation
	// can not be performed immediately.
	NonBlock bool
	// writes and reads will provide packet buffer with link-layer header removed(cooked mode).
	NoLinkLayer bool
	// ethernet protocol to use in socket.
	Proto Proto
	// timestamp resolution in nano or micro seconds.
	TstampResolution TstampResolution
	// flow of packet to allow.
	Direction Direction
	// the maximum number of consecutive undesired Direction of the packet that should happen
	// before a single call to Read decides to return a nil packet and a nil error.
	// this field will not matter if Direction is DirInOut.
	MaxNilRead uint64
}

Config is used to configure a packet handler. all fields are optional.

configuration should be initialized from calling DefaultConfig. Default value of the field is the value resulted from calling DefaultConfig(). a care must be taken when modifying Config values(read docs of the fields).

if you want to limit the packet size("snapshot") use BPF filters.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig user should call this before creating custom Config object

func (*Config) CheckIntegrity

func (c *Config) CheckIntegrity() bool

CheckIntegrity checks values in this Config and return true if all of them are valid.

type Direction

type Direction uint8

Direction the flow of the packet

const (
	// DirInOut incoming and outgoing
	DirInOut Direction = iota
	// DirIn incoming only
	DirIn
	// DirOut outgoing only
	DirOut
)

type ErrBreakLoop

type ErrBreakLoop uint8

ErrBreakLoop returned when loop was terminated by BreakLoop.

func (ErrBreakLoop) Error

func (e ErrBreakLoop) Error() string

func (ErrBreakLoop) Temporary

func (e ErrBreakLoop) Temporary() bool

Temporary ErrBreakLoop is a temporary error

type ErrWouldPoll

type ErrWouldPoll uint8

ErrWouldPoll read would rather poll.

func (ErrWouldPoll) Error

func (e ErrWouldPoll) Error() string

func (ErrWouldPoll) Temporary

func (e ErrWouldPoll) Temporary() bool

Temporary ErrWouldPoll is a temporary error

type Handler

type Handler interface {
	// read a packet from the socket.
	//
	// poll, if true, Read will wait for a packet(s), an error, a timeout, or an event on the socket.
	// if poll is false and there no packets to read, Read will return immediately with an error set to ErrWouldPoll.
	//
	// it is recommended to read documentation of Config and Handler.BreakLoop before using this method.
	Read(poll bool) (raw []byte, info *Info, err error)
	// transmit a packet to the socket.
	//
	// if iff is nil, interface bound to this socket is used.
	// EINVAL is returned if iff is nil and socket is not bound to an interface or values in iff are invalid
	// or protocol value is invalid.
	//
	// protocol is an ethernet protocol. values of common protocols are exposed by this library.
	Write(buf []byte, iff *net.Interface, protocol Proto) (int, error)
	// returns packet socket file descriptor, always.
	Fd() uintptr
	// poll happening in the middle or after a call to this method will return ErrBreakLoop.
	BreakLoop() error
	// similar to (*Config).Filter, attaches an assembled BPF program to the socket.
	// if filter length is 0, this method will detach recently added filters.
	SetBPF(filter []bpf.RawInstruction) error
	// if total is true Stats returns the total stats since the socket lifetime or stats
	// since the recent call to this method otherwise.
	//
	// in case of any error, this method returns *Stats with zero values.
	Stats(total bool) *Stats
	// returns pointer to the internal Config used this handle.
	Config() *Config
	// returns the link type of the interface bound to this socket or LinkTypeNone.
	LinkType() LinkType
	// close the handle sockets. reads and writes operations after this call should return EINVAL.
	Close() error
}

Handler is an interface for a linux packet socket.

func NewHandler

func NewHandler(iff string, config *Config) (Handler, error)

NewHandler activates and configure a linux packet socket and return its handler.

socket is bound to iff interface. if iff is empty string, socket receives packets from all interfaces and config.NoLinkLayer is set to true. if config is nil, default configuration is used. it returns an error or a non-nil handler.

type Info

type Info struct {
	Time    time.Time // unix timestamp this packet was captured, if that is known.
	CapLen  int       // the total number of bytes read off of the wire.
	Len     int       // original packet length. should be>= CapLen.
	Ifindex int32     // interface index.
	Status  uint32    // linux status variable in t_packet header. can be used to validate timestamp and vlan tags.
	VLAN    VLAN
	Link    Link
}

Info useful information of a packet

type Link struct {
	Protocol Proto    // ethernet protocol type
	LinkType LinkType // arp type
}

Link is packet's link layer info

type LinkType

type LinkType uint16

LinkType data link layer type

const (
	// LinkTypeEthernet standard ethernet type
	LinkTypeEthernet LinkType = 1
	// LinkTypeNone no link type or nothing is known
	LinkTypeNone LinkType = 0xffff
)

func InterfaceLinkType

func InterfaceLinkType(iff string) (link LinkType)

InterfaceLinkType returns LinkType of the "iff" network interface. it returns LinkTypeNone if interface with "iff" name does not exists or we can't query such info using standard linux mechanisms

func (LinkType) String

func (l LinkType) String() string

type Proto

type Proto uint16

Proto ethernet protocol

const (
	ProtoIP  Proto = 0x800
	ProtoIP6 Proto = 0x86dd
	ProtoARP Proto = 0x806
	ProtoAll Proto = 0x3
)

common protocols, their values are linux's

type Stats

type Stats struct {
	// number of packets received by the socket(excluding those that failed the BPF filter check).
	Recvs uint64
	// number of packets dropped(due to the short buffer size). this number does not include packets that failed BPF filters.
	Drops uint64
}

Stats contains statistics about a handle.

type TstampResolution

type TstampResolution uint8

TstampResolution Time stamp resolution types.

const (
	// TstampNano use timestamps with nanosecond precision, default
	TstampNano TstampResolution = iota
	// TstampMicro use timestamps with microsecond precision
	TstampMicro
)

type VLAN

type VLAN struct {
	TPID uint16
	TCI  uint16
}

VLAN IEEE 802.1Q

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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