bugfix: variable length, missing option templates

This commit is contained in:
lspgn
2021-05-25 21:52:59 -07:00
parent e4bacbc4bd
commit 1fda65fe41

View File

@@ -67,7 +67,10 @@ func DecodeIPFIXOptionsTemplateSet(payload *bytes.Buffer) ([]IPFIXOptionsTemplat
fields := make([]Field, int(optsTemplateRecord.ScopeFieldCount)) fields := make([]Field, int(optsTemplateRecord.ScopeFieldCount))
for i := 0; i < int(optsTemplateRecord.ScopeFieldCount); i++ { for i := 0; i < int(optsTemplateRecord.ScopeFieldCount); i++ {
field := Field{} field := Field{}
err = utils.BinaryDecoder(payload, &field) if field.Type&0x8000 != 0 {
field.PenProvided = true
err = utils.BinaryDecoder(payload, &field.Pen)
}
fields[i] = field fields[i] = field
} }
optsTemplateRecord.Scopes = fields optsTemplateRecord.Scopes = fields
@@ -79,7 +82,13 @@ 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) err = utils.BinaryDecoder(payload, &field.Type)
err = utils.BinaryDecoder(payload, &field.Length)
if field.Type&0x8000 != 0 {
field.PenProvided = true
err = utils.BinaryDecoder(payload, &field.Pen)
}
fields[i] = field fields[i] = field
} }
optsTemplateRecord.Options = fields optsTemplateRecord.Options = fields
@@ -123,19 +132,22 @@ func DecodeTemplateSet(version uint16, payload *bytes.Buffer) ([]TemplateRecord,
return records, nil return records, nil
} }
func GetTemplateSize(template []Field) int { func GetTemplateSize(version uint16, template []Field) int {
sum := 0 sum := 0
for _, templateField := range template { for _, templateField := range template {
if version == 10 && templateField.Length == 0xffff {
continue
}
sum += int(templateField.Length) sum += int(templateField.Length)
} }
return sum return sum
} }
func DecodeDataSetUsingFields(version uint16, payload *bytes.Buffer, listFields []Field) []DataField { func DecodeDataSetUsingFields(version uint16, payload *bytes.Buffer, listFields []Field) []DataField {
for payload.Len() >= GetTemplateSize(listFields) { for payload.Len() >= GetTemplateSize(version, listFields) {
dataFields := make([]DataField, len(listFields)) dataFields := make([]DataField, len(listFields))
for i, templateField := range listFields { for i, templateField := range listFields {
finalLength := int(templateField.Length) finalLength := int(templateField.Length)
@@ -149,7 +161,6 @@ func DecodeDataSetUsingFields(version uint16, payload *bytes.Buffer, listFields
} else { } else {
finalLength = int(variableLen8) finalLength = int(variableLen8)
} }
} }
value := payload.Next(finalLength) value := payload.Next(finalLength)
@@ -229,14 +240,12 @@ func (e *ErrorDecodingNetFlow) Error() string {
func DecodeOptionsDataSet(version uint16, payload *bytes.Buffer, listFieldsScopes, listFieldsOption []Field) ([]OptionsDataRecord, error) { func DecodeOptionsDataSet(version uint16, payload *bytes.Buffer, listFieldsScopes, listFieldsOption []Field) ([]OptionsDataRecord, error) {
records := make([]OptionsDataRecord, 0) records := make([]OptionsDataRecord, 0)
listFieldsScopesSize := GetTemplateSize(listFieldsScopes) listFieldsScopesSize := GetTemplateSize(version, listFieldsScopes)
listFieldsOptionSize := GetTemplateSize(listFieldsOption) listFieldsOptionSize := GetTemplateSize(version, listFieldsOption)
for payload.Len() >= listFieldsScopesSize+listFieldsOptionSize { for payload.Len() >= listFieldsScopesSize+listFieldsOptionSize {
payloadLim := bytes.NewBuffer(payload.Next(listFieldsScopesSize)) scopeValues := DecodeDataSetUsingFields(version, payload, listFieldsScopes)
scopeValues := DecodeDataSetUsingFields(version, payloadLim, listFieldsScopes) optionValues := DecodeDataSetUsingFields(version, payload, listFieldsOption)
payloadLim = bytes.NewBuffer(payload.Next(listFieldsOptionSize))
optionValues := DecodeDataSetUsingFields(version, payloadLim, listFieldsOption)
record := OptionsDataRecord{ record := OptionsDataRecord{
ScopesValues: scopeValues, ScopesValues: scopeValues,
@@ -251,10 +260,9 @@ func DecodeOptionsDataSet(version uint16, payload *bytes.Buffer, listFieldsScope
func DecodeDataSet(version uint16, payload *bytes.Buffer, listFields []Field) ([]DataRecord, error) { func DecodeDataSet(version uint16, payload *bytes.Buffer, listFields []Field) ([]DataRecord, error) {
records := make([]DataRecord, 0) records := make([]DataRecord, 0)
listFieldsSize := GetTemplateSize(listFields) listFieldsSize := GetTemplateSize(version, listFields)
for payload.Len() >= listFieldsSize { for payload.Len() >= listFieldsSize {
payloadLim := bytes.NewBuffer(payload.Next(listFieldsSize)) values := DecodeDataSetUsingFields(version, payload, listFields)
values := DecodeDataSetUsingFields(version, payloadLim, listFields)
record := DataRecord{ record := DataRecord{
Values: values, Values: values,