diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e22d2d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.*egg-info.* +build* +dist* +.*python_netflow_v9_softflowd.egg-info/ +*.swp +*.swo diff --git a/main.py b/main.py new file mode 100644 index 0000000..0af4786 --- /dev/null +++ b/main.py @@ -0,0 +1,55 @@ +import logging +import argparse +import sys +import SocketServer +from netflow.collector_v9 import ExportPacket + +logging.getLogger().setLevel(logging.INFO) +ch = logging.StreamHandler(sys.stdout) +ch.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(message)s') +ch.setFormatter(formatter) +logging.getLogger().addHandler(ch) + +parser = argparse.ArgumentParser(description='A sample netflow collector.') + +parser.add_argument('-chost', type=str, default='', + help='collector listening address') +parser.add_argument('-cport', type=int, default=2055, + help='collector listener port') + + +class SoftflowUDPHandler(SocketServer.BaseRequestHandler): + # We need to save the templates our NetFlow device + # send over time. Templates are not resended every + # time a flow is sent to the collector. + TEMPLATES = {} + + @classmethod + def get_server(cls, host, port): + logging.info("Listening on interface {}:{}".format(host, port)) + server = SocketServer.UDPServer((host, port), cls) + return server + + def handle(self): + data = self.request[0] + host = self.client_address[0] + s = "Received data from {}, length {}".format(host, len(data)) + logging.info(s) + export = ExportPacket(data, self.TEMPLATES) + self.TEMPLATES.update(export.templates) + s = "Processed ExportPacket with {} flows.".format(export.header.count) + logging.info(s) + return export + +if __name__ == "__main__": + args = parser.parse_args() + server = SoftflowUDPHandler.get_server(args.chost, args.cport) + + try: + logging.debug("Starting the NetFlow listener") + server.serve_forever(poll_interval=0.5) + except (IOError, SystemExit): + raise + except KeyboardInterrupt: + raise diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c954cec --- /dev/null +++ b/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +from setuptools import setup, find_packages +import os + + +data_files = [(d, [os.path.join(d, f) for f in files]) + for d, folders, files in os.walk(os.path.join('src', 'config'))] + +setup(name='python-netflow-v9-softflowd', + version='1.0', + description='NetFlow v9 parser and collector implemented in Python 3. Developed to be used with softflowd v0.9.9', + author='coox', + author_email='gro.rotarocedten@mod', + packages=find_packages('src'), + package_dir={'': 'src'}, +) diff --git a/src/netflow/__init__.py b/src/netflow/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/collector-v9.py b/src/netflow/collector_v9.py similarity index 99% rename from collector-v9.py rename to src/netflow/collector_v9.py index ad69062..728a68e 100644 --- a/collector-v9.py +++ b/src/netflow/collector_v9.py @@ -15,8 +15,6 @@ import socket import struct import sys -HOST = sys.argv[1] -PORT = int(sys.argv[2]) field_types = { 1: 'IN_BYTES', @@ -278,6 +276,8 @@ if __name__ == "__main__": # We need to save the templates our NetFlow device send over time. Templates # are not resended every time a flow is sent to the collector. _templates = {} + HOST = sys.argv[1] + PORT = int(sys.argv[2]) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((HOST, PORT))