IPFIX: add template withdrawal handling; bump version to v0.10.2

Templates may be withdrawn as per RFC7011. Receiving a template with an
existing template_id and a field_count of 0 now triggers deletion of
this template.
This commit is contained in:
Dominik Pataky 2020-04-06 17:27:26 +02:00
parent 742f5a0a48
commit 5d1c5b8710
3 changed files with 15 additions and 5 deletions

View file

@ -814,15 +814,21 @@ class IPFIXSet:
while offset < self.header.length: # length of whole set
template_record = IPFIXTemplateRecord(data[offset:])
self.records.append(template_record)
self._templates[template_record.template_id] = template_record.fields
if template_record.field_count == 0:
self._templates[template_record.template_id] = None
else:
self._templates[template_record.template_id] = template_record.fields
offset += template_record.get_length()
elif self.header.set_id == 3: # options template
while offset < self.header.length:
optionstemplate_record = IPFIXOptionsTemplateRecord(data[offset:])
self.records.append(optionstemplate_record)
self._templates[optionstemplate_record.template_id] = \
optionstemplate_record.scope_fields + optionstemplate_record.fields
if optionstemplate_record.field_count == 0:
self._templates[optionstemplate_record.template_id] = None
else:
self._templates[optionstemplate_record.template_id] = \
optionstemplate_record.scope_fields + optionstemplate_record.fields
offset += optionstemplate_record.get_length()
elif self.header.set_id >= 256: # data set, set_id is template id
@ -883,7 +889,6 @@ class IPFIXSetHeader:
class IPFIXExportPacket:
"""IPFIX export packet with header, templates, options and data flowsets
"""
def __init__(self, data: bytes, templates: Dict[int, list]):
self.header = IPFIXHeader(data[:IPFIXHeader.size])
self.sets = []
@ -900,6 +905,10 @@ class IPFIXExportPacket:
if new_set.is_template:
self._contains_new_templates = True
self._templates.update(new_set.templates)
for template_id, template_fields in self._templates.items():
if template_fields is None:
# Template withdrawal
del self._templates[template_id]
elif new_set.is_data:
self._flows += new_set.records

View file

@ -7,7 +7,7 @@ with open("README.md", "r") as fh:
setup(
name='netflow',
version='0.10.1',
version='0.10.2',
description='NetFlow v1, v5, v9 and IPFIX tool suite implemented in Python 3',
long_description=long_description,
long_description_content_type='text/markdown',

View file

@ -7,6 +7,7 @@ Copyright 2016-2020 Dominik Pataky <dev@bitkeks.eu>
Licensed under MIT License. See LICENSE.
"""
# TODO: tests with 500 packets fail with delay=0. Probably a problem with UDP sockets buffer
# TODO: add test for template withdrawal
import ipaddress
import unittest