Manager side

PDU var-binds to MIB objects

This script explains how Python application could turn SNMP PDU variable-bindings into MIB objects or the other way around.

The code that configures MIB compiler is similar to what happens inside the pysnmp.hlapi API.

from pysnmp.smi import builder, view, compiler, rfc1902

# Assemble MIB browser
mibBuilder = builder.MibBuilder()
mibViewController = view.MibViewController(mibBuilder)
compiler.add_mib_compiler(
    mibBuilder,
    sources=["file:///usr/share/snmp/mibs", "https://mibs.pysnmp.com/asn1/@mib@"],
)

# Pre-load MIB modules we expect to work with
mibBuilder.load_modules("SNMPv2-MIB", "SNMP-COMMUNITY-MIB")

# This is what we can get in TRAP PDU
varBinds = [
    ("1.3.6.1.2.1.1.3.0", 12345),
    ("1.3.6.1.6.3.1.1.4.1.0", "1.3.6.1.6.3.1.1.5.2"),
    ("1.3.6.1.6.3.18.1.3.0", "0.0.0.0"),
    ("1.3.6.1.6.3.18.1.4.0", ""),
    ("1.3.6.1.6.3.1.1.4.3.0", "1.3.6.1.4.1.20408.4.1.1.2"),
    ("1.3.6.1.2.1.1.1.0", "my system"),
]

# Run var-binds through MIB resolver
# You may want to catch and ignore resolution errors here
varBinds = [
    rfc1902.ObjectType(rfc1902.ObjectIdentity(x[0]), x[1]).resolve_with_mib(
        mibViewController
    )
    for x in varBinds
]

for varBind in varBinds:
    print(varBind.prettyPrint())

Download script.

MIB objects to PDU var-binds

This script explains how Python application (typically pysnmp-based SNMP Manager) could turn SNMP PDU variable-bindings into MIB objects or the other way around.

The code below does not explicitly add MIB compiler - that happens behind the scenes. Examples below try to demo different kinds of MIB objects to work with.

from pysnmp.smi import builder, view, rfc1902, error

# MIB Builder manages pysnmp MIBs
mibBuilder = builder.MibBuilder()

# MIB View Controller implements various queries to loaded MIBs
mibView = view.MibViewController(mibBuilder)

# Obtain MIB object information by MIB object name
mibVar = rfc1902.ObjectIdentity("IF-MIB", "ifInOctets", 1)

# Optionally attach PySMI MIB compiler to MIB Builder that would
# create pysnmp MIBs on demand from ASN.1 sources downloaded from
# a web site.
try:
    mibVar.add_asn1_mib_source("https://mibs.pysnmp.com/asn1/@mib@")
except error.SmiError:
    print("WARNING: not using MIB compiler (PySMI not installed)")

mibVar.resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain MIB object information by its [sequence] OID
mibVar = rfc1902.ObjectIdentity(tuple(mibVar)).resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain MIB object information by its [string] OID
mibVar = rfc1902.ObjectIdentity(str(mibVar)).resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain MIB object information by a mix of OID/label parts
mibVar = rfc1902.ObjectIdentity(
    (1, 3, 6, 1, 2, "mib-2", 1, "sysDescr")
).resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain MIB object information by a label
mibVar = rfc1902.ObjectIdentity(
    "iso.org.dod.internet.mgmt.mib-2.system.sysDescr"
).resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain the first MIB object in given MIB module
mibVar = rfc1902.ObjectIdentity("SNMPv2-MIB").resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain the last MIB object in given MIB module
mibVar = rfc1902.ObjectIdentity("SNMPv2-MIB", last=True).resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Another way to obtain the first (or last) symbol in MIB module
mibVar = rfc1902.ObjectIdentity("SNMPv2-MIB", "").resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Obtain MIB symbol from whatever MIB it is defined at (MIB should be loaded)
mibVar = rfc1902.ObjectIdentity("", "sysDescr", 0).resolve_with_mib(mibView)

print(mibVar.prettyPrint(), tuple(mibVar), str(mibVar))

# Create an OID-value pair (called variable-binding in SNMP)
varBind = rfc1902.ObjectType(
    rfc1902.ObjectIdentity("SNMPv2-MIB", "sysObjectID", 0), "1.3.6.1"
).resolve_with_mib(mibView)

