Parsing SNMP MIBs with PySMI


In [57]:
!pip3 install pysmi


Collecting pysmi
  Using cached pysmi-0.3.4-py2.py3-none-any.whl (80 kB)
Requirement already satisfied: ply in /home/mjuenemann/.virtualenvs/pysmi/lib/python3.7/site-packages (from pysmi) (3.11)
Installing collected packages: pysmi
Successfully installed pysmi-0.3.4

Reader

We are creating a Readers for local MIB files.


In [58]:
from pysmi.reader import FileReader, HttpReader

reader = FileReader('/tmp/SNMP-MIBs', recursive=True, ignoreErrors=True)

Parser

There are different Parsers for (strict) SMIv1 and SMIv2 and one that accepts "relaxed" syntax. Given that few SNMP MIBs are syntactically correct, a "relaxed" parser is instantiated.


In [59]:
from pysmi.parser.dialect import smiV1Relaxed
from pysmi.parser.smi import parserFactory

Parser = parserFactory(**smiV1Relaxed)
parser = Parser()

The SmiStarParser() is a convenient short-cut for the same thing.


In [60]:
from pysmi.parser import SmiStarParser
parser = SmiStarParser()

Code Generator

The are Code Generators for JSON and PySNMP-style MIBs.


In [61]:
from pysmi.codegen import JsonCodeGen
codegen = JsonCodeGen()

Writer

The Writer gets the output from the Generator. The FileWriter(path) can be used to save the output to a file inside of path. Alternatively the CallbackWriter() can be used for further processing of the output. The code below shows how it works although in this example it operates similar to the FileWriter().


In [62]:
from pysmi.writer import CallbackWriter

def callback(mibname, doc, context):
    with open('/tmp/SNMP-MIBs-JSON/{}.json'.format(mibname), 'wt') as fp:
        fp.write(doc)
    
writer = CallbackWriter(callback)

Compiler

The Compiler ties the Parser, Code Generator and Writer together.


In [63]:
from pysmi.compiler import MibCompiler

compiler = MibCompiler(parser, codegen, writer)

The reader is added as source to the Compiler.


In [64]:
compiler.addSources(reader)


Out[64]:
<pysmi.compiler.MibCompiler at 0x7f9e4c967f50>

Finally the Compiler can be "run" against some MIB names(!).


In [65]:
status = compiler.compile('IF-MIB', 'VRRP-MIB')

The status shows that the imported MIBs were also compiled.


In [66]:
status


Out[66]:
{'IF-MIB': 'compiled',
 'VRRP-MIB': 'compiled',
 'IANAifType-MIB': 'compiled',
 'SNMPv2-CONF': 'compiled',
 'SNMPv2-MIB': 'compiled',
 'SNMPv2-SMI': 'compiled',
 'SNMPv2-TC': 'compiled'}

The Writer created the JSON files.


In [67]:
!ls /tmp/SNMP-MIBs-JSON


IANAifType-MIB.json    IP-MIB.json	 SNMPv2-SMI.json
IF-MIB.json	       SNMPv2-CONF.json  SNMPv2-TC.json
INET-ADDRESS-MIB.json  SNMPv2-MIB.json	 VRRP-MIB.json

In [68]:
!head /tmp/SNMP-MIBs-JSON/IF-MIB.json


{
  "imports": {
    "class": "imports",
    "IANAifType-MIB": [
      "IANAifType"
    ],
    "SNMPv2-CONF": [
      "MODULE-COMPLIANCE",
      "NOTIFICATION-GROUP",
      "OBJECT-GROUP"

The status will also show if a MIB could not be processed.


In [69]:
status = compiler.compile('MISSING-MIB')
status


Out[69]:
{'MISSING-MIB': 'missing'}