-- import "github.com/calmh/ipfix"
Package ipfix implements an IPFIX (RFC 5101) parser and interpreter.
An input stream in the form of an io.Reader is read and chunked into messages. Template management and the standard IPFIX types are implemented so a fully parsed data set can be produced. Vendor fields can be added at runtime.
To read an IPFIX stream, create a Session around a Reader, then call ReadMessage repeatedly.
s := ipfix.NewSession(os.Stdin)
i := ipfix.NewInterpreter(s)
for {
// ReadMessage will block until a full message is available.
msg, err := s.ReadMessage()
if err != nil {
panic(err)
}
for _, record := range msg.DataRecords {
// record contains raw enterpriseId, fieldId => []byte information
fmt.Println(record)
fieldsMap := i.Interpret(&record)
// fieldsMap is a map[string]interface{}, with types
// resolved to their natural equivalents and field
// names resolved for standard fields.
fmt.Println(fieldsMap)
}
}
To add a vendor field to the dictionary so that it will be resolved by Interpret, create a DictionaryEntry and call AddDictionaryEntry.
e := ipfix.DictionaryEntry{Name: "someVendorField", FieldId: 42, EnterpriseId: 123456, Type: ipfix.Int32}
s.AddDictionaryEntry(e)
The MIT license.
varErrRead=errors.New("short read - malformed packet?")varErrVersion=errors.New("incorrect version field in message header - out of sync?")The version field in IPFIX messages should always have the value 10. If it does not, you get this error. It's probably a sign of a bug in the parser or the exporter and that we have lost synchronization with the data stream. Reestablishing the session is the only way forward at this point.
typeDataRecordstruct {
TemplateIduint16Fields [][]byte
}The DataRecord represents a single exported flow. The Fields each describe different aspects of the flow (source and destination address, counters, service, etc.).
typeDictionaryEntrystruct {
NamestringFieldIduint16EnterpriseIduint32TypeFieldType
}DictionaryEntry provied a mapping between an (Enterprise, Field) pair and a Name and Type.
typeFieldTypestringIPFIX type of an Information Element ("Field").
const (
Uint8FieldType="unsigned8"Uint16FieldType="unsigned16"Uint32FieldType="unsigned32"Uint64FieldType="unsigned64"Int8FieldType="signed8"Int16FieldType="signed16"Int32FieldType="signed32"Int64FieldType="signed64"Float32FieldType="float32"Float64FieldType="float64"BooleanFieldType="boolean"MacAddressFieldType="macAddress"OctetArrayFieldType="octetArray"StringFieldType="string"DateTimeSecondsFieldType="dateTimeSeconds"DateTimeMillisecondsFieldType="dateTimeMilliseconds"DateTimeMicrosecondsFieldType="dateTimeMicroseconds"DateTimeNanosecondsFieldType="dateTimeNanoseconds"Ipv4AddressFieldType="ipv4Address"Ipv6AddressFieldType="ipv6Address"
)The available field types as defined by RFC 5102.
typeInterpretedFieldstruct {
NamestringEnterpriseIduint32FieldIduint16Valueinterface{}
RawValue []byte
}An InterpretedField is a field with the field name filled in and the value converted to the appropriate type. If this is not possible (because the name and type of the field is unknown at the time of interpretation), Name will be the empty string, Value will be a nil interface and RawValue will contain the original bytes.
typeInterpreterstruct {
}Interpreter provides translation between the raw bytes of a DataRecord and the actual values as specified by the corresponding template.
funcNewInterpreter(s*Session) *InterpreterNewInterpreter craets a new Interpreter based on the specified Session.
func (i*Interpreter) AddDictionaryEntry(eDictionaryEntry)Add a DictionaryEntry (containing a vendor field) to the dictionary used by Interpret.
func (i*Interpreter) Interpret(ds*DataRecord) []InterpretedFieldInterpret a raw DataRecord into a list of InterpretedFields.
typeMessagestruct {
HeaderMessageHeaderDataRecords []DataRecordTemplateRecords []TemplateRecord
}A Message is the top level construct representing an IPFIX message. A well formed message contains one or more sets of data or template information.
typeMessageHeaderstruct {
Versionuint16// Always 0x0aLengthuint16ExportTimeuint32// Epoch secondsSequenceNumberuint32DomainIduint32
}The MessageHeader provides metadata for the entire Message. The sequence number and domain ID can be used to gain knowledge of messages lost on an unreliable transport such as UDP.
typeSessionstruct {
}The Session is the context for IPFIX messages.
funcNewSession(reader io.Reader) *SessionNewSession initializes a new Session based on the provided io.Reader.
func (s*Session) ReadMessage() (msg*Message, errerror)ReadMessage extracts and returns one message from the IPFIX stream. As long as err is nil, further messages can be read from the stream. Errors are not recoverable -- once an error has been returned, ReadMessage should not be called again on the same session.
typeTemplateFieldSpecifierstruct {
EnterpriseIduint32FieldIduint16Lengthuint16
}The TemplateFieldSpecifier describes the ID and size of the corresponding Fields in a DataRecord.
typeTemplateRecordstruct {
TemplateIduint16FieldSpecifiers []TemplateFieldSpecifier
}The TemplateRecord describes a data template, as used by DataRecords.
