--- /dev/null
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+
+NETFLOW_V1 = 0x01
+NETFLOW_V5 = 0x05
+NETFLOW_V6 = 0x06
+NETFLOW_V7 = 0x07
+NETFLOW_V8 = 0x08
+NETFLOW_V9 = 0x09
+
+
+class NetFlow(object):
+ _PACK_STR = '!H'
+ _NETFLOW_VERSIONS = {}
+
+ @staticmethod
+ def register_netflow_version(version):
+ def _register_netflow_version(cls):
+ NetFlow._NETFLOW_VERSIONS[version] = cls
+ return cls
+ return _register_netflow_version
+
+ def __init__(self):
+ super(NetFlow, self).__init__()
+
+ @classmethod
+ def parser(cls, buf):
+ (version,) = struct.unpack_from(cls._PACK_STR, buf)
+
+ cls_ = cls._NETFLOW_VERSIONS.get(version, None)
+ if cls_:
+ return cls_.parser(buf)
+ else:
+ return None
+
+
+@NetFlow.register_netflow_version(NETFLOW_V5)
+class NetFlowV5(object):
+ _PACK_STR = '!HHIIIIBBH'
+ _MIN_LEN = struct.calcsize(_PACK_STR)
+
+ def __init__(self, version, count, sys_uptime, unix_secs,
+ unix_nsecs, flow_sequence, engine_type, engine_id,
+ sampling_interval, flows=None):
+ self.version = version
+ self.count = count
+ self.sys_uptime = sys_uptime
+ self.unix_secs = unix_secs
+ self.unix_nsecs = unix_nsecs
+ self.flow_sequence = flow_sequence
+ self.engine_type = engine_type
+ self.engine_id = engine_id
+ self.sampling_interval = sampling_interval
+
+ @classmethod
+ def parser(cls, buf):
+ (version, count, sys_uptime, unix_secs, unix_nsecs,
+ flow_sequence, engine_type, engine_id, sampling_interval) = \
+ struct.unpack_from(cls._PACK_STR, buf)
+
+ msg = cls(version, count, sys_uptime, unix_secs, unix_nsecs,
+ flow_sequence, engine_type, engine_id,
+ sampling_interval)
+ offset = cls._MIN_LEN
+ msg.flows = []
+ while len(buf) > offset:
+ f = NetFlowV5Flow.parser(buf, offset)
+ offset += NetFlowV5Flow._MIN_LEN
+ msg.flows.append(f)
+
+ return msg
+
+
+class NetFlowV5Flow(object):
+ _PACK_STR = '!IIIHHIIIIHHxBBBHHBB2x'
+ _MIN_LEN = struct.calcsize(_PACK_STR)
+
+ def __init__(self, srcaddr, dstaddr, nexthop, input_, output,
+ dpkts, doctets, first, last, srcport, dstport,
+ tcp_flags, prot, tos, src_as, dst_as, src_mask,
+ dst_mask):
+ self.srcaddr = srcaddr
+ self.dstaddr = dstaddr
+ self.nexthop = nexthop
+ self.input = input_
+ self.output = output
+ self.dpkts = dpkts
+ self.doctets = doctets
+ self.first = first
+ self.last = last
+ self.srcport = srcport
+ self.dstport = dstport
+ self.tcp_flags = tcp_flags
+ self.prot = prot
+ self.tos = tos
+ self.src_as = src_as
+ self.dst_as = dst_as
+ self.src_mask = src_mask
+ self.dst_mask = dst_mask
+
+ @classmethod
+ def parser(cls, buf, offset):
+ (srcaddr, dstaddr, nexthop, input_, output, dpkts, doctets,
+ first, last, srcport, dstport, tcp_flags, prot, tos, src_as,
+ dst_as, src_mask, dst_mask) = struct.unpack_from(
+ cls._PACK_STR, buf, offset)
+ msg = cls(srcaddr, dstaddr, nexthop, input_, output, dpkts,
+ doctets, first, last, srcport, dstport, tcp_flags,
+ prot, tos, src_as, dst_as, src_mask, dst_mask)
+
+ return msg