snmp trap handling using snmptrapd, and parsing using pvl.snmp.traps
authorTero Marttila <terom@paivola.fi>
Sat, 03 Jan 2015 20:18:23 +0200
changeset 435 d10e9db3fb24
parent 434 ee5d6abf600e
child 436 18805b3bf382
snmp trap handling using snmptrapd, and parsing using pvl.snmp.traps
bin/pvl.switches-traps
etc/snmptrapd.conf
pvl/snmp/traps.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/pvl.switches-traps	Sat Jan 03 20:18:23 2015 +0200
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+import pvl.args
+import pvl.hosts
+import pvl.snmp.traps
+import pvl.syslog.args
+
+import collections
+import logging; log = logging.getLogger('pvl.switches-traps')
+import optparse
+
+
+def main (argv) :
+    """
+        Process SNMP traps from snmptrapd.
+    """
+
+    parser = optparse.OptionParser(main.__doc__)
+    parser.add_option_group(pvl.args.parser(parser))
+    parser.add_option_group(pvl.hosts.optparser(parser))
+    parser.add_option_group(pvl.syslog.args.parser(parser))
+
+    # input
+    options, args = parser.parse_args(argv[1:])
+    pvl.args.apply(options)
+    
+    # syslog source
+    syslog = pvl.syslog.args.apply(options)
+
+    # XXX: associate with host data
+    #hosts = pvl.hosts.apply(options, args)
+
+    # main
+    for item in syslog:
+        host, values = pvl.snmp.traps.parse_snmptrapd_log(item['msg'])
+
+        print '{}'.format(host)
+
+        for field, value in values.iteritems():
+            print '\t{:55} {}'.format(field, value)
+
+        print
+    
+    return 0
+
+if __name__ == '__main__':
+    pvl.args.main(main)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/snmptrapd.conf	Sat Jan 03 20:18:23 2015 +0200
@@ -0,0 +1,5 @@
+authCommunity   log         we1ooL2ru5ohnael8
+
+outputOption X
+format1     %B %N %w %q %W\t%v\n
+format2     %B\t%v\n
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pvl/snmp/traps.py	Sat Jan 03 20:18:23 2015 +0200
@@ -0,0 +1,66 @@
+"""
+    Trap handling
+"""
+
+TRAP_TYPE = {
+    # Link Down
+    2: 'IF-MIB::linkDown',
+    
+    # Link Up
+    3: 'IF-MIB::linkUp',
+}
+
+# use subtype
+TRAP_TYPE_ENTERPRISE = 6
+
+VALUE_TYPE = {
+
+}
+
+def parse_snmptrapd_log (line):
+    """
+        Parse a line of data logged by snmptrapd using the following formats:
+
+            format1     %B %N %w %q %W\t%v\n
+            format2     %B\t%v\n
+    """
+
+    values = { }
+
+    items = line.split('\t')
+
+    header = items.pop(0)
+    
+    if ' ' in header:
+        # XXX: some kind of compat wrapping of SNMPv1 TRAPs to fit the SNMPv2-TRAP model
+        host, enterprise, trap_type, trap_subtype, trap_descr = header.split(' ', 4)
+
+        trap_type = int(trap_type)
+
+        values['SNMPv2-MIB::snmpTrapEnterprise.0'] = enterprise
+
+        if trap_type == TRAP_TYPE_ENTERPRISE:
+            # XXX: no idea why
+            if trap_subtype.startswith('.'):
+                trap_oid = enterprise + '.0' + trap_subtype
+            else:
+                trap_oid = trap_subtype
+        else:
+            trap_oid = TRAP_TYPE.get(trap_type, trap_type)
+
+        values['SNMPv2-MIB::snmpTrapOID.0'] = trap_oid
+    else:
+        host = header
+
+    for item in items:
+        key, value = item.split(' = ', 1)
+        value_type, value = value.split(': ', 1)
+
+        func = VALUE_TYPE.get(value_type)
+
+        if func:
+            value = func(value)
+        
+        values[key] = value
+    
+    return host, values