Rename classes in v1, v5 and v9 according to version
Until now, every NetFlow version file used similar names for their classes, e.g. "Header". These are now prefixed with their respective version, e.g. "V1Header", to avoid confusion in imports etc.
This commit is contained in:
parent
5fd4e9bd24
commit
e8073013c1
|
@ -14,9 +14,9 @@ See https://github.com/djmdjm/softflowd
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
|
||||||
class DataFlow:
|
class V1DataFlow:
|
||||||
"""Holds one v1 DataRecord"""
|
"""Holds one v1 DataRecord
|
||||||
|
"""
|
||||||
length = 48
|
length = 48
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
@ -42,9 +42,9 @@ class DataFlow:
|
||||||
return "<DataRecord with data {}>".format(self.data)
|
return "<DataRecord with data {}>".format(self.data)
|
||||||
|
|
||||||
|
|
||||||
class Header:
|
class V1Header:
|
||||||
"""The header of the V1ExportPacket"""
|
"""The header of the V1ExportPacket
|
||||||
|
"""
|
||||||
length = 16
|
length = 16
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
@ -57,11 +57,12 @@ class Header:
|
||||||
|
|
||||||
|
|
||||||
class V1ExportPacket:
|
class V1ExportPacket:
|
||||||
"""The flow record holds the header and data flowsets."""
|
"""The flow record holds the header and data flowsets.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.flows = []
|
self.flows = []
|
||||||
self.header = Header(data)
|
self.header = V1Header(data)
|
||||||
|
|
||||||
offset = self.header.length
|
offset = self.header.length
|
||||||
for flow_count in range(0, self.header.count):
|
for flow_count in range(0, self.header.count):
|
||||||
|
|
|
@ -5,18 +5,15 @@ Netflow V5 collector and parser implementation in Python 3.
|
||||||
Created purely for fun. Not battled tested nor will it be.
|
Created purely for fun. Not battled tested nor will it be.
|
||||||
|
|
||||||
Reference: https://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html
|
Reference: https://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html
|
||||||
|
This script is specifically implemented in combination with softflowd. See https://github.com/djmdjm/softflowd
|
||||||
This script is specifically implemented in combination with softflowd.
|
|
||||||
See https://github.com/djmdjm/softflowd
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
|
||||||
class DataFlow:
|
class V5DataFlow:
|
||||||
"""Holds one v5 DataRecord"""
|
"""Holds one v5 DataRecord
|
||||||
|
"""
|
||||||
length = 48
|
length = 48
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
@ -46,9 +43,9 @@ class DataFlow:
|
||||||
return "<DataRecord with data {}>".format(self.data)
|
return "<DataRecord with data {}>".format(self.data)
|
||||||
|
|
||||||
|
|
||||||
class Header:
|
class V5Header:
|
||||||
"""The header of the V5ExportPacket"""
|
"""The header of the V5ExportPacket
|
||||||
|
"""
|
||||||
length = 24
|
length = 24
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
@ -65,15 +62,15 @@ class Header:
|
||||||
|
|
||||||
|
|
||||||
class V5ExportPacket:
|
class V5ExportPacket:
|
||||||
"""The flow record holds the header and data flowsets."""
|
"""The flow record holds the header and data flowsets.
|
||||||
|
"""
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.flows = []
|
self.flows = []
|
||||||
self.header = Header(data)
|
self.header = V5Header(data)
|
||||||
|
|
||||||
offset = self.header.length
|
offset = self.header.length
|
||||||
for flow_count in range(0, self.header.count):
|
for flow_count in range(0, self.header.count):
|
||||||
flow = DataFlow(data[offset:])
|
flow = V5DataFlow(data[offset:])
|
||||||
self.flows.append(flow)
|
self.flows.append(flow)
|
||||||
offset += flow.length
|
offset += flow.length
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ class TemplateNotRecognized(KeyError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DataRecord:
|
class V9DataRecord:
|
||||||
"""This is a 'flow' as we want it from our source. What it contains is
|
"""This is a 'flow' as we want it from our source. What it contains is
|
||||||
variable in NetFlow V9, so to work with the data you have to analyze the
|
variable in NetFlow V9, so to work with the data you have to analyze the
|
||||||
data dict keys (which are integers and can be mapped with the FIELD_TYPES
|
data dict keys (which are integers and can be mapped with the FIELD_TYPES
|
||||||
|
@ -173,7 +173,7 @@ class DataRecord:
|
||||||
return "<DataRecord with data: {}>".format(self.data)
|
return "<DataRecord with data: {}>".format(self.data)
|
||||||
|
|
||||||
|
|
||||||
class DataFlowSet:
|
class V9DataFlowSet:
|
||||||
"""Holds one or multiple DataRecord which are all defined after the same
|
"""Holds one or multiple DataRecord which are all defined after the same
|
||||||
template. This template is referenced in the field 'flowset_id' of this
|
template. This template is referenced in the field 'flowset_id' of this
|
||||||
DataFlowSet and must not be zero.
|
DataFlowSet and must not be zero.
|
||||||
|
@ -196,7 +196,7 @@ class DataFlowSet:
|
||||||
padding_size = 4 - (self.length % 4) # 4 Byte
|
padding_size = 4 - (self.length % 4) # 4 Byte
|
||||||
|
|
||||||
while offset <= (self.length - padding_size):
|
while offset <= (self.length - padding_size):
|
||||||
new_record = DataRecord()
|
new_record = V9DataRecord()
|
||||||
|
|
||||||
for field in template.fields:
|
for field in template.fields:
|
||||||
flen = field.field_length
|
flen = field.field_length
|
||||||
|
@ -230,7 +230,7 @@ class DataFlowSet:
|
||||||
.format(self.template_id, self.length, len(self.flows))
|
.format(self.template_id, self.length, len(self.flows))
|
||||||
|
|
||||||
|
|
||||||
class TemplateField:
|
class V9TemplateField:
|
||||||
"""A field with type identifier and length."""
|
"""A field with type identifier and length."""
|
||||||
def __init__(self, field_type, field_length):
|
def __init__(self, field_type, field_length):
|
||||||
self.field_type = field_type # integer
|
self.field_type = field_type # integer
|
||||||
|
@ -241,7 +241,7 @@ class TemplateField:
|
||||||
self.field_type, FIELD_TYPES[self.field_type], self.field_length)
|
self.field_type, FIELD_TYPES[self.field_type], self.field_length)
|
||||||
|
|
||||||
|
|
||||||
class TemplateRecord:
|
class V9TemplateRecord:
|
||||||
"""A template record contained in a TemplateFlowSet."""
|
"""A template record contained in a TemplateFlowSet."""
|
||||||
def __init__(self, template_id, field_count, fields):
|
def __init__(self, template_id, field_count, fields):
|
||||||
self.template_id = template_id
|
self.template_id = template_id
|
||||||
|
@ -254,7 +254,7 @@ class TemplateRecord:
|
||||||
' '.join([FIELD_TYPES[field.field_type] for field in self.fields]))
|
' '.join([FIELD_TYPES[field.field_type] for field in self.fields]))
|
||||||
|
|
||||||
|
|
||||||
class TemplateFlowSet:
|
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
|
||||||
identifiers of data types (eg "IP_SRC_ADDR", "PKTS"..). This way the flow
|
identifiers of data types (eg "IP_SRC_ADDR", "PKTS"..). This way the flow
|
||||||
|
@ -281,11 +281,11 @@ class TemplateFlowSet:
|
||||||
field_type, field_length = struct.unpack('!HH', data[offset:offset+4])
|
field_type, field_length = struct.unpack('!HH', data[offset:offset+4])
|
||||||
if field_type not in FIELD_TYPES:
|
if field_type not in FIELD_TYPES:
|
||||||
field_type = 0 # Set field_type to UNKNOWN_FIELD_TYPE as fallback
|
field_type = 0 # Set field_type to UNKNOWN_FIELD_TYPE as fallback
|
||||||
field = TemplateField(field_type, field_length)
|
field = V9TemplateField(field_type, field_length)
|
||||||
fields.append(field)
|
fields.append(field)
|
||||||
|
|
||||||
# Create a template object with all collected data
|
# Create a template object with all collected data
|
||||||
template = TemplateRecord(template_id, field_count, fields)
|
template = V9TemplateRecord(template_id, field_count, fields)
|
||||||
|
|
||||||
# Append the new template to the global templates list
|
# Append the new template to the global templates list
|
||||||
self.templates[template.template_id] = template
|
self.templates[template.template_id] = template
|
||||||
|
@ -298,7 +298,7 @@ class TemplateFlowSet:
|
||||||
.format(self.flowset_id, self.length, self.templates.keys())
|
.format(self.flowset_id, self.length, self.templates.keys())
|
||||||
|
|
||||||
|
|
||||||
class Header:
|
class V9Header:
|
||||||
"""The header of the V9ExportPacket"""
|
"""The header of the V9ExportPacket"""
|
||||||
length = 20
|
length = 20
|
||||||
|
|
||||||
|
@ -326,9 +326,8 @@ class Header:
|
||||||
|
|
||||||
class V9ExportPacket:
|
class V9ExportPacket:
|
||||||
"""The flow record holds the header and all template and data flowsets."""
|
"""The flow record holds the header and all template and data flowsets."""
|
||||||
|
|
||||||
def __init__(self, data, templates):
|
def __init__(self, data, templates):
|
||||||
self.header = Header(data)
|
self.header = V9Header(data)
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
self._new_templates = False
|
self._new_templates = False
|
||||||
self.flows = []
|
self.flows = []
|
||||||
|
@ -337,7 +336,7 @@ class V9ExportPacket:
|
||||||
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 = TemplateFlowSet(data[offset:])
|
tfs = V9TemplateFlowSet(data[offset:])
|
||||||
# Check for any new/changed templates
|
# Check for any new/changed templates
|
||||||
if not self._new_templates:
|
if not self._new_templates:
|
||||||
for id_, template in tfs.templates.items():
|
for id_, template in tfs.templates.items():
|
||||||
|
@ -347,7 +346,7 @@ class V9ExportPacket:
|
||||||
self.templates.update(tfs.templates)
|
self.templates.update(tfs.templates)
|
||||||
offset += tfs.length
|
offset += tfs.length
|
||||||
else:
|
else:
|
||||||
dfs = DataFlowSet(data[offset:], self.templates)
|
dfs = V9DataFlowSet(data[offset:], self.templates)
|
||||||
self.flows += dfs.flows
|
self.flows += dfs.flows
|
||||||
offset += dfs.length
|
offset += dfs.length
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue