MIB structure

Displaying the MIB structure as a tree

One of the most useful tools for exploring the structure of an SNMP MIB is the snmptranslate utility provided in the net-analyzer/net-snmp package. As you can see from the example below the snmptranslate utility can be used to produce a "tree" describing the structure of an SNMP MIB, in this case the structure of the SMARTCTL-MIB used to represent harddisk SMART data.

lisa snmptranslate -Tp SMARTCTL-MIB::smartCtl
+--smartCtl(1)
   |
   +--smartCtlMIB(1)
   |
   +--smartCtlTable(2)
      |
      +--smartCtlEntry(1)
         |  Index: smartCtlDeviceIndex
         |
         +-- -R-- Integer32 smartCtlDeviceIndex(1)
         |        Range: 0..65535
         +-- -R-- String    smartCtlDeviceDev(2)
         |        Textual Convention: DisplayString
         |        Size: 0..255
         +-- -R-- String    smartCtlDeviceModelFamily(3)
         |        Textual Convention: DisplayString
         |        Size: 0..255
         +-- -R-- String    smartCtlDeviceDeviceModel(4)
         |        Textual Convention: DisplayString
         |        Size: 0..255
         +-- -R-- String    smartCtlDeviceSerialNumber(5)
         |        Textual Convention: DisplayString
         |        Size: 0..255
         +-- -R-- String    smartCtlDeviceUserCapacity(6)
         |        Textual Convention: DisplayString
         |        Size: 0..255
         +-- -R-- String    smartCtlDeviceATAVersion(7)
         |        Textual Convention: DisplayString
         |        Size: 0..255
         +-- -R-- EnumVal   smartCtlDeviceHealthOK(8)
         |        Textual Convention: TruthValue
         |        Values: true(1), false(2)
         +-- -R-- Gauge     smartCtlDeviceTemperatureCelsius(9)
         +-- -R-- Gauge     smartCtlDeviceReallocatedSectorCt(10)
         +-- -R-- Gauge     smartCtlDeviceCurrentPendingSector(11)
         +-- -R-- Gauge     smartCtlDeviceOfflineUncorrectable(12)
         +-- -R-- Gauge     smartCtlDeviceUDMACRCErrorCount(13)
         +-- -R-- Gauge     smartCtlDeviceReadErrorRate(14)
         +-- -R-- Gauge     smartCtlDeviceSeekErrorRate(15)
         +-- -R-- Gauge     smartCtlDeviceHardwareECCRecovered(16) 

Displaying numeric OIDs

The snmptranslate utility may also be used to resolve the numeric OID when passed a MIB name and MIB entry, as shown below.

lisa snmptranslate -On SMARTCTL-MIB::smartCtl
.1.3.6.1.4.1.38696.2.1 

You can see from the above example that the SMARTCTL-MIB root element (named smartCtl) is located nine levels down (there are nine groups of numbers) in the complete MIB tree.

lisa snmptranslate -On SMARTCTL-MIB::smartCtlTable
.1.3.6.1.4.1.38696.2.1.2 

As the above command demonstrates each additional level in the above tree adds another dotted decimal number to the end of the numeric OID.

Walking the tree

The net-analyzer/net-snmp package also provides another useful utility, the snmpwalk application, which may be used to "walk" the MIB tree from a specified starting location. As you can see from the output below the "walk" ends when there are no more entries below the starting address.

lisa snmpwalk localhost -On SMARTCTL-MIB::smartCtl
.1.3.6.1.4.1.38696.2.1.2.1.1.1 = INTEGER: 1
.1.3.6.1.4.1.38696.2.1.2.1.1.2 = INTEGER: 2
.1.3.6.1.4.1.38696.2.1.2.1.1.3 = INTEGER: 3
.1.3.6.1.4.1.38696.2.1.2.1.1.4 = INTEGER: 4
.1.3.6.1.4.1.38696.2.1.2.1.2.1 = STRING: /dev/sda
.1.3.6.1.4.1.38696.2.1.2.1.2.2 = STRING: /dev/sdb
.1.3.6.1.4.1.38696.2.1.2.1.2.3 = STRING: /dev/sdc
.1.3.6.1.4.1.38696.2.1.2.1.2.4 = STRING: /dev/sdd
.1.3.6.1.4.1.38696.2.1.2.1.3.1 = STRING: Seagate Barracuda 7200.7 and 7200.7 Plus family
.1.3.6.1.4.1.38696.2.1.2.1.3.2 = STRING: Seagate Barracuda 7200.7 and 7200.7 Plus family
.1.3.6.1.4.1.38696.2.1.2.1.3.3 = STRING: Seagate Barracuda 7200.7 and 7200.7 Plus family
.1.3.6.1.4.1.38696.2.1.2.1.3.4 = STRING: Seagate Barracuda 7200.7 and 7200.7 Plus family
.1.3.6.1.4.1.38696.2.1.2.1.4.1 = STRING: ST3160827AS
.1.3.6.1.4.1.38696.2.1.2.1.4.2 = STRING: ST3160827AS
.1.3.6.1.4.1.38696.2.1.2.1.4.3 = STRING: ST3160827AS
.1.3.6.1.4.1.38696.2.1.2.1.4.4 = STRING: ST3160827AS
.1.3.6.1.4.1.38696.2.1.2.1.5.1 = STRING: 4MT00KR4
.1.3.6.1.4.1.38696.2.1.2.1.5.2 = STRING: 5MT0CG5Q
.1.3.6.1.4.1.38696.2.1.2.1.5.3 = STRING: 5MT0CG9Y
.1.3.6.1.4.1.38696.2.1.2.1.5.4 = STRING: 5MT0CG7J
.1.3.6.1.4.1.38696.2.1.2.1.6.1 = STRING: 160,041,885,696 bytes
.1.3.6.1.4.1.38696.2.1.2.1.6.2 = STRING: 160,041,885,696 bytes
.1.3.6.1.4.1.38696.2.1.2.1.6.3 = STRING: 160,041,885,696 bytes
.1.3.6.1.4.1.38696.2.1.2.1.6.4 = STRING: 160,041,885,696 bytes
.1.3.6.1.4.1.38696.2.1.2.1.7.1 = STRING: 6
.1.3.6.1.4.1.38696.2.1.2.1.7.2 = STRING: 6
.1.3.6.1.4.1.38696.2.1.2.1.7.3 = STRING: 6
.1.3.6.1.4.1.38696.2.1.2.1.7.4 = STRING: 6
.1.3.6.1.4.1.38696.2.1.2.1.8.1 = INTEGER: true(1)
.1.3.6.1.4.1.38696.2.1.2.1.8.2 = INTEGER: true(1)
.1.3.6.1.4.1.38696.2.1.2.1.8.3 = INTEGER: true(1)
.1.3.6.1.4.1.38696.2.1.2.1.8.4 = INTEGER: true(1)
.1.3.6.1.4.1.38696.2.1.2.1.9.1 = Gauge32: 39
.1.3.6.1.4.1.38696.2.1.2.1.9.2 = Gauge32: 38
.1.3.6.1.4.1.38696.2.1.2.1.9.3 = Gauge32: 40
.1.3.6.1.4.1.38696.2.1.2.1.9.4 = Gauge32: 39
.1.3.6.1.4.1.38696.2.1.2.1.10.1 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.10.2 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.10.3 = Gauge32: 1
.1.3.6.1.4.1.38696.2.1.2.1.10.4 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.11.1 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.11.2 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.11.3 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.11.4 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.12.1 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.12.2 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.12.3 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.12.4 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.13.1 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.13.2 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.13.3 = Gauge32: 15
.1.3.6.1.4.1.38696.2.1.2.1.13.4 = Gauge32: 0
.1.3.6.1.4.1.38696.2.1.2.1.14.1 = Gauge32: 44
.1.3.6.1.4.1.38696.2.1.2.1.14.2 = Gauge32: 55
.1.3.6.1.4.1.38696.2.1.2.1.14.3 = Gauge32: 46
.1.3.6.1.4.1.38696.2.1.2.1.14.4 = Gauge32: 47
.1.3.6.1.4.1.38696.2.1.2.1.15.1 = Gauge32: 54
.1.3.6.1.4.1.38696.2.1.2.1.15.2 = Gauge32: 54
.1.3.6.1.4.1.38696.2.1.2.1.15.3 = Gauge32: 54
.1.3.6.1.4.1.38696.2.1.2.1.15.4 = Gauge32: 54
.1.3.6.1.4.1.38696.2.1.2.1.16.1 = Gauge32: 50
.1.3.6.1.4.1.38696.2.1.2.1.16.2 = Gauge32: 61
.1.3.6.1.4.1.38696.2.1.2.1.16.3 = Gauge32: 52
.1.3.6.1.4.1.38696.2.1.2.1.16.4 = Gauge32: 53 

MIB table structure

Examining the above output we can see that tabular data is represented using four additional dotted-decimal numbers. The first of these identifies the table in question, as you can see in the table below the smartCtlTable has a numeric identifier of two. The next dotted-decimal number identifies the entry in the table. As you can see below the smartCtlTable table has only a single type of entry which has been assigned the numeric identifier one. The next two numbers represent the column identifier and the index respectively.

|        BASE-OID        | TABLE | ENTRY | COLUMN | INDEX | TYPE    | VALUE
| | | | | | |
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .1 | .1 | INTEGER | 1
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .2 | .1 | STRING | /dev/sda
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .3 | .1 | STRING | Seagate Barracuda 7200.7 and 7200.7 Plus family
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .4 | .1 | STRING | ST3160827AS
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .5 | .1 | STRING | 4MT00KR4
| | | | | | |
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .14 | .1 | Gauge32 | 44
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .15 | .1 | Gauge32 | 54
| .1.3.6.1.4.1.38696.2.1 | .2 | .1 | .16 | .1 | Gauge32 | 50

In the next section we shall demonstrate how the above MIB structure may be simply encoded using Bash arrays so that the snmpd-connector-lib library can take care of all the difficult work of generating and decoding numeric OIDs. We shall also examine how the index values are provided and how MIB specific functions can be created to enable the data to be correctly retrieved and returned to the SNMP daemon.