netflow: correctly decode options template set (#39)

netflow: correctly decode options template set
This commit is contained in:
Vincent Bernat
2021-09-24 05:46:39 +02:00
committed by GitHub
parent b0b73b2b90
commit 17a96d9911
3 changed files with 73 additions and 27 deletions

View File

@@ -23,7 +23,7 @@ func DecodeNFv9OptionsTemplateSet(payload *bytes.Buffer) ([]NFv9OptionsTemplateR
optsTemplateRecord := NFv9OptionsTemplateRecord{} optsTemplateRecord := NFv9OptionsTemplateRecord{}
err = utils.BinaryDecoder(payload, &optsTemplateRecord.TemplateId, &optsTemplateRecord.ScopeLength, &optsTemplateRecord.OptionLength) err = utils.BinaryDecoder(payload, &optsTemplateRecord.TemplateId, &optsTemplateRecord.ScopeLength, &optsTemplateRecord.OptionLength)
if err != nil { if err != nil {
break return records, err
} }
sizeScope := int(optsTemplateRecord.ScopeLength) / 4 sizeScope := int(optsTemplateRecord.ScopeLength) / 4
@@ -35,7 +35,10 @@ func DecodeNFv9OptionsTemplateSet(payload *bytes.Buffer) ([]NFv9OptionsTemplateR
fields := make([]Field, sizeScope) fields := make([]Field, sizeScope)
for i := 0; i < sizeScope; i++ { for i := 0; i < sizeScope; i++ {
field := Field{} field := Field{}
err = utils.BinaryDecoder(payload, &field) err := utils.BinaryDecoder(payload, &field.Type, &field.Length)
if err != nil {
return records, err
}
fields[i] = field fields[i] = field
} }
optsTemplateRecord.Scopes = fields optsTemplateRecord.Scopes = fields
@@ -43,7 +46,10 @@ func DecodeNFv9OptionsTemplateSet(payload *bytes.Buffer) ([]NFv9OptionsTemplateR
fields = make([]Field, sizeOptions) fields = make([]Field, sizeOptions)
for i := 0; i < sizeOptions; i++ { for i := 0; i < sizeOptions; i++ {
field := Field{} field := Field{}
err = utils.BinaryDecoder(payload, &field) err := utils.BinaryDecoder(payload, &field.Type, &field.Length)
if err != nil {
return records, err
}
fields[i] = field fields[i] = field
} }
optsTemplateRecord.Options = fields optsTemplateRecord.Options = fields
@@ -51,7 +57,7 @@ func DecodeNFv9OptionsTemplateSet(payload *bytes.Buffer) ([]NFv9OptionsTemplateR
records = append(records, optsTemplateRecord) records = append(records, optsTemplateRecord)
} }
return records, nil return records, err
} }
func DecodeIPFIXOptionsTemplateSet(payload *bytes.Buffer) ([]IPFIXOptionsTemplateRecord, error) { func DecodeIPFIXOptionsTemplateSet(payload *bytes.Buffer) ([]IPFIXOptionsTemplateRecord, error) {
@@ -61,7 +67,7 @@ func DecodeIPFIXOptionsTemplateSet(payload *bytes.Buffer) ([]IPFIXOptionsTemplat
optsTemplateRecord := IPFIXOptionsTemplateRecord{} optsTemplateRecord := IPFIXOptionsTemplateRecord{}
err = utils.BinaryDecoder(payload, &optsTemplateRecord.TemplateId, &optsTemplateRecord.FieldCount, &optsTemplateRecord.ScopeFieldCount) err = utils.BinaryDecoder(payload, &optsTemplateRecord.TemplateId, &optsTemplateRecord.FieldCount, &optsTemplateRecord.ScopeFieldCount)
if err != nil { if err != nil {
break return records, err
} }
fields := make([]Field, int(optsTemplateRecord.ScopeFieldCount)) fields := make([]Field, int(optsTemplateRecord.ScopeFieldCount))
@@ -69,7 +75,10 @@ func DecodeIPFIXOptionsTemplateSet(payload *bytes.Buffer) ([]IPFIXOptionsTemplat
field := Field{} field := Field{}
if field.Type&0x8000 != 0 { if field.Type&0x8000 != 0 {
field.PenProvided = true field.PenProvided = true
err = utils.BinaryDecoder(payload, &field.Pen) err := utils.BinaryDecoder(payload, &field.Pen)
if err != nil {
return records, err
}
} }
fields[i] = field fields[i] = field
} }
@@ -82,13 +91,14 @@ func DecodeIPFIXOptionsTemplateSet(payload *bytes.Buffer) ([]IPFIXOptionsTemplat
fields = make([]Field, optionsSize) fields = make([]Field, optionsSize)
for i := 0; i < optionsSize; i++ { for i := 0; i < optionsSize; i++ {
field := Field{} field := Field{}
err = utils.BinaryDecoder(payload, &field.Type) err := utils.BinaryDecoder(payload, &field.Type, &field.Length)
err = utils.BinaryDecoder(payload, &field.Length) if err == nil && field.Type&0x8000 != 0 {
if field.Type&0x8000 != 0 {
field.PenProvided = true field.PenProvided = true
err = utils.BinaryDecoder(payload, &field.Pen) err = utils.BinaryDecoder(payload, &field.Pen)
} }
if err != nil {
return records, nil
}
fields[i] = field fields[i] = field
} }
optsTemplateRecord.Options = fields optsTemplateRecord.Options = fields
@@ -106,7 +116,7 @@ func DecodeTemplateSet(version uint16, payload *bytes.Buffer) ([]TemplateRecord,
templateRecord := TemplateRecord{} templateRecord := TemplateRecord{}
err = utils.BinaryDecoder(payload, &templateRecord.TemplateId, &templateRecord.FieldCount) err = utils.BinaryDecoder(payload, &templateRecord.TemplateId, &templateRecord.FieldCount)
if err != nil { if err != nil {
break return records, err
} }
if int(templateRecord.FieldCount) < 0 { if int(templateRecord.FieldCount) < 0 {
@@ -116,14 +126,15 @@ func DecodeTemplateSet(version uint16, payload *bytes.Buffer) ([]TemplateRecord,
fields := make([]Field, int(templateRecord.FieldCount)) fields := make([]Field, int(templateRecord.FieldCount))
for i := 0; i < int(templateRecord.FieldCount); i++ { for i := 0; i < int(templateRecord.FieldCount); i++ {
field := Field{} field := Field{}
err = utils.BinaryDecoder(payload, &field.Type) err := utils.BinaryDecoder(payload, &field.Type, &field.Length)
err = utils.BinaryDecoder(payload, &field.Length) if err == nil && version == 10 && field.Type&0x8000 != 0 {
if version == 10 && field.Type&0x8000 != 0 {
field.PenProvided = true field.PenProvided = true
field.Type = field.Type ^ 0x8000 field.Type = field.Type ^ 0x8000
err = utils.BinaryDecoder(payload, &field.Pen) err = utils.BinaryDecoder(payload, &field.Pen)
} }
if err != nil {
return records, err
}
fields[i] = field fields[i] = field
} }
templateRecord.Fields = fields templateRecord.Fields = fields
@@ -155,9 +166,15 @@ func DecodeDataSetUsingFields(version uint16, payload *bytes.Buffer, listFields
if version == 10 && templateField.Length == 0xffff { if version == 10 && templateField.Length == 0xffff {
var variableLen8 byte var variableLen8 byte
var variableLen16 uint16 var variableLen16 uint16
utils.BinaryDecoder(payload, &variableLen8) err := utils.BinaryDecoder(payload, &variableLen8)
if err != nil {
return []DataField{}
}
if variableLen8 == 0xff { if variableLen8 == 0xff {
utils.BinaryDecoder(payload, &variableLen16) err := utils.BinaryDecoder(payload, &variableLen16)
if err != nil {
return []DataField{}
}
finalLength = int(variableLen16) finalLength = int(variableLen16)
} else { } else {
finalLength = int(variableLen8) finalLength = int(variableLen8)
@@ -346,13 +363,19 @@ func DecodeMessage(payload *bytes.Buffer, templates NetFlowTemplateSystem) (inte
binary.Read(payload, binary.BigEndian, &version) binary.Read(payload, binary.BigEndian, &version)
if version == 9 { if version == 9 {
utils.BinaryDecoder(payload, &packetNFv9.Count, &packetNFv9.SystemUptime, &packetNFv9.UnixSeconds, &packetNFv9.SequenceNumber, &packetNFv9.SourceId) err := utils.BinaryDecoder(payload, &packetNFv9.Count, &packetNFv9.SystemUptime, &packetNFv9.UnixSeconds, &packetNFv9.SequenceNumber, &packetNFv9.SourceId)
if err != nil {
return nil, err
}
size = packetNFv9.Count size = packetNFv9.Count
packetNFv9.Version = version packetNFv9.Version = version
returnItem = *(&packetNFv9) returnItem = *(&packetNFv9)
obsDomainId = packetNFv9.SourceId obsDomainId = packetNFv9.SourceId
} else if version == 10 { } else if version == 10 {
utils.BinaryDecoder(payload, &packetIPFIX.Length, &packetIPFIX.ExportTime, &packetIPFIX.SequenceNumber, &packetIPFIX.ObservationDomainId) err := utils.BinaryDecoder(payload, &packetIPFIX.Length, &packetIPFIX.ExportTime, &packetIPFIX.SequenceNumber, &packetIPFIX.ObservationDomainId)
if err != nil {
return nil, err
}
size = packetIPFIX.Length size = packetIPFIX.Length
packetIPFIX.Version = version packetIPFIX.Version = version
returnItem = *(&packetIPFIX) returnItem = *(&packetIPFIX)
@@ -363,7 +386,9 @@ func DecodeMessage(payload *bytes.Buffer, templates NetFlowTemplateSystem) (inte
for i := 0; ((i < int(size) && version == 9) || version == 10) && payload.Len() > 0; i++ { for i := 0; ((i < int(size) && version == 9) || version == 10) && payload.Len() > 0; i++ {
fsheader := FlowSetHeader{} fsheader := FlowSetHeader{}
utils.BinaryDecoder(payload, &fsheader) if err := utils.BinaryDecoder(payload, &fsheader); err != nil {
return returnItem, err
}
nextrelpos := int(fsheader.Length) - binary.Size(fsheader) nextrelpos := int(fsheader.Length) - binary.Size(fsheader)
if nextrelpos < 0 { if nextrelpos < 0 {

View File

@@ -23,7 +23,10 @@ func (e *ErrorVersion) Error() string {
func DecodeMessage(payload *bytes.Buffer) (interface{}, error) { func DecodeMessage(payload *bytes.Buffer) (interface{}, error) {
var version uint16 var version uint16
utils.BinaryDecoder(payload, &version) err := utils.BinaryDecoder(payload, &version)
if err != nil {
return nil, err
}
packet := PacketNetFlowV5{} packet := PacketNetFlowV5{}
if version == 5 { if version == 5 {
packet.Version = version packet.Version = version
@@ -42,7 +45,10 @@ func DecodeMessage(payload *bytes.Buffer) (interface{}, error) {
packet.Records = make([]RecordsNetFlowV5, int(packet.Count)) packet.Records = make([]RecordsNetFlowV5, int(packet.Count))
for i := 0; i < int(packet.Count) && payload.Len() >= 48; i++ { for i := 0; i < int(packet.Count) && payload.Len() >= 48; i++ {
record := RecordsNetFlowV5{} record := RecordsNetFlowV5{}
utils.BinaryDecoder(payload, &record) err := utils.BinaryDecoder(payload, &record)
if err != nil {
return packet, err
}
packet.Records[i] = record packet.Records[i] = record
} }

View File

@@ -81,11 +81,17 @@ func DecodeCounterRecord(header *RecordHeader, payload *bytes.Buffer) (CounterRe
switch (*header).DataFormat { switch (*header).DataFormat {
case 1: case 1:
ifCounters := IfCounters{} ifCounters := IfCounters{}
utils.BinaryDecoder(payload, &ifCounters) err := utils.BinaryDecoder(payload, &ifCounters)
if err != nil {
return counterRecord, err
}
counterRecord.Data = ifCounters counterRecord.Data = ifCounters
case 2: case 2:
ethernetCounters := EthernetCounters{} ethernetCounters := EthernetCounters{}
utils.BinaryDecoder(payload, &ethernetCounters) err := utils.BinaryDecoder(payload, &ethernetCounters)
if err != nil {
return counterRecord, err
}
counterRecord.Data = ethernetCounters counterRecord.Data = ethernetCounters
default: default:
return counterRecord, NewErrorDataFormat((*header).DataFormat) return counterRecord, NewErrorDataFormat((*header).DataFormat)
@@ -96,7 +102,10 @@ func DecodeCounterRecord(header *RecordHeader, payload *bytes.Buffer) (CounterRe
func DecodeIP(payload *bytes.Buffer) (uint32, []byte, error) { func DecodeIP(payload *bytes.Buffer) (uint32, []byte, error) {
var ipVersion uint32 var ipVersion uint32
utils.BinaryDecoder(payload, &ipVersion) err := utils.BinaryDecoder(payload, &ipVersion)
if err != nil {
return 0, nil, err
}
var ip []byte var ip []byte
if ipVersion == 1 { if ipVersion == 1 {
ip = make([]byte, 4) ip = make([]byte, 4)
@@ -106,7 +115,10 @@ func DecodeIP(payload *bytes.Buffer) (uint32, []byte, error) {
return ipVersion, ip, NewErrorIPVersion(ipVersion) return ipVersion, ip, NewErrorIPVersion(ipVersion)
} }
if payload.Len() >= len(ip) { if payload.Len() >= len(ip) {
utils.BinaryDecoder(payload, &ip) err := utils.BinaryDecoder(payload, &ip)
if err != nil {
return 0, nil, err
}
} else { } else {
return ipVersion, ip, NewErrorDecodingSFlow(fmt.Sprintf("Not enough data: %v, needs %v.", payload.Len(), len(ip))) return ipVersion, ip, NewErrorDecodingSFlow(fmt.Sprintf("Not enough data: %v, needs %v.", payload.Len(), len(ip)))
} }
@@ -354,7 +366,10 @@ func DecodeMessage(payload *bytes.Buffer) (interface{}, error) {
var ip []byte var ip []byte
if packetV5.IPVersion == 1 { if packetV5.IPVersion == 1 {
ip = make([]byte, 4) ip = make([]byte, 4)
utils.BinaryDecoder(payload, ip) err = utils.BinaryDecoder(payload, ip)
if err != nil {
return packetV5, err
}
} else if packetV5.IPVersion == 2 { } else if packetV5.IPVersion == 2 {
ip = make([]byte, 16) ip = make([]byte, 16)
err = utils.BinaryDecoder(payload, ip) err = utils.BinaryDecoder(payload, ip)