Adapt new V9OptionsTemplateFlowSet stub

Resolves #29
This commit is contained in:
Dominik Pataky 2021-04-04 10:35:08 +02:00
parent fcddb49a6a
commit 54e19af8c2

View file

@ -15,7 +15,7 @@ Licensed under MIT License. See LICENSE.
import ipaddress import ipaddress
import struct import struct
__all__ = ["V9DataFlowSet", "V9DataRecord", "V9ExportPacket", "V9Header", "V9TemplateField", __all__ = ["V9DataFlowSet", "V9DataRecord", "V9ExportPacket", "V9Header", "V9TemplateField", "V9OptionsTemplateFlowSet"
"V9TemplateFlowSet", "V9TemplateNotRecognized", "V9TemplateRecord"] "V9TemplateFlowSet", "V9TemplateNotRecognized", "V9TemplateRecord"]
V9_FIELD_TYPES = { V9_FIELD_TYPES = {
@ -194,8 +194,6 @@ class V9DataFlowSet:
raise V9TemplateNotRecognized raise V9TemplateNotRecognized
template = templates[self.template_id] template = templates[self.template_id]
if len(template.fields) == 0:
return #ignore options templates at the moment
# As the field lengths are variable V9 has padding to next 32 Bit # As the field lengths are variable V9 has padding to next 32 Bit
padding_size = 4 - (self.length % 4) # 4 Byte padding_size = 4 - (self.length % 4) # 4 Byte
@ -264,13 +262,18 @@ class V9TemplateRecord:
self.template_id, self.field_count, self.template_id, self.field_count,
' '.join([V9_FIELD_TYPES[field.field_type] for field in self.fields])) ' '.join([V9_FIELD_TYPES[field.field_type] for field in self.fields]))
class V9OptionsTemplateFlowSet: class V9OptionsTemplateFlowSet:
"""An options template flowset. Always uses flowset ID 1.
TODO: not handled at the moment, only stub implementation
"""
def __init__(self, data): def __init__(self, data):
pack = struct.unpack('!HHH', data[:6]) pack = struct.unpack('!HHH', data[:6])
self.flowset_id = pack[0] self.flowset_id = pack[0]
self.length = pack[1] self.length = pack[1]
self.template_id = pack[2] self.template_id = pack[2]
class V9TemplateFlowSet: class V9TemplateFlowSet:
"""A template flowset, which holds an id that is used by data flowsets to """A template flowset, which holds an id that is used by data flowsets to
reference back to the template. The template then has fields which hold reference back to the template. The template then has fields which hold
@ -348,6 +351,7 @@ class V9ExportPacket:
skipped_flowsets_offsets = [] skipped_flowsets_offsets = []
while offset != len(data): while offset != len(data):
flowset_id = struct.unpack('!H', data[offset:offset + 2])[0] flowset_id = struct.unpack('!H', data[offset:offset + 2])[0]
if flowset_id == 0: # TemplateFlowSet always have id 0 if flowset_id == 0: # TemplateFlowSet always have id 0
tfs = V9TemplateFlowSet(data[offset:]) tfs = V9TemplateFlowSet(data[offset:])
@ -361,14 +365,13 @@ class V9ExportPacket:
# Update the templates with the provided templates, even if they are the same # Update the templates with the provided templates, even if they are the same
self._templates.update(tfs.templates) self._templates.update(tfs.templates)
offset += tfs.length offset += tfs.length
elif flowset_id == 1:
otfs = V9OptionsTemplateFlowSet(data[offset:])
if not self._new_templates:
if otfs.template_id not in self._templates:
self._new_templates = True
self._templates.update({otfs.template_id: V9TemplateRecord(otfs.template_id, 0, {})}) elif flowset_id == 1: # Option templates always use ID 1
# TODO: Options templates are ignored, to prevent template ID collision
# (if a collision can occur is not yet tested)
otfs = V9OptionsTemplateFlowSet(data[offset:])
offset += otfs.length offset += otfs.length
else: else:
try: try:
dfs = V9DataFlowSet(data[offset:], self._templates) dfs = V9DataFlowSet(data[offset:], self._templates)