Skip to content

Instantly share code, notes, and snippets.

@emschu
Last active June 4, 2020 09:16
Show Gist options
  • Save emschu/d22dba9206b3bea99ae90af25c9eba71 to your computer and use it in GitHub Desktop.
Save emschu/d22dba9206b3bea99ae90af25c9eba71 to your computer and use it in GitHub Desktop.
Generate JSON OID Tree and catalog representation

How-To generate a JSON Tree out of a MIB Tree

This is an approach to generate dynamically a JSON representation of an OID tree (=an(y) SNMP MIB) using mibdump.py of python pysmi.

We will generate a flat list of OID objects (oid_catalog.json) + hierarchical json tree (oid_tree.json) with "."-separated nodes of RFC 1213 MIB.

1. Setup + get MIB(s) as JSON

$ pip install pysmi
# walk into and/or create a new directory you run the following command in
$ mibdump.py --destination-format=json --generate-mib-texts --build-index --mib-stub= RFC1213-MIB

NOTE: for some MIBs mibdump.py needs --mib-stub= as argument to dump something.

2. Generate OID-Catalog + Tree

Create a file converter.py in your working directory of step 1 with the content of the file below and execute:

$ python3 converter.py

Two new files oid_catalog.json and oid_tree.json should be created with a RFC 1213 tree representation of the MIB. The catalog file contains a flat list of all known oid-nodes it knows out of the *.json files we downloaded in step 1.

Feel free to modify and experiment with this code and share improvements.

oid_tree.json Example

{
  "isLeaf": false,
  "children": {
    "1": {
      "isLeaf": false,
      "children": {
        "3": {
          "isLeaf": true,
          "children": {
            "6": {
              "isLeaf": true,
              "children": {
                "1": {
                  "isLeaf": true,
                  "children": {
                    "2": {
                      "isLeaf": true,
                      "children": {
                        "1": {
                          "isLeaf": true,
                          "children": {
                            "1": {
                              "isLeaf": true,
                              "children": {
                                "1": {
                                  "isLeaf": true,
                                  "children": {},
                                  "oidValue": "1.3.6.1.2.1.1.1",
                                  "name": "sysDescr"
                                },
                                "2": {
                                  "isLeaf": true,
                                  "children": {},
                                  "oidValue": "1.3.6.1.2.1.1.2",
                                  "name": "sysObjectID"
                                },
                                "3": {
                                  "isLeaf": true,
                                  "children": {},
                                  "oidValue": "1.3.6.1.2.1.1.3",
                                  "name": "sysUpTime"
                                },
                                "4": {
                                  "isLeaf": true,
                                  "children": {},
                                  "oidValue": "1.3.6.1.2.1.1.4",
                                  "name": "sysContact"
                                }

Python script with PoC algorithm using a Trie

import glob
import json
import os
# the following is a proof of concept example to generate 
# an oid catalog + tree dynamically out of several files

blackList = {"index.json", "oid_tree.json", "oid_catalog.json"}
oidElements = {}

fileList = ("RFC1213-MIB.json", "*.json")

for mibName in fileList:
    path = os.path.dirname(os.path.realpath(__file__)) + "/" + mibName
    for filename in glob.glob(path):
        isBlackListed = False
        for blItem in blackList:
            if blItem in filename:
                isBlackListed = True

        if isBlackListed:
            print("skip blacklisted " + filename)
            continue
        print("importing file " + filename)
        with open(filename, 'r') as f:
            data = json.load(f)

        for key in data:
            value = data[key]
            isSelected = False
            if value != False:
                for elementProperty in value:
                    if elementProperty == "oid":
                        if value[elementProperty] in oidElements:
                            print("skip duplicate " + value[elementProperty])
                            continue
                        oidElements[value[elementProperty]] = value
                        isSelected = True
                        print("added " + value[elementProperty])
                        break
                if not isSelected:
                    print("not selected " + key)

# if you want to remove read-write entries, uncomment the following lines
# readWriteOids = []
# for oid in oidElements:
#     queryContent = oidElements[oid]
#     if "maxaccess" in queryContent:
#         if queryContent["maxaccess"] == "read-write":
#             readWriteOids.append(oid)
#
# for oidToDelete in readWriteOids:
#     oidElements.pop(oidToDelete)
#     print("removing read-write oid " + oidToDelete)

# write oid_catalog.json
# dump oid catalog file
with open('oid_catalog.json', 'w') as fp:
    json.dump(oidElements, fp)

# OID Trie class
class Trie:
    def __init__(self):
        self.root = self.getNode()

    def getNode(self):
        return {"isLeaf": False, "children": {}}

    def insertWord(self, word, oid, name):
        current = self.root
        # split nodes by "."
        for ch in word.split('.'):
            if ch in current["children"]:
                node = current["children"][ch]
            else:
                node = self.getNode()
                current["children"][ch] = node
            current = node
        current["isLeaf"] = True
        current["oidValue"] = oid
        current["name"] = name

# remove zeroDotZero
oidElements.pop('0.0')

rtree = Trie()
for oid in oidElements:
    rtree.insertWord(oid, oid, oidElements[oid]['name'])

# write oid_tree.json
with open('oid_tree.json', 'w') as fp:
    json.dump(rtree.root, fp)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment