ipfix

package module
v0.0.0-...-9d85a86 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2019 License: BSD-3-Clause Imports: 13 Imported by: 25

README

go-ipfix

This library provides ipfix protocol write support. See godoc for more details.

GoDoc

Documentation

Overview

Package ipfix writes ipfix data streams as defined by RFC 7011.

Currently supported is only writing to an io.Writer, the datatypes from the RFC7011 + basic lists from RFC 6313.

Option templates and template recovation are not supported.

Usage

For exporting ipfix data a MessageStream instance has to be created with MakeMessageStream. This stream then provides the two functions AddTemplate for adding templates and SendData for sending data, as specified by a template. After all the data has been added with SendData, Flush must be called. Full examples are provided at the MakeMessageStream function.

Information elements can be created either from an iespec (RFC 7373) with MakeIEFromSpec, or by hand with NewInformationElement or NewBasicList.

All the information elements as defined by the iana can be loaded with LoadIanaSpec and then accessed by name with GetInformationElement.

Custom loaders can be created with generate_spec.go or by calling RegisterInformationElement.

Index

Examples

Constants

View Source
const VariableLength uint16 = 65535

VariableLength is the variable length specifier as defined by RFC7011

Variables

View Source
var DefaultSize = [...]uint16{
	VariableLength,
	1,
	2,
	4,
	8,
	1,
	2,
	4,
	8,
	4,
	8,
	1,
	6,
	VariableLength,
	4,
	8,
	8,
	8,
	4,
	16,
	VariableLength,
}

DefaultSize can be used to look up the default size of an ipfix type

Functions

func LoadIANASpec

func LoadIANASpec()

LoadIANASpec loads information elements from the given specification

func RegisterInformationElement

func RegisterInformationElement(x InformationElement) error

RegisterInformationElement registers the given InformationElement. This can later be queried by name with GetInformationElement.

Types

type BasicListMismatchError

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

BasicListMismatchError indicates that the number of required information elements did not match the number of passed data values.

func (BasicListMismatchError) Error

func (e BasicListMismatchError) Error() string

type ConversionError

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

ConversionError indicates that the type of the given value can't be converted to the given ipfix type

func (ConversionError) Error

func (e ConversionError) Error() string

type DateTimeMicroseconds

type DateTimeMicroseconds uint64

DateTimeMicroseconds represents time in units of microseconds from 00:00 UTC, Januray 1, 1970 according to RFC5102.

type DateTimeMilliseconds

type DateTimeMilliseconds uint64

DateTimeMilliseconds represents time in units of milliseconds from 00:00 UTC, Januray 1, 1970 according to RFC5102.

type DateTimeNanoseconds

type DateTimeNanoseconds uint64

DateTimeNanoseconds represents time in units of nanoseconds from 00:00 UTC, Januray 1, 1970 according to RFC5102.

type DateTimeSeconds

type DateTimeSeconds uint64

DateTimeSeconds represents time in units of seconds from 00:00 UTC, Januray 1, 1970 according to RFC5102.

type IllegalTypeError

type IllegalTypeError Type

IllegalTypeError indicates that the given type is not known

func (IllegalTypeError) Error

func (e IllegalTypeError) Error() string

type InformationElement

type InformationElement struct {
	// Name of the information element
	Name string
	// Pen is the enterprise number (0 for iana reserved)
	Pen uint32
	// ID is the information element ID
	ID uint16
	// Type is the associated data type
	Type Type
	// Length is the length of the field value
	Length uint16
	// contains filtered or unexported fields
}

InformationElement represents the description of an information element according to RFC7011

func GetInformationElement

func GetInformationElement(name string) (ret InformationElement, err error)

GetInformationElement retrieves an InformationElement by name.

func MakeIEFromSpec

func MakeIEFromSpec(spec []byte) (InformationElement, error)

MakeIEFromSpec returns an InformationElement as specified by the provided specification. The specification format must follow RFC7013 section 10.1

func NewBasicList

func NewBasicList(name string, subelement InformationElement, number uint16) InformationElement

NewBasicList returns an InformationElement holding the basic list according to RFC6313. If number is 0, a variable length list is returned.

func NewInformationElement

func NewInformationElement(name string, pen uint32, id uint16, t Type, length uint16) InformationElement

NewInformationElement returns an information element for the given specification. If length is 0, the default length for this data type is chosen.

