Working with MIBs in ezsnmp: OID Translation & Enterprise MIBs

Note

  • Published: November 01, 2026

  • Authors: Written by Gemini 3.8 Flash, Co-Authored & Reviewed by Carlos Santos (@carlkidcrypto)

  • Estimated Reading Time: 5 minutes

  • Tags: Python • Snmp • Mibs • Net-Snmp • Ezsnmp • Network-Monitoring

Why MIBs Matter in SNMP Automation

Behind every SNMP query lies an Object Identifier (OID)—a dotted-decimal tree sequence like .1.3.6.1.2.1.1.1.0. While network daemons communicate exclusively in these numeric identifiers, human engineers need semantic names like sysDescr.0 or ifHCInOctets.2.

Management Information Base (MIB) files bridge this gap by defining data types, object descriptions, and structural hierarchies.

In pure-Python SNMP libraries, working with custom MIBs often requires an awkward preprocessing pipeline: compiling raw vendor text MIBs into Python modules using tools like PySMI.

ezsnmp takes a faster, native approach by directly leveraging Net-SNMP’s compiled C-level MIB parser. Vendor MIBs are loaded into memory by Net-SNMP once, enabling sub-millisecond symbolic resolution with zero Python code generation required.

How ezsnmp Resolves OIDs

When you query an OID using ezsnmp, you can pass either:

  1. Symbolic Strings: session.get('sysDescr.0')

  2. Multiple OIDs via List: session.get(['sysDescr.0', 'sysUpTime.0'])

  3. Numeric Dot Notation: session.get('.1.3.6.1.2.1.1.1.0')

Returned objects are instances of Result, which unpack the MIB attributes automatically:

from ezsnmp import Session

session = Session(hostname='192.168.1.1', community='public', version=2)

var = session.get('sysUpTime.0')[0]
print(f"Symbolic OID : {var.oid}")        # 'sysUpTime'
print(f"Index        : {var.index}")      # '0'
print(f"Value        : {var.value}")      # '12345678'
print(f"Type         : {var.type}")       # 'TICKS'

Loading Custom Enterprise MIBs

Most modern enterprise hardware (Cisco switches, Arista routers, APC PDUs) exposes proprietary metrics under private enterprise numbers (PEN, .1.3.6.1.4.1). To query these by name, Net-SNMP must be configured to find the vendor MIB text files.

1. Organizing Your MIB Directory

Place your vendor MIB files (e.g., CISCO-SMI.my, CISCO-PROCESS-MIB.my) into a dedicated directory:

mkdir -p ~/.snmp/mibs
cp /path/to/vendor/mibs/*.my ~/.snmp/mibs/

2. Configuring Environment Variables

Net-SNMP detects MIBs through two standard environment variables:

  • MIBDIRS: Specifies colon-separated (or semicolon-separated on Windows) directories where MIB files reside.

  • MIBS: Directs Net-SNMP which MIB modules to load. Using +ALL instructs the parser to load all discovered MIB files alongside standard RFC MIBs.

You can export these in your shell or set them dynamically in Python before instantiating an ezsnmp Session:

import os
from ezsnmp import Session

# Add custom directory to MIB search path
custom_mibs = os.path.expanduser("~/.snmp/mibs")
os.environ["MIBDIRS"] = f"+{custom_mibs}"
os.environ["MIBS"] = "ALL"

session = Session(
    hostname='core-sw01.internal',
    community='secret',
    version=2
)

# Query custom vendor metric by symbol name
cpu_usage = session.get('cpmCPUTotal5minRev.1')[0]
print(f"CPU Utilization (5m): {cpu_usage.value}%")

3. Configuring via snmp.conf

For system-wide or persistent configurations across services, configure snmp.conf (located at /etc/snmp/snmp.conf or ~/.snmp/snmp.conf):

# Add custom MIB directories
mibdirs +/opt/custom_mibs

# Automatically parse all MIBs in the directories
mibs +ALL

Handling MIB Dependencies & Import Errors

Enterprise MIB files frequently import types from other MIBs (for example, importing DisplayString from SNMPv2-TC or ciscoMgmt from CISCO-SMI).

If a dependency is missing, Net-SNMP prints parser warnings to stderr:

Cannot find module (CISCO-SMI): At line 14 in /opt/mibs/CISCO-PROCESS-MIB.my

To resolve parser warnings:

  1. Verify Base MIBs: Ensure standard RFC MIBs are installed. On Ubuntu, install snmp-mibs-downloader.

  2. Order of Ingestion: Ensure parent enterprise definitions (e.g., CISCO-SMI.my) exist in the same directory as child feature MIBs.

Performance Optimization: Symbolic vs Numeric OIDs

While symbolic names simplify development and debugging, resolving MIB strings imposes a minor CPU cost during high-volume polling.

  • During Development & Ad-Hoc Scripts: Use symbolic strings (e.g. session.walk('ifDescr')) for readability.

  • In Production Polling Engines (>10,000 queries/sec): Query numeric OIDs directly (e.g. session.bulk_walk('.1.3.6.1.2.1.2.2.1.2')). Numeric OIDs bypass the Net-SNMP string lookup table entirely, maximizing packet throughput and cutting latency.

Migration Notes: Easy SNMP vs ezsnmp

If migrating MIB-heavy scripts from legacy easysnmp:

  • UTF-8 and Binary Handling: ezsnmp provides cleaner C++17 type coercion for OCTET STRING values, eliminating Python 3 decoding crashes when devices return raw binary MAC addresses or non-ASCII characters.

  • Symbolic OID Queries & Result Access: While querying symbolic OIDs remains supported, consuming results requires updating to the modern API: session.get() returns a tuple of Result objects, and attributes are accessed via .index and .type (rather than legacy .oid_index and .snmp_type). Bulk walks use session.bulk_walk() instead of .bulkwalk().