Documentation ¶
Index ¶
- Constants
- Variables
- func ClassifyPacketDirection(packet *GPPacket) uint8
- func InitGPLog() error
- func InitPacketLog(dbpath string, ifaces []string)
- func IsSpecialPort(port uint16) bool
- type Capture
- type CaptureConfig
- type CaptureManager
- func (cm *CaptureManager) CloseAll()
- func (cm *CaptureManager) DisableAll()
- func (cm *CaptureManager) EnableAll()
- func (cm *CaptureManager) ErrorsAll() map[string]errorMap
- func (cm *CaptureManager) RotateAll(returnChan chan TaggedAggFlowMap)
- func (cm *CaptureManager) StatusAll() map[string]CaptureStatus
- func (cm *CaptureManager) Update(ifaces map[string]CaptureConfig, returnChan chan TaggedAggFlowMap)
- type CaptureState
- type CaptureStats
- type CaptureStatus
- type EPHash
- type FlowLog
- type GPFlow
- type GPFlower
- type GPPacket
- type PacketLogWriter
- type PcapWriter
- type RunGroup
- type TaggedAggFlowMap
- Bugs
Constants ¶
const ( Unknown uint8 = 0 DirectionRemains uint8 = 1 DirectionReverts uint8 = 2 )
const ( SLOG_ADDR = "127.0.0.1" SLOG_PORT = "514" )
const ( TCP byte = 6 UDP = 17 ESP = 50 )
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 ¶
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} )
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.
var SysLog *syslog.Writer
Functions ¶
func ClassifyPacketDirection ¶
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 InitPacketLog ¶
func IsSpecialPort ¶
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) 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 ¶
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 CaptureStatus ¶
type CaptureStatus struct { State CaptureState Stats CaptureStats }
type FlowLog ¶
type FlowLog struct {
// contains filtered or unexported fields
}
A FlowLog stores flows. It is NOT threadsafe.
func (*FlowLog) Add ¶
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 (*GPFlow) HasBeenIdle ¶
func (*GPFlow) IsWorthKeeping ¶
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) UpdateFlow ¶
here, the values are incremented if the packet belongs to an existing flow
type PacketLogWriter ¶
var PacketLog *PacketLogWriter
func (*PacketLogWriter) Close ¶
func (p *PacketLogWriter) Close()
type PcapWriter ¶
type PcapWriter struct {
// contains filtered or unexported fields
}
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.