1#! /usr/bin/env python
2## ------------------------------------------------------------------------
3## sample_exporter_collector_blind.py
4##
5## sample IPFIX collector & exporter (aka mediator) using pyfixbuf.
6## created to be used with the sample_exporter.py script.
7## Processes the ipfix file created by sample_exporter.py and writes
8## to a text file.  This is different from sample_exporter_collector.py
9## in that it has no idea what to expect.
10## ------------------------------------------------------------------------
11## Copyright (C) 2013-2019 Carnegie Mellon University. All Rights Reserved.
12## ------------------------------------------------------------------------
13## Authors: Emily Sarneso <ecoff@cert.org>
14## ------------------------------------------------------------------------
15## See license information in LICENSE-OPENSOURCE.txt
16
17from __future__ import print_function
18import os
19import sys
20import pyfixbuf
21import pyfixbuf.cert
22from pyfixbuf import DataType
23
24# Test that the argument number is correct
25if (len(sys.argv) < 2 or sys.argv[1] in ['-h', '--help']):
26    print("Must supply an IPFIX file to read and (optional) text file "
27          "to write to.")
28    sys.exit()
29
30
31#create the information model with the standard IPFIX elements
32infomodel = pyfixbuf.InfoModel()
33
34# add YAF's IPFIX elements
35pyfixbuf.cert.add_elements_to_model(infomodel)
36
37# create the collector
38collector = pyfixbuf.Collector()
39
40# create the IPFIX file to read from
41collector.init_file(sys.argv[1])
42
43# create the session
44session = pyfixbuf.Session(infomodel)
45
46# create the buffer for the collector, set auto to True to
47# automatically generate templates
48buf = pyfixbuf.Buffer(auto=True)
49
50# make the buffer an import buffer
51buf.init_collection(session, collector)
52
53# set auto insert on buffer in case we receive any Info Element Options Recs
54buf.auto_insert()
55
56if (len(sys.argv) > 2 and sys.argv[2] != "-"):
57    outFile = open(sys.argv[2], "w")
58else:
59    outFile = sys.stdout
60
61flowcount = 0
62
63dontprintlist = [DataType.BASIC_LIST, DataType.SUB_TMPL_LIST,
64                 DataType.SUB_TMPL_MULTI_LIST, DataType.OCTET_ARRAY]
65
66def do_record(rec):
67    for field in rec.iterfields():
68        ty = field.ie.type
69        if ty not in dontprintlist:
70            outFile.write("%s: %s\n" % (field.name, str(field.value)))
71        elif ty == DataType.BASIC_LIST:
72            do_bl(field)
73        elif ty == DataType.SUB_TMPL_LIST:
74            do_stl(rec, field)
75        elif ty == DataType.SUB_TMPL_MULTI_LIST:
76            do_stml(rec, field)
77        elif field.name == "paddingOctets":
78            outFile.write("%s: (len %d)\n" % (field.name, len(field.value)))
79        else:
80            # handle octet array that is not padding
81            outFile.write("%s: %s\n" % (field.name, str(field.value)))
82
83def do_bl(field):
84    bl = field.value
85    name = bl.element.name
86    outFile.write("%s:\n--- BL (ie = %s, count = %d) ---\n" %
87                  (field.name, name, len(bl)))
88    count = 0
89    for item in bl:
90        outFile.write("%s[%d]: %s\n" % (name, count, str(item)))
91        count += 1
92    bl.clear()
93
94def do_stl(parent, field):
95    #stl = parent[(field.name, field.instance)]
96    stl = field.value
97    outFile.write("%s:\n--- STL ---\n" % field.name)
98    recs = 0
99    for record in stl:
100        outFile.write("-- REC %d --\n" % recs)
101        do_record(record)
102        recs += 1
103    stl.clear()
104
105def do_stml(parent, field):
106    #stml = parent[(field.name, field.instance)]
107    stml = field.value
108    outFile.write("%s:\n" % field.name)
109    subs = 0
110    for entry in stml:
111        outFile.write("--- STML %d ---\n" % subs)
112        recs = 0
113        for record in entry:
114            outFile.write("-- ENTRY %d --\n" % recs)
115            do_record(record)
116            recs += 1
117        subs += 1
118    stml.clear()
119
120
121for data in buf:
122    do_record(data)
123    outFile.write("------------------------------\n")
124    flowcount += 1
125
126sys.stderr.write("Processed %d flows\n" % flowcount)
127