func (InformationElement) ListElement

func (ie InformationElement) ListElement() (InformationElement, bool)

ListElement returns the InformationElement of a list item and true if this InformationElement is a list. Otherwise an empty InformationElement and false is returned.

func (InformationElement) Reverse

Reverse returns the reverse information element according to RFC5103

Example
package main

import (
	"fmt"

	ipfix "github.com/CN-TU/go-ipfix"
)

func main() {
	ipfix.LoadIANASpec()

	ie, err := ipfix.GetInformationElement("octetDeltaCount")
	if err != nil {
		fmt.Println("GetInformationElement failed:", err)
		return
	}
	fmt.Println(ie)

	revie := ie.Reverse()
	fmt.Println(revie)

	revrevie := revie.Reverse()
	fmt.Println(revrevie)
}
Output:

octetDeltaCount
reverseOctetDeltaCount(29305/1)<unsigned64>
octetDeltaCount

func (InformationElement) String

func (ie InformationElement) String() string

type MessageStream

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

MessageStream represents an ipfix message stream.

func MakeMessageStream

func MakeMessageStream(w io.Writer, mtu uint16, observationID uint32) (ret *MessageStream, err error)

MakeMessageStream initializes a new message stream, which writes to the given writer and uses the given mtu size. The observationID is used as the observation id in the ipfix messages.

Example
package main

import (
	"bytes"
	"fmt"
	"net"
	"time"

	ipfix "github.com/CN-TU/go-ipfix"
)

func main() {
	// output of this example will be in buf
	buf := new(bytes.Buffer)

	// load the iana information elements
	ipfix.LoadIANASpec()

	now := time.Date(2018, 01, 01, 0, 0, 0, 0, time.UTC) // simulated fixed time

	// First create a message stream; mtu=0 chooses the default size
	msgStream, err := ipfix.MakeMessageStream(buf, 0, 0)
	if err != nil {
		fmt.Println("MakeMessageStream failed:", err)
		return
	}

	// Add a new template with three information elements
	a, err := ipfix.GetInformationElement("octetDeltaCount")
	if err != nil {
		fmt.Println("GetInformationElement failed:", err)
	}
	b, err := ipfix.GetInformationElement("sourceIPv4Address")
	if err != nil {
		fmt.Println("GetInformationElement failed:", err)
	}
	c, err := ipfix.GetInformationElement("flowEndNanoseconds")
	if err != nil {
		fmt.Println("GetInformationElement failed:", err)
	}
	id, err := msgStream.AddTemplate(now, a, b, c)
	if err != nil {
		fmt.Println("MessageStream.AddTemplate failed:", err)
		return
	}

	// Export data for this information Element
	if err := msgStream.SendData(now, id, uint64(5), net.IP{192, 168, 0, 1}, now); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
		return
	}

	now = now.Add(1 * time.Second)
	if err := msgStream.SendData(now, id, uint64(10), net.IP{192, 168, 0, 2}, now); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
		return
	}

	now = now.Add(1 * time.Minute)
	if err := msgStream.SendData(now.Add(10*time.Second), id, uint64(2), net.IP{192, 168, 0, 3}, now); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
		return
	}

	// Call finalize
	if err := msgStream.Flush(now); err != nil {
		fmt.Println("MessageStream.Flush failed:", err)
		return
	}

	// buf holds now the complete ipfix data of this example
	fmt.Printf("% x", buf.Bytes())
}
Output:

00 0a 00 64 5a 49 7a 3d 00 00 00 00 00 00 00 00 00 02 00 14 01 00 00 03 00 01 00 08 00 08 00 04 00 9d 00 08 01 00 00 40 00 00 00 00 00 00 00 05 c0 a8 00 01 dd f3 f8 80 00 00 00 01 00 00 00 00 00 00 00 0a c0 a8 00 02 dd f3 f8 81 00 00 00 01 00 00 00 00 00 00 00 02 c0 a8 00 03 dd f3 f8 bd 00 00 00 01
Example (BasicList)
package main

import (
	"bytes"
	"fmt"
	"time"

	ipfix "github.com/CN-TU/go-ipfix"
)

