Loading content...
When an SNMP manager requests 'interface 3's input byte count,' how does the agent know what data to provide? When a network engineer wants to monitor CPU temperature, how is that information structured and accessed? The answer lies in the Management Information Base (MIB).
A MIB is not a database in the conventional sense—it's a schema definition. MIBs define what managed objects exist, their data types, access permissions, and semantic meaning. Just as a database schema defines tables and columns without containing actual data, MIBs define the structure of management information without storing it.
Mastering MIBs is essential for effective SNMP work. Without understanding MIB structure, you're limited to pre-built monitoring templates. With MIB expertise, you can monitor any SNMP-exposed value on any compliant device.
By the end of this page, you will understand MIB structure and the SMI (Structure of Management Information), standard MIB-2 groups and their objects, how to read MIB files and interpret object definitions, the relationship between MIBs, OIDs, and actual device data, and practical techniques for MIB navigation and discovery.
A MIB (Management Information Base) is a formal definition of management data. Think of it as a contract between managers and agents: the MIB specifies exactly what information is available, how it's identified, what format it takes, and whether it can be read, written, or both.
Key Concepts:
| Term | Definition | Analogy |
|---|---|---|
| MIB | Collection of related object definitions | Database schema / API specification |
| Managed Object | Single data element definition | Column in a database table |
| OID | Unique identifier for an object | Primary key / Unique address |
| Syntax | Data type specification | Column data type (INT, VARCHAR) |
| Instance | Actual runtime value of an object | Row in a table / Cell value |
| SMI | Language for defining MIBs | SQL DDL / Schema definition language |
The SMI: Structure of Management Information
MIBs are written in a formal notation called SMI (Structure of Management Information), which is based on ASN.1 (Abstract Syntax Notation One). SMI defines:
SMI has evolved through two major versions:
Most modern MIBs use SMIv2, though you'll encounter SMIv1 MIBs when working with older equipment.
1234567891011121314151617181920
-- Example MIB Object Definition (SMIv2)-- This defines the sysDescr object from MIB-2 sysDescr OBJECT-TYPE SYNTAX DisplayString (SIZE (0..255)) MAX-ACCESS read-only STATUS current DESCRIPTION "A textual description of the entity. This value should include the full name and version identification of the system's hardware type, software operating-system, and networking software." ::= { system 1 } -- Breaking down the definition:-- SYNTAX → Data type: a string up to 255 characters-- MAX-ACCESS → Read-only (cannot be modified via SNMP SET)-- STATUS → Current (actively maintained, not deprecated)-- DESCRIPTION → Human-readable explanation of the object-- ::= { system 1 } → OID assignment: this is system.1MIB files serve as both machine-readable specifications and human documentation. The DESCRIPTION clauses explain what each object means, its units, valid ranges, and intended use. When troubleshooting SNMP, reading the MIB description often clarifies confusing values or unexpected behavior.
SMI defines a set of data types that constrain what values managed objects can hold. Understanding these types is essential for interpreting SNMP data correctly.
Primitive ASN.1 Types:
| Type | Description | Range/Size | Example Use |
|---|---|---|---|
| INTEGER | Signed integer value | -2^31 to 2^31-1 | Enumerated states (1=up, 2=down) |
| Integer32 | 32-bit signed integer (SMIv2) | -2^31 to 2^31-1 | Temperature, signal strength |
| Unsigned32 | 32-bit unsigned integer | 0 to 2^32-1 | Indexes, non-negative counts |
| Counter32 | 32-bit monotonically increasing counter | 0 to 2^32-1, wraps at max | Packet counts, byte totals |
| Counter64 | 64-bit counter (SMIv2) | 0 to 2^64-1 | High-speed interface byte counts |
| Gauge32 | Non-negative integer that can increase/decrease | 0 to 2^32-1 | Current queue depth, TCP connections |
| TimeTicks | Hundredths of seconds since epoch | 0 to 2^32-1 | System uptime, ages |
| OCTET STRING | Arbitrary binary or text data | 0-65535 bytes | Descriptions, MAC addresses |
| OBJECT IDENTIFIER | OID value pointing to another object | Sequence of integers | System object ID, MIB references |
| IpAddress | 32-bit IPv4 address | 4 octets | Default gateway, interface IP |
Understanding Counters vs Gauges:
The distinction between Counter and Gauge types is crucial for correct data interpretation:
Counters are monotonically increasing values that wrap when they reach their maximum. They represent cumulative totals:
ifInOctets — Total bytes received on an interface (ever-increasing)ifInErrors — Total input errors (ever-increasing)To derive useful metrics from counters, you calculate the difference between successive polls:
Utilization = (ifInOctets_now - ifInOctets_previous) / time_interval
Warning: 32-bit counters wrap at ~4.3 billion. On a 10 Gbps interface, a byte counter wraps every ~3.4 seconds, making accurate calculation impossible. Use Counter64/HC (High Capacity) counters for high-speed interfaces.
Gauges represent instantaneous values that can increase or decrease:
tcpCurrEstab — Current number of established TCP connectionsifSpeed — Current interface speedGauges are directly usable without delta calculation—the current value is meaningful on its own.
On modern high-speed networks, 32-bit counters are practically useless. A 10 Gbps interface at 50% utilization wraps ifInOctets every ~6.9 seconds. If your poll interval is 5 minutes, you'll miss many wraps, making the data meaningless. Always use 64-bit HC counters (e.g., ifHCInOctets from IF-MIB) for interfaces faster than ~25 Mbps.
Textual Conventions:
SMIv2 introduced textual conventions—named type refinements that add semantic meaning:
| Convention | Base Type | Purpose |
|---|---|---|
DisplayString | OCTET STRING | Human-readable ASCII text (0-255 chars) |
PhysAddress | OCTET STRING | Media-dependent physical address (MAC) |
MacAddress | OCTET STRING | Specifically 802 MAC address (6 octets) |
TruthValue | INTEGER | Boolean: true(1), false(2) |
RowStatus | INTEGER | Table row lifecycle management |
DateAndTime | OCTET STRING | Date/time with optional timezone |
StorageType | INTEGER | How object survives reboots |
Textual conventions improve MIB readability and enable tools to provide appropriate formatting (e.g., displaying PhysAddress as "aa:bb:cc:dd:ee:ff" rather than raw hex).
MIB-2 (RFC 1213, updated by various RFCs) is the foundational standard MIB that every SNMP-compliant device must implement. It defines management objects for:
MIB-2 Object Groups:
| Group | OID Suffix | Purpose | Key Objects |
|---|---|---|---|
| system | 1 | Device identification | sysDescr, sysUpTime, sysName, sysLocation |
| interfaces | 2 | Network interface data | ifNumber, ifTable (ifDescr, ifType, ifSpeed, ifInOctets...) |
| at | 3 | Address translation (deprecated) | atTable (ARP cache, superseded by ipNetToMediaTable) |
| ip | 4 | IP protocol statistics | ipForwarding, ipRouteTable, ipAddrTable |
| icmp | 5 | ICMP message counters | icmpInMsgs, icmpOutEchos, error counts |
| tcp | 6 | TCP connection data | tcpCurrEstab, tcpConnTable, connection counts |
| udp | 7 | UDP statistics | udpTable (listening ports), datagram counts |
| egp | 8 | Exterior Gateway Protocol (historical) | Rarely used today |
| transmission | 10 | Transmission media MIBs | Media-specific (Ethernet, Token Ring...) |
| snmp | 11 | SNMP agent statistics | snmpInPkts, snmpOutTraps, error counters |
The System Group (1.3.6.1.2.1.1)
The system group provides basic device identification. Every SNMP-capable device exposes these objects:
12345678910111213141516171819202122
# System Group Objects (OID: 1.3.6.1.2.1.1.*) sysDescr.0 (.1.1.0) - System description string Example: "Cisco IOS Software, C2960 Software..." sysObjectID.0 (.1.2.0) - Vendor's OID for this device type Example: 1.3.6.1.4.1.9.1.1208 (Cisco Catalyst 2960-S) sysUpTime.0 (.1.3.0) - Time since agent started (centiseconds) Example: 8640000 = 1 day exactly sysContact.0 (.1.4.0) - Administrator contact information Example: "noc@example.com, +1-555-0100" sysName.0 (.1.5.0) - Device hostname (FQDN recommended) Example: "core-rtr-1.datacenter1.example.com" sysLocation.0 (.1.6.0) - Physical location description Example: "Building A, Floor 2, Rack 15, U20" sysServices.0 (.1.7.0) - OSI layers this device implements (bit mask) Example: 72 = physical (1) + datalink (2) + network (4) + application (64)The Interfaces Group (1.3.6.1.2.1.2)
The interfaces group (ifTable) is among the most heavily used MIB structures. It provides a table with one row per interface, containing:
The original interfaces group in RFC 1213 has been superseded by IF-MIB (RFC 2863), which adds 64-bit counters (ifHCInOctets), interface stacking (ifStackTable), and enhanced status objects. Modern implementations should use IF-MIB objects, especially the HC (High Capacity) counters for high-speed interfaces.
Many MIB objects are organized into tables—two-dimensional structures with rows representing instances (interfaces, routes, connections) and columns representing attributes. Understanding table indexing is crucial for SNMP queries.
Scalar vs Tabular Objects:
Scalar objects have exactly one instance. Their OID ends with .0:
sysUpTime.0 → 1.3.6.1.2.1.1.3.0
ifNumber.0 → 1.3.6.1.2.1.2.1.0
Tabular objects have multiple instances indexed by row identifiers:
ifDescr.1 → 1.3.6.1.2.1.2.2.1.2.1 (Interface 1 description)
ifDescr.2 → 1.3.6.1.2.1.2.2.1.2.2 (Interface 2 description)
ifInOctets.3 → 1.3.6.1.2.1.2.2.1.10.3 (Interface 3 input bytes)
Table Structure:
MIB tables follow a consistent pattern:
12345678910111213141516171819202122
# Anatomy of a MIB Table OID Consider: 1.3.6.1.2.1.2.2.1.10.3 (ifInOctets for interface 3) 1.3.6.1.2.1 - iso.org.dod.internet.mgmt.mib-2 .2 - interfaces group .2 - ifTable (the table object) .1 - ifEntry (row entry definition) .10 - ifInOctets (column 10) .3 - index = 3 (interface 3) # Table hierachy pattern:# tableObject (n)# └── tableEntry (1)# └── columns (1, 2, 3...)# └── index values (instance identifiers) # Retrieving ifDescr for all interfaces:ifDescr.1 = "GigabitEthernet0/1"ifDescr.2 = "GigabitEthernet0/2" ifDescr.3 = "Vlan10"ifDescr.4 = "Loopback0"Index Types:
Different tables use different index structures:
Simple Integer Index Most common—a single integer identifies rows:
ifTable indexed by ifIndex (INTEGER)
ifDescr.1, ifDescr.2, ifDescr.3...
Compound Index Multiple values index each row:
ipRouteTable indexed by ipRouteDest (IpAddress)
ipRouteDest.10.1.1.0, ipRouteDest.192.168.1.0...
tcpConnTable indexed by (localAddr, localPort, remoteAddr, remotePort)
tcpConnState.10.1.1.5.443.10.2.2.10.52341
String Index Octet string indexes are encoded as length-prefixed sequences:
vacmSecurityName indexed by vacmSecurityModel + vacmSecurityName
# "public" becomes: 6.112.117.98.108.105.99 (length 6 + ASCII values)
To retrieve all rows from a table, use GetNextRequest starting from the table's OID. The agent returns successive entries until exiting the table's OID subtree. Modern polling uses GetBulkRequest for efficiency. Tools like 'snmpwalk' and 'snmptable' automate this process.
Index Persistence:
A critical consideration for monitoring: are indexes stable?
ifIndex Persistence: Historically, ifIndex values could change after device reboots (interfaces renumbered). IF-MIB introduced ifXTable with more stable naming, and many vendors now support persistent ifIndex assignment.
Monitoring Implication: If your monitoring system tracks 'interface 5' by index, and a reboot renumbers interfaces, you'll monitor the wrong port. Best practices:
Standard MIBs like MIB-2 cover common functionality, but vendors need to expose device-specific data—CPU utilization, hardware sensors, feature-specific counters, and proprietary configurations. This is where enterprise MIBs come in.
The Enterprise Tree:
Each vendor is assigned a unique number under 1.3.6.1.4.1 (iso.org.dod.internet.private.enterprises). The vendor then defines their MIB structure beneath this branch:
| Vendor | Enterprise Number | OID Prefix | Example MIBs |
|---|---|---|---|
| Cisco | 9 | 1.3.6.1.4.1.9 | CISCO-PROCESS-MIB, CISCO-ENVMON-MIB |
| HP/HPE | 11 | 1.3.6.1.4.1.11 | HP-ICF-*-MIB series |
| IBM | 2 | 1.3.6.1.4.1.2 | IBM-SYSTEM-*-MIB |
| Microsoft | 311 | 1.3.6.1.4.1.311 | MSFT-MIB |
| Juniper | 2636 | 1.3.6.1.4.1.2636 | JUNIPER-*-MIB series |
| Arista | 30065 | 1.3.6.1.4.1.30065 | ARISTA-*-MIB series |
| Palo Alto | 25461 | 1.3.6.1.4.1.25461 | PAN-*-MIB series |
| Fortinet | 12356 | 1.3.6.1.4.1.12356 | FORTINET-*-MIB series |
Finding Enterprise Numbers:
IANA maintains the official registry of enterprise numbers at: https://www.iana.org/assignments/enterprise-numbers/
Anyone can request an enterprise number for free. This creates a global namespace where any organization can define MIBs without collision.
Common Vendor MIB Patterns:
12345678910111213141516171819202122
# Cisco CPU Monitoring (CISCO-PROCESS-MIB)# 1.3.6.1.4.1.9.9.109.1.1.1.1.5 - cpmCPUTotal5min# CPU utilization (5-min average) per processor snmpget -v2c -c public router1 1.3.6.1.4.1.9.9.109.1.1.1.1.5.1# Returns: INTEGER: 23 (23% CPU utilization) # Cisco Memory Monitoring (CISCO-MEMORY-POOL-MIB) # 1.3.6.1.4.1.9.9.48.1.1.1.5 - ciscoMemoryPoolUsed# 1.3.6.1.4.1.9.9.48.1.1.1.6 - ciscoMemoryPoolFree # Cisco Environment Monitoring (CISCO-ENVMON-MIB)# 1.3.6.1.4.1.9.9.13.1.3 - ciscoEnvMonTemperatureStatusTable# Temperature sensor readings # Juniper Firearm Monitoring (JUNIPER-MIB)# 1.3.6.1.4.1.2636.3.1.13.1.8 - jnxOperatingTemp# Component temperature readings # Palo Alto Firewall Session Count# 1.3.6.1.4.1.25461.2.1.2.3.1.0 - panSessionActiveTcp# Active TCP sessions on firewallVendors typically provide MIB files on their support portals or include them with device software. Some vendors also contribute MIBs to public repositories. Having the correct MIB files loaded in your management tools enables human-readable object names, proper value formatting, and comprehensive device discovery.
Working Without Official MIBs:
Sometimes you need to poll devices without having their MIB files. Approaches:
snmpwalk -v2c -c public device 1.3.6.1.4.1.X discovers what's availableEffective SNMP work requires tools for exploring MIBs, testing queries, and troubleshooting polling issues. The Net-SNMP suite provides essential command-line utilities.
Essential Net-SNMP Commands:
| Command | Purpose | Example |
|---|---|---|
snmpget | Retrieve specific OID values | snmpget -v2c -c public host sysDescr.0 |
snmpgetnext | Get next OID in tree order | snmpgetnext -v2c -c public host sysDescr |
snmpwalk | Walk entire subtree | snmpwalk -v2c -c public host interfaces |
snmpbulkwalk | Efficient bulk walk (v2c/v3) | snmpbulkwalk -v2c -c public host ifTable |
snmptable | Display table in tabular format | snmptable -v2c -c public host ifTable |
snmptranslate | Convert between OID formats | snmptranslate -On sysDescr.0 |
snmpset | Modify writable OID values | snmpset -v2c -c private host sysContact.0 s "admin" |
123456789101112131415161718192021222324252627282930313233343536373839
# Basic SNMP queries with Net-SNMP # Get system description$ snmpget -v2c -c public 10.1.1.1 sysDescr.0SNMPv2-MIB::sysDescr.0 = STRING: Cisco IOS Software, C3560CX Software... # Walk the system group$ snmpwalk -v2c -c public 10.1.1.1 systemSNMPv2-MIB::sysDescr.0 = STRING: Cisco IOS Software...SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.9.1.2131SNMPv2-MIB::sysUpTimeInstance = Timeticks: (34852100) 4 days, 0:48:41.00SNMPv2-MIB::sysContact.0 = STRING: noc@example.comSNMPv2-MIB::sysName.0 = STRING: access-switch-1SNMPv2-MIB::sysLocation.0 = STRING: Building A, Closet 1 # Display interface table in readable format$ snmptable -v2c -c public 10.1.1.1 ifTableSNMP table: IF-MIB::ifTable ifIndex ifDescr ifType ifSpeed ifAdminStatus ifOperStatus 1 Gi0/1 ethernetCsmacd 1000000000 up up 2 Gi0/2 ethernetCsmacd 1000000000 up down 3 Gi0/3 ethernetCsmacd 1000000000 up up 4 Vlan1 propVirtual 1000000000 up up # Translate between numeric and named OIDs$ snmptranslate -On sysDescr.0.1.3.6.1.2.1.1.1.0 $ snmptranslate -Of .1.3.6.1.2.1.1.1.0.iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0 # Discover what a device supports (walk entire tree)$ snmpwalk -v2c -c public 10.1.1.1 . | head -50 # Check specific interface counters$ snmpget -v2c -c public 10.1.1.1 ifInOctets.1 ifOutOctets.1IF-MIB::ifInOctets.1 = Counter32: 2984756234IF-MIB::ifOutOctets.1 = Counter32: 1847293847GUI MIB Browsers:
For interactive exploration, graphical MIB browsers provide a tree view of MIB structure with point-and-click querying:
MIB Compilation:
Management tools require compiled MIB files to translate OIDs to names. Net-SNMP includes a compiler:
# Compile a vendor MIB file
$ snmptranslate -M+/path/to/mibs -m ALL -Tp
# Add MIBs to your search path
export MIBS=ALL
export MIBDIRS=/usr/share/snmp/mibs:/opt/vendor/mibs
When SNMP queries fail, increase verbosity: snmpget -v2c -c public -d host oid. The -d flag shows raw packet dumps. For timeout issues, try -t 10 (10-second timeout). For packet loss, try -r 3 (3 retries). These options help distinguish between connectivity problems and agent issues.
Translating monitoring requirements into SNMP queries requires understanding the relationship between what you want to know and what MIB objects provide.
Common Monitoring Use Cases:
Calculating Interface Utilization:
Interface utilization requires two polls to calculate delta values:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
# Python example: Calculate interface utilization via SNMPimport timefrom pysnmp.hlapi import * def get_interface_counters(host, community, if_index): """Get octect counters for an interface""" oid_in = ObjectIdentity('IF-MIB', 'ifHCInOctets', if_index) oid_out = ObjectIdentity('IF-MIB', 'ifHCOutOctets', if_index) oid_speed = ObjectIdentity('IF-MIB', 'ifHighSpeed', if_index) result = {} for (errorIndication, errorStatus, errorIndex, varBinds) in getCmd( SnmpEngine(), CommunityData(community), UdpTransportTarget((host, 161)), ContextData(), ObjectType(oid_in), ObjectType(oid_out), ObjectType(oid_speed) ): if errorIndication or errorStatus: raise Exception(f"SNMP error: {errorIndication or errorStatus}") for varBind in varBinds: name = str(varBind[0]) if 'ifHCInOctets' in name: result['in_octets'] = int(varBind[1]) elif 'ifHCOutOctets' in name: result['out_octets'] = int(varBind[1]) elif 'ifHighSpeed' in name: result['speed_mbps'] = int(varBind[1]) result['timestamp'] = time.time() return result def calculate_utilization(sample1, sample2): """Calculate utilization percentage between two samples""" time_delta = sample2['timestamp'] - sample1['timestamp'] in_delta = sample2['in_octets'] - sample1['in_octets'] out_delta = sample2['out_octets'] - sample1['out_octets'] # Convert to bits and calculate percentage speed_bps = sample2['speed_mbps'] * 1_000_000 in_util = (in_delta * 8 / time_delta / speed_bps) * 100 out_util = (out_delta * 8 / time_delta / speed_bps) * 100 return { 'in_utilization_pct': round(in_util, 2), 'out_utilization_pct': round(out_util, 2), 'in_throughput_mbps': round(in_delta * 8 / time_delta / 1_000_000, 2), 'out_throughput_mbps': round(out_delta * 8 / time_delta / 1_000_000, 2) } # Usagesample1 = get_interface_counters('10.1.1.1', 'public', 1)time.sleep(60) # Wait 60 secondssample2 = get_interface_counters('10.1.1.1', 'public', 1) util = calculate_utilization(sample1, sample2)print(f"Inbound: {util['in_utilization_pct']}% ({util['in_throughput_mbps']} Mbps)")print(f"Outbound: {util['out_utilization_pct']}% ({util['out_throughput_mbps']} Mbps)")Production code must handle counter wraps. If sample2 < sample1, either the counter wrapped or the device rebooted (check sysUpTime). For wrapped counters, adjust: delta = (max_counter - sample1) + sample2. For reboots, discard the sample and start fresh.
We've covered the Management Information Base in depth—the schema that defines what data SNMP can access and how it's structured. This knowledge enables you to work with any SNMP-enabled device.
What's Next:
Now that you understand MIB structure and navigation, we'll explore the evolution of SNMP versions. SNMPv1, v2c, and v3 offer progressively enhanced features—particularly in security. Understanding version differences is essential for deploying SNMP appropriately in different security contexts.
You now understand MIB structure, SMI data types, standard and enterprise MIBs, table indexing, and practical navigation techniques. With this knowledge, you can interpret any MIB object definition and construct queries for any SNMP-exposed data. Next, we'll examine SNMP version evolution and the critical security improvements in SNMPv3.