Using the distribution¶
Two things people do with it, and the one wrinkle between them.
Resolving a name¶
The everyday reason to care. IF-MIB is not one of the modules pysnmp ships,
so naming an object in it needs pysmi and a source to read from:
from pysnmp.smi import builder, compiler, rfc1902, view
mibBuilder = builder.MibBuilder()
compiler.addMibCompiler(
mibBuilder, sources=["https://pysnmp.github.io/mibs/asn1/@mib@"]
)
mibView = view.MibViewController(mibBuilder)
identity = rfc1902.ObjectIdentity("IF-MIB", "ifInOctets", 1)
identity.resolveWithMib(mibView)
print(identity.getOid())
1.3.6.1.2.1.2.2.1.10.1
The @mib@ in the source is a placeholder pysmi substitutes with the module
name it wants; it is not a URL you would open. The first resolution compiles
IF-MIB; later ones read the compiled copy. Hand the same ObjectIdentity to
getCmd or nextCmd and you are polling by name.
Translating a trap¶
A notification arrives as bare numbers. Turning it into something a human or a
log pipeline can read is the same machinery in reverse, with one wrinkle worth
knowing: an OID carries no hint of which module defines it, so the modules
you care about have to be loaded before the lookup can succeed. Resolving
against an empty builder raises SmiError: ... (MIB not loaded?).
from pysnmp.smi import builder, compiler, rfc1902, view
mibBuilder = builder.MibBuilder()
compiler.addMibCompiler(
mibBuilder, sources=["https://pysnmp.github.io/mibs/asn1/@mib@"]
)
# Load what this receiver expects to see. Without this the reverse lookup
# has nothing to search.
mibBuilder.loadModules("SNMPv2-MIB", "IF-MIB")
mibView = view.MibViewController(mibBuilder)
# What a linkDown trap actually carries on the wire.
varBinds = [
("1.3.6.1.6.3.1.1.4.1.0", "1.3.6.1.6.3.1.1.5.3"),
("1.3.6.1.2.1.2.2.1.1.1", 1),
("1.3.6.1.2.1.2.2.1.8.1", 2),
]
for oid, value in varBinds:
varBind = rfc1902.ObjectType(rfc1902.ObjectIdentity(oid), value)
varBind.resolveWithMib(mibView)
print(varBind.prettyPrint())
SNMPv2-MIB::snmpTrapOID.0 = IF-MIB::linkDown
IF-MIB::ifIndex.1 = 1
IF-MIB::ifOperStatus.1 = down
Note the last line. 2 became down because the textual convention in
IF-MIB says so — this distribution gives you the enumeration labels, not just
the names.
Where a receiver cannot know in advance which modules a trap will name,
core.db answers the other way round: one
indexed query per arc, from an OID to the module, the name, the syntax and the
access level, with no compile on the trap path.
Pointing pysmi somewhere else¶
The source is a list, and the first hit wins, so a local directory in front of the published tree is how you override a module or work offline:
compiler.addMibCompiler(
mibBuilder,
sources=[
"/usr/share/snmp/mibs",
"https://pysnmp.github.io/mibs/asn1/@mib@",
],
)
The same list is what mibdump takes on the command line. Most vendor MIBs are
not public, so this is the normal arrangement rather than the exception.
An unpacked mibs-asn1.zip or a mounted corpus-compact image is a local
directory like any other — see channels.
Warning
A MIB module compiled by pysmi becomes Python that pysnmp imports. Treat an ASN.1 MIB source the way you would treat any other code you are about to run, and compile from somewhere you trust.