func main() {
	// output of this example will be in buf
	buf := new(bytes.Buffer)

	// load the iana information elements
	ipfix.LoadIANASpec()

	now := time.Date(2018, 01, 01, 0, 0, 0, 0, time.UTC) // simulated fixed time

	// First create a message stream; mtu=0 chooses the default size
	msgStream, err := ipfix.MakeMessageStream(buf, 0, 0)
	if err != nil {
		fmt.Println("MakeMessageStream failed:", err)
		return
	}

	// Create an information elemenet for the basiclist, holding a variable number of octetDeltaCount
	elem, err := ipfix.GetInformationElement("octetDeltaCount")
	if err != nil {
		fmt.Println("GetInformationElement failed:", err)
	}
	ie := ipfix.NewBasicList("testlist", elem, 0)

	// Add a new template with this information element
	id, err := msgStream.AddTemplate(now,
		ie,
	)
	if err != nil {
		fmt.Println("MessageStream.AddTemplate failed:", err)
		return
	}

	// write out some data
	// Note that despite octetDeltaCount being defined as uint64, you can use differnt types here
	// The data will be converted to the right type; There is no automation to export data with shorter
	// values
	if err := msgStream.SendData(now, id, []uint64{1, 2, 3}); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
	}
	now = now.Add(1 * time.Second)
	if err := msgStream.SendData(now, id, []uint8{4, 5}); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
	}
	now = now.Add(1 * time.Second)
	if err := msgStream.SendData(now, id, []int32{10, 20, 33, 100}); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
	}
	now = now.Add(1 * time.Second)
	if err := msgStream.Flush(now); err != nil {
		fmt.Println("MessageStream.Flush failed:", err)
	}

	// buf holds now the complete ipfix data of this example
	fmt.Printf("% x", buf.Bytes())
}
Output:

00 0a 00 80 5a 49 7a 03 00 00 00 00 00 00 00 00 00 02 00 0c 01 00 00 01 01 23 ff ff 01 00 00 64 ff 00 1d ff 00 01 00 08 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 03 ff 00 15 ff 00 01 00 08 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 05 ff 00 25 ff 00 01 00 08 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 64
Example (BasicListVariable)
package main

import (
	"bytes"
	"fmt"
	"time"

	ipfix "github.com/CN-TU/go-ipfix"
)

func main() {
	// output of this example will be in buf
	buf := new(bytes.Buffer)

	// load the iana information elements
	ipfix.LoadIANASpec()

	now := time.Date(2018, 01, 01, 0, 0, 0, 0, time.UTC) // simulated fixed time

	// First create a message stream; mtu=0 chooses the default size
	msgStream, err := ipfix.MakeMessageStream(buf, 0, 0)
	if err != nil {
		fmt.Println("MakeMessageStream failed:", err)
		return
	}

	// Create an information elemenet for the basiclist, holding a variable number of applicationName, which in turn are also variable length
	elem, err := ipfix.GetInformationElement("applicationName")
	if err != nil {
		fmt.Println("GetInformationElement failed:", err)
	}
	ie := ipfix.NewBasicList("testlist", elem, 0)

	// Add a new template with this information element
	id, err := msgStream.AddTemplate(now,
		ie,
	)
	if err != nil {
		fmt.Println("MessageStream.AddTemplate failed:", err)
		return
	}

	// write out some data
	if err := msgStream.SendData(now, id, []string{"testA", "2", "testB"}); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
	}
	now = now.Add(1 * time.Second)
	if err := msgStream.SendData(now, id, []string{"something longer"}); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
	}
	now = now.Add(1 * time.Second)
	if err := msgStream.SendData(now, id, []string{"short", "test", "some", "more", "tests"}); err != nil {
		fmt.Println("MessageStream.SendData failed:", err)
	}
	now = now.Add(1 * time.Second)
	if err := msgStream.Flush(now); err != nil {
		fmt.Println("MessageStream.Flush failed:", err)
	}

	// buf holds now the complete ipfix data of this example
	fmt.Printf("% x", buf.Bytes())
}
Output:

00 0a 00 72 5a 49 7a 03 00 00 00 00 00 00 00 00 00 02 00 0c 01 00 00 01 01 23 ff ff 01 00 00 56 ff 00 13 ff 00 60 ff ff 05 74 65 73 74 41 01 32 05 74 65 73 74 42 ff 00 16 ff 00 60 ff ff 10 73 6f 6d 65 74 68 69 6e 67 20 6c 6f 6e 67 65 72 ff 00 20 ff 00 60 ff ff 05 73 68 6f 72 74 04 74 65 73 74 04 73 6f 6d 65 04 6d 6f 72 65 05 74 65 73 74 73

