forked from bitkeks/python-netflow-v9-softflowd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathv1.py
86 lines (68 loc) · 2.36 KB
/
v1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3
"""
Netflow V1 collector and parser implementation in Python 3.
This file belongs to https://github.com/bitkeks/python-netflow-v9-softflowd.
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
This script is specifically implemented in combination with softflowd. See https://github.com/djmdjm/softflowd
"""
import struct
__all__ = ["V1DataFlow", "V1ExportPacket", "V1Header"]
class V1DataFlow:
"""Holds one v1 DataRecord
"""
length = 48
def __init__(self, data):
pack = struct.unpack('!IIIHHIIIIHHxxBBBxxxxxxx', data)
fields = [
'IPV4_SRC_ADDR',
'IPV4_DST_ADDR',
'NEXT_HOP',
'INPUT',
'OUTPUT',
'IN_PACKETS',
'IN_OCTETS',
'FIRST_SWITCHED',
'LAST_SWITCHED',
'SRC_PORT',
'DST_PORT',
# Word at 36-37 is used for padding
'PROTO',
'TOS',
'TCP_FLAGS',
# Data at 41-47 is padding/reserved
]
self.data = {}
for idx, field in enumerate(fields):
self.data[field] = pack[idx]
self.__dict__.update(self.data) # Make data dict entries accessible as object attributes
def __repr__(self):
return "<DataRecord with data {}>".format(self.data)
class V1Header:
"""The header of the V1ExportPacket
"""
length = 16
def __init__(self, data):
pack = struct.unpack('!HHIII', data[:self.length])
self.version = pack[0]
self.count = pack[1]
self.uptime = pack[2]
self.timestamp = pack[3]
self.timestamp_nano = pack[4]
def to_dict(self):
return self.__dict__
class V1ExportPacket:
"""The flow record holds the header and data flowsets.
"""
def __init__(self, data):
self.flows = []
self.header = V1Header(data)
offset = self.header.length
for flow_count in range(0, self.header.count):
end = offset + V1DataFlow.length
flow = V1DataFlow(data[offset:end])
self.flows.append(flow)
offset += flow.length
def __repr__(self):
return "<ExportPacket v{} with {} records>".format(
self.header.version, self.header.count)