goProbe

package
v0.0.0-...-c20b0bb Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2018 License: GPL-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	Unknown          uint8 = 0
	DirectionRemains uint8 = 1
	DirectionReverts uint8 = 2
)
View Source
const (
	SLOG_ADDR = "127.0.0.1"
	SLOG_PORT = "514"
)
View Source
const (
	TCP byte = 6
	UDP      = 17
	ESP      = 50
)
View Source
const (
	CAPTURE_SNAPLEN         = 86
	CAPTURE_ERROR_THRESHOLD = 10000
	// Our experiments show that you don't want to set this value lower
	// than roughly 100 ms. Otherwise we flood the kernel with syscalls
	// and our performance drops.
	CAPTURE_TIMEOUT time.Duration = 500 * time.Millisecond

	MIN_PCAP_BUF_SIZE = 1024               // require at least one KiB
	MAX_PCAP_BUF_SIZE = 1024 * 1024 * 1024 // 1 GiB should be enough for anyone ;)
)

Variables

View Source
var (
	BYTE_ARR_1_ZERO  = byte(0x00)
	BYTE_ARR_2_ZERO  = [2]byte{0x00, 0x00}
	BYTE_ARR_4_ZERO  = [4]byte{0x00, 0x00, 0x00, 0x00}
	BYTE_ARR_16_ZERO = [16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	BYTE_ARR_37_ZERO = [37]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
)
View Source
var PcapMutex sync.Mutex

This mutex linearizes all pcap.InactiveHandle.Activate and pcap.Handle.SetBPFFilter calls. Don't touch it unless you know what you're doing.

View Source
var SysLog *syslog.Writer

Functions

func ClassifyPacketDirection

func ClassifyPacketDirection(packet *GPPacket) uint8

This function is responsible for running a variety of heuristics on the packet in order to determine its direction. This classification is important since the termination of flows in regular intervals otherwise results in the incapability to correctly assign the appropriate endpoints. Current heuristics include:

  • investigating the TCP flags (if available)
  • incorporating the port information (with respect to privileged ports)
  • dissecting ICMP traffic

Return value: according to above enumeration

0: if no classification possible
1: if packet direction is "request"
2: if packet direction is "response"

func InitGPLog

func InitGPLog() error

func InitPacketLog

func InitPacketLog(dbpath string, ifaces []string)

func IsSpecialPort

func IsSpecialPort(port uint16) bool

Types

type Capture

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

A Capture captures and logs flow data for all traffic on a given network interface. For each Capture, a goroutine is spawned at creation time. To avoid leaking this goroutine, be sure to call Close() when you're done with a Capture.

Each Capture is a finite state machine. Here is a diagram of the possible state transitions:

         +---------------+
         |               |
         |               |
         |               +---------------------+
         |               |                     |
         | UNINITIALIZED <-------------------+ |
         |               |  recoverError()   | |
         +----^-+--------+                   | |initialize()
              | |                            | |fails
              | |initialize() is             | |
              | |successful                  | |
              | |                            | |
uninitialize()| |                            | |
              | |                            | |
          +---+-v-------+                    | |
          |             |                +---+-v---+
          |             |                |         |
          |             |                |         |
          |             |                |  ERROR  |
          | INITIALIZED |                |         |
          |             |                +----^----+
          +---^-+-------+                     |
              | |                             |
              | |activate()                   |
              | |                             |
  deactivate()| |                             |
              | |                             |
            +-+-v----+                        |
            |        |                        |
            |        +------------------------+
            |        |  capturePacket()
            |        |  (called by process())
            | ACTIVE |  fails
            |        |
            +--------+

Enable() and Update() try to put the capture into the ACTIVE state, Disable() puts the capture into the UNINITIALIZED state.

Each capture is associated with a network interface when created. This interface can never be changed.

All public methods of Capture are threadsafe.

func NewCapture

func NewCapture(iface string, config CaptureConfig) *Capture

NewCapture creates a new Capture associated with the given iface.

func (*Capture) Close

func (c *Capture) Close()

Close closes the Capture and releases all underlying resources. Close is idempotent. Once you have closed a Capture, you can no longer call any of its methods (apart from Close).

func (*Capture) Disable

func (c *Capture) Disable()

Disable will bring the Capture instance into CAPTURE_STATE_UNINITIALIZED Disable will have no effect if the Capture is already in CAPTURE_STATE_UNINITIALIZED.

func (*Capture) Enable

func (c *Capture) Enable()

Enable will attempt to put the Capture instance into CAPTURE_STATE_ACTIVE. Enable will have no effect if the Capture is already in CAPTURE_STATE_ACTIVE.

func (*Capture) Errors

func (c *Capture) Errors() (result errorMap)

Error map status call

func (*Capture) Rotate

func (c *Capture) Rotate() (agg goDB.AggFlowMap, stats CaptureStats)

Rotate performs a rotation of the underlying flow log and returns an AggFlowMap with all flows that have been collected since the last call to Rotate(). It also returns capture statistics collected since the last call to Rotate().

Note: stats.Pcap may be null if there was an error fetching the stats of the underlying pcap handle.

func (*Capture) Status

func (c *Capture) Status() (result CaptureStatus)

Status returns the current CaptureState as well as the statistics collected since the last call to Rotate()

Note: If the Capture was reinitialized since the last rotation, result.Stats.Pcap will be inaccurate.

Note: result.Stats.Pcap may be null if there was an error fetching the stats of the underlying pcap handle.

func (*Capture) Update

func (c *Capture) Update(config CaptureConfig)

Update will attempt to put the Capture instance into CAPTURE_STATE_ACTIVE with the given config. If the Capture is already active with the given config Update will detect this and do no work.

type CaptureConfig

type CaptureConfig struct {
	BufSize   int    `json:"buf_size"` // in bytes
	BPFFilter string `json:"bpf_filter"`
	Promisc   bool   `json:"promisc"`
}

func (CaptureConfig) Validate

func (cc CaptureConfig) Validate() error

Validate (partially) checks that the given CaptureConfig contains no bogus settings.

Note that the BPFFilter field isn't checked.

type CaptureManager

type CaptureManager struct {
	sync.Mutex
	// contains filtered or unexported fields
}

CaptureManager manages a set of Capture instances. Each interface can be associated with up to one Capture.

func NewCaptureManager

func NewCaptureManager() *CaptureManager

NewCaptureManager creates a new CaptureManager and returns a pointer to it.

func (*CaptureManager) CloseAll

func (cm *CaptureManager) CloseAll()

CloseAll() closes and deletes all Capture instances managed by the CaptureManager

func (*CaptureManager) DisableAll

func (cm *CaptureManager) DisableAll()

DisableAll disables all managed Capture instances.

Returns once all instances have been disabled. The instances are not deleted, so you may later enable them again; for example, by calling EnableAll().

func (*CaptureManager) EnableAll

func (cm *CaptureManager) EnableAll()

EnableAll attempts to enable all managed Capture instances.

Returns once all instances have been enabled. Note that each attempt may fail, for example if the interface that a Capture is supposed to monitor ceases to exist. Use StateAll() to find out wheter the Capture instances encountered an error.

func (*CaptureManager) ErrorsAll

func (cm *CaptureManager) ErrorsAll() map[string]errorMap

ErrorsAll() returns the error maps of all managed Capture instances.

func (*CaptureManager) RotateAll

func (cm *CaptureManager) RotateAll(returnChan chan TaggedAggFlowMap)

RotateAll() returns the state of all managed Capture instances.

The resulting TaggedAggFlowMaps will be sent over returnChan and be tagged with the given timestamp.

func (*CaptureManager) StatusAll

func (cm *CaptureManager) StatusAll() map[string]CaptureStatus

StatusAll() returns the statuses of all managed Capture instances.

func (*CaptureManager) Update

func (cm *CaptureManager) Update(ifaces map[string]CaptureConfig, returnChan chan TaggedAggFlowMap)

Update attempts to enable all Capture instances given by ifaces. If an instance doesn't exist, it will be created. If an instance has encountered an error or an instance's configuration differs from the one specified in ifaces, it will be re-enabled. Finally, if the CaptureManager manages an instance for an iface that does not occur in ifaces, the following actions are performed on the instance: (1) the instance will be disabled, (2) the instance will be rotated, (3) the resulting flow data will be sent over returnChan, (tagged with the interface name and stats), (4) the instance will be closed, and (5) the instance will be completely removed from the CaptureManager.

Returns once all the above actions have been completed.

type CaptureState

type CaptureState byte
const (
	CAPTURE_STATE_UNINITIALIZED CaptureState = iota + 1
	CAPTURE_STATE_INITIALIZED
	CAPTURE_STATE_ACTIVE
	CAPTURE_STATE_ERROR
)

func (CaptureState) String

func (cs CaptureState) String() string

type CaptureStats

type CaptureStats struct {
	Pcap          *pcap.Stats
	PacketsLogged int
}

type CaptureStatus

type CaptureStatus struct {
	State CaptureState
	Stats CaptureStats
}

type EPHash

type EPHash [37]byte

typedef that allows us to replace the type of hash

type FlowLog

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

A FlowLog stores flows. It is NOT threadsafe.

func NewFlowLog

func NewFlowLog() *FlowLog

NewFlowLog creates a new flow log for storing flows.

func (*FlowLog) Add

func (fm *FlowLog) Add(packet *GPPacket)

Add a packet to the flow log. If the packet belongs to a flow already present in the log, the flow will be updated. Otherwise, a new flow will be created.

func (*FlowLog) Rotate

func (fm *FlowLog) Rotate() (agg goDB.AggFlowMap)

Rotate the log. All flows are reset to no packets and traffic. Moreover, any flows not worth keeping (according to GPFlow.IsWorthKeeping) are discarded.

Returns an AggFlowMap containing all flows since the last call to Rotate.

type GPFlow

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

func NewGPFlow

func NewGPFlow(packet *GPPacket) *GPFlow

Constructor method

func (*GPFlow) HasBeenIdle

func (f *GPFlow) HasBeenIdle() bool

func (*GPFlow) IsWorthKeeping

func (f *GPFlow) IsWorthKeeping() bool

routine that a flow uses to check whether it has any interesting layer 7 info worth keeping and whether its counters are non-zero. If they are, it means that the flow was essentially idle in the last time interval and that it can be safely discarded. Updated: also carries over the flows where a direction could be identified

func (*GPFlow) Reset

func (f *GPFlow) Reset()

reset all flow counters

func (*GPFlow) UpdateFlow

func (f *GPFlow) UpdateFlow(packet *GPPacket)

here, the values are incremented if the packet belongs to an existing flow

type GPFlower

type GPFlower interface {
	UpdateFlow()
	IsWorthKeeping() bool
	HasBeenIdle() bool
	Reset()
}

type GPPacket

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

func (*GPPacket) Populate

func (p *GPPacket) Populate(srcPacket gopacket.Packet) error

Populate takes a raw packet and populates a GPPacket structure from it.

type PacketLogWriter

type PacketLogWriter struct {
	sync.Mutex
	// contains filtered or unexported fields
}
var PacketLog *PacketLogWriter

func (*PacketLogWriter) Close

func (p *PacketLogWriter) Close()

func (*PacketLogWriter) Log

func (p *PacketLogWriter) Log(iface string, packet gopacket.Packet, snapshotLen int) error

type PcapWriter

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

type RunGroup

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

func (*RunGroup) Run

func (rg *RunGroup) Run(f func())

func (*RunGroup) Wait

func (rg *RunGroup) Wait()

type TaggedAggFlowMap

type TaggedAggFlowMap struct {
	Map   goDB.AggFlowMap
	Stats CaptureStats
	Iface string
}

TaggedAggFlowMap represents an aggregated flow map tagged with CaptureStats and an an interface name.

Used by CaptureManager to return the results of RotateAll() and Update().

Notes

Bugs

  • There is a pcap bug? that causes mysterious panics when we try to call Activate on more than one pcap.InactiveHandle at the same time. We have also observed (much rarer) panics triggered by calls to SetBPFFilter on activated pcap handles. Hence we use PcapMutex to make sure that there can only be on call to Activate and SetBPFFilter at any given moment.

Jump to

Keyboard shortcuts

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