print(varBind[0].prettyPrint(), varBind[1].__class__.__name__, varBind[1].prettyPrint())

# Create just OID
varBind = rfc1902.ObjectType(
    rfc1902.ObjectIdentity("SNMPv2-MIB", "sysObjectID", 0)
).resolve_with_mib(mibView)

print(varBind[0].prettyPrint(), varBind[1].__class__.__name__, varBind[1].prettyPrint())

# Create var-binds from MIB notification object (without OBJECTS clause)
varBinds = rfc1902.NotificationType(
    rfc1902.ObjectIdentity("SNMPv2-MIB", "coldStart")
).resolve_with_mib(mibView)

print(
    [
        f"{x[0].prettyPrint()} = {x[1].__class__.__name__}({x[1].prettyPrint()})"
        for x in varBinds
    ]
)

# Create var-binds from MIB notification object (with OBJECTS clause)
varBinds = rfc1902.NotificationType(
    rfc1902.ObjectIdentity("IF-MIB", "linkUp"),
    instanceIndex=(1,),
    objects={("IF-MIB", "ifOperStatus"): "down"},
).resolve_with_mib(mibView)

print(varBinds.prettyPrint())

Download script.

SNMP MIB browser

This script explains how Python application (typically SNMP Manager) could load SNMP MIB modules into memory and introspect Managed Objects defined in MIB.

from pysnmp.smi import builder, view, compiler, error

# Create MIB loader/builder
mibBuilder = builder.MibBuilder()

# Optionally attach PySMI MIB compiler (if installed)
# print('Attaching MIB compiler...'),
# compiler.addMibCompiler(mibBuilder, sources=['/usr/share/snmp/mibs'])
# print('done')

# Optionally set an alternative path to compiled MIBs
print("Setting MIB sources...")
mibBuilder.add_mib_sources(builder.DirMibSource("/opt/pysnmp_mibs"))
print(mibBuilder.get_mib_sources())
print("done")

print("Loading MIB modules..."),
mibBuilder.load_modules(
    "SNMPv2-MIB", "SNMP-FRAMEWORK-MIB", "SNMP-COMMUNITY-MIB", "IP-MIB"
)
print("done")

print("Indexing MIB objects..."),
mibView = view.MibViewController(mibBuilder)
print("done")

print("MIB symbol name lookup by OID: "),
oid, label, suffix = mibView.get_node_name((1, 3, 6, 1, 2, 1, 1, 1))
print(oid, label, suffix)

print("MIB symbol name lookup by label: "),
oid, label, suffix = mibView.get_node_name((1, 3, 6, 1, 2, "mib-2", 1, "sysDescr"))
print(oid, label, suffix)

print("MIB symbol name lookup by symbol description: "),
oid, label, suffix = mibView.get_node_name(("sysDescr",))
oid, label, suffix = mibView.get_node_name(("snmpEngineID",), "SNMP-FRAMEWORK-MIB")
print(oid, label, suffix)

print("MIB object value pretty print: "),
(mibNode,) = mibBuilder.import_symbols("SNMP-FRAMEWORK-MIB", "snmpEngineID")
print(mibNode.syntax.prettyPrint())

print("MIB symbol location lookup by name: "),
modName, symName, suffix = mibView.get_node_location(("snmpCommunityEntry",))
print(symName, modName)

print("MIB node lookup by location: "),
(rowNode,) = mibBuilder.import_symbols(modName, symName)
print(rowNode)

print("Conceptual table index value to oid conversion: "),
oid = rowNode.getInstIdFromIndices("router")
print(oid)
print("Conceptual table index oid to value conversion: "),
print(rowNode.getIndicesFromInstId(oid))

print("MIB tree traversal")
oid, label, suffix = mibView.get_first_node_name()
while 1:
    try:
        modName, nodeDesc, suffix = mibView.get_node_location(oid)
        print(f"{modName}::{nodeDesc} == {oid}")
        oid, label, suffix = mibView.get_next_node_name(oid)
    except error.NoSuchObjectError:
        break

print("Modules traversal")
modName = mibView.get_first_module_name()
while 1:
    if modName:
        print(modName)
    try:
        modName = mibView.get_next_module_name(modName)
    except error.SmiError:
        break

Download script.

See also: library reference.