func (*MessageStream) AddTemplate

func (m *MessageStream) AddTemplate(now interface{}, elements ...InformationElement) (id int, err error)

AddTemplate adds the given InformationElement as a new template. now must be the current or exported time either as a time.Time value or as one of the provieded ipfix time types. A template id is returned that can be used with SendData. In case of error an error value is provided.

func (*MessageStream) Flush

func (m *MessageStream) Flush(now interface{}) (err error)

Flush must be called before the underlying writer is closed. This function finishes and flushes eventual not yet finalized messages. This does not flush the underlying buffer!

func (*MessageStream) SendData

func (m *MessageStream) SendData(now interface{}, template int, data ...interface{}) (err error)

SendData sends the given values for the given template id (Can be allocated with AddTemplate). now must be the current or exported time either as a time.Time value or as one of the provieded ipfix time types. Template InformationElements and given data types must match. Numeric types are converted automatically. In case of error an error is returned.

type RecordTooBigError

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

RecordTooBigError indicates that the template or data set was too big for the mtu

func (RecordTooBigError) Error

func (e RecordTooBigError) Error() string

type SizeError

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

SizeError indicates that the given size is illegal for the given type

func (SizeError) Error

func (e SizeError) Error() string

type StructuredSemantic

type StructuredSemantic byte

StructuredSemantic represents the semantic of the structured data type according to RFC6313

const (
	// NoneOfSemantic as defined by RFC6313
	NoneOfSemantic StructuredSemantic = iota
	// ExactlyOneOfSemantic as defined by RFC6313
	ExactlyOneOfSemantic
	// OneOrMoreOfSemantic as defined by RFC6313
	OneOrMoreOfSemantic
	// AllOfSemantic as defined by RFC6313
	AllOfSemantic
	// OrderedSemantic as defined by RFC6313
	OrderedSemantic
	// UndefinedSemantic as defined by RFC6313
	UndefinedSemantic StructuredSemantic = 0xFF
)

type TemplateMismatchError

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

TemplateMismatchError indicates that the number of required information elements did not match the number of passed data values.

func (TemplateMismatchError) Error

func (e TemplateMismatchError) Error() string

type Type

type Type int

Type is a datatype according to RFC7011

const (
	// OctetArrayType as defined by RFC7011
	OctetArrayType Type = iota
	// Unsigned8Type as defined by RFC7011
	Unsigned8Type
	// Unsigned16Type as defined by RFC7011
	Unsigned16Type
	// Unsigned32Type as defined by RFC7011
	Unsigned32Type
	// Unsigned64Type as defined by RFC7011
	Unsigned64Type
	// Signed8Type as defined by RFC7011
	Signed8Type
	// Signed16Type as defined by RFC7011
	Signed16Type
	// Signed32Type as defined by RFC7011
	Signed32Type
	// Signed64Type as defined by RFC7011
	Signed64Type
	// Float32Type as defined by RFC7011
	Float32Type
	// Float64Type as defined by RFC7011
	Float64Type
	// BooleanType as defined by RFC7011
	BooleanType
	// MacAddressType as defined by RFC7011
	MacAddressType
	// StringType as defined by RFC7011
	StringType
	// DateTimeSecondsType as defined by RFC7011
	DateTimeSecondsType
	// DateTimeMillisecondsType as defined by RFC7011
	DateTimeMillisecondsType
	// DateTimeMicrosecondsType as defined by RFC7011
	DateTimeMicrosecondsType
	// DateTimeNanosecondsType as defined by RFC7011
	DateTimeNanosecondsType
	// Ipv4AddressType as defined by RFC7011
	Ipv4AddressType
	// Ipv6AddressType as defined by RFC7011
	Ipv6AddressType
	// BasicListType as defined by RFC7011
	BasicListType
	// IllegalType is an undefined type
	IllegalType = -1
)

func NameToType

func NameToType(x []byte) Type

NameToType converts the given textual representation of a type to the ipfix type. Returns IllegalType if the type is not recognised.

func (Type) String

func (t Type) String() string

type UnknownTemplateError

type UnknownTemplateError int

UnknownTemplateError indicates that the given template id is unknown

func (UnknownTemplateError) Error

func (e UnknownTemplateError) Error() string

Jump to

Keyboard shortcuts

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