Notes on using PF-MIB w/ MRTG

Screenshot in Action

First, install your patched snmpd(8) agent binary on the systems you aree monitoring. Then install the MIB files on your NMS (management workstation):

  $ ls -al /usr/local/share/snmp/mibs/OPENBSD-*
  -rw-r--r--  1 root  wheel   1723 Aug 31 13:07 /usr/local/share/snmp/mibs/OPENBSD-BASE-MIB.txt
  -rw-r--r--  1 root  wheel   7500 Sep 23 17:46 /usr/local/share/snmp/mibs/OPENBSD-CARP-MIB.txt
  -rw-r--r--  1 root  wheel  34568 Sep 23 17:47 /usr/local/share/snmp/mibs/OPENBSD-PF-MIB.txt
  -rw-r--r--  1 root  wheel   4086 Mar 18  2007 /usr/local/share/snmp/mibs/OPENBSD-SENSORS-MIB.txt
In some environments, you may need to set the $MIBS environmental variable to explicitly force Net-SNMP libraries to load the MIBs
   $ export MIBS="+/usr/local/share/snmp/mibs/OPENBSD-PF-MIB.txt:/usr/local/share/snmp/mibs/OPENBSD-SENSORS-MIB.txt:\
                  /usr/local/share/snmp/mibs/OPENBSD-CARP-MIB.txt:/usr/local/share/snmp/mibs/OPENBSD-BASE-MIB.txt"
Next, become familiar with the following Net-SNMP utilities (read the entire man page until it hurts):
   snmpwalk(1), snmpget(1), snmpcmd(1), snmptable(1), snmptranslate(1)
Next, try walking the mib w/ snmpwalk(1). An example of walking the Sensor MIB:
 $ snmpwalk -v2c -c [community] [device] OPENBSD-SENSORS-MIB::sensorsMIBObjects  | egrep "\.(2|4|5|6|7|8|9)"
  OPENBSD-SENSORS-MIB::sensorDescr.2 = STRING: "Internal"
  OPENBSD-SENSORS-MIB::sensorDescr.4 = STRING: "fan0"
  OPENBSD-SENSORS-MIB::sensorDescr.5 = STRING: "fan1"
  OPENBSD-SENSORS-MIB::sensorDescr.6 = STRING: "fan2"
  OPENBSD-SENSORS-MIB::sensorDescr.7 = STRING: "+2.5Vin"
  OPENBSD-SENSORS-MIB::sensorDescr.8 = STRING: "Vccp"
  OPENBSD-SENSORS-MIB::sensorDescr.9 = STRING: "Vcc"

  OPENBSD-SENSORS-MIB::sensorType.2 = INTEGER: temperature(0)
  OPENBSD-SENSORS-MIB::sensorType.4 = INTEGER: fan(1)
  OPENBSD-SENSORS-MIB::sensorType.5 = INTEGER: fan(1)
  OPENBSD-SENSORS-MIB::sensorType.6 = INTEGER: fan(1)
  OPENBSD-SENSORS-MIB::sensorType.7 = INTEGER: voltsdc(2)
  OPENBSD-SENSORS-MIB::sensorType.8 = INTEGER: voltsdc(2)
  OPENBSD-SENSORS-MIB::sensorType.9 = INTEGER: voltsdc(2)

  OPENBSD-SENSORS-MIB::sensorDevice.2 = STRING: "adt0"
  OPENBSD-SENSORS-MIB::sensorDevice.4 = STRING: "adt0"
  OPENBSD-SENSORS-MIB::sensorDevice.5 = STRING: "adt0"
  OPENBSD-SENSORS-MIB::sensorDevice.6 = STRING: "adt0"
  OPENBSD-SENSORS-MIB::sensorDevice.7 = STRING: "adt0"
  OPENBSD-SENSORS-MIB::sensorDevice.8 = STRING: "adt0"
  OPENBSD-SENSORS-MIB::sensorDevice.9 = STRING: "adt0"

  OPENBSD-SENSORS-MIB::sensorValue.2 = STRING: "39.00"
  OPENBSD-SENSORS-MIB::sensorValue.4 = STRING: "700"
  OPENBSD-SENSORS-MIB::sensorValue.5 = STRING: "600"
  OPENBSD-SENSORS-MIB::sensorValue.6 = STRING: "2336"
  OPENBSD-SENSORS-MIB::sensorValue.7 = STRING: "1.82"
  OPENBSD-SENSORS-MIB::sensorValue.8 = STRING: "2.05"
  OPENBSD-SENSORS-MIB::sensorValue.9 = STRING: "3.37"

  OPENBSD-SENSORS-MIB::sensorUnits.2 = STRING: "degC"
  OPENBSD-SENSORS-MIB::sensorUnits.4 = STRING: "RPM"
  OPENBSD-SENSORS-MIB::sensorUnits.5 = STRING: "RPM"
  OPENBSD-SENSORS-MIB::sensorUnits.6 = STRING: "RPM"
  OPENBSD-SENSORS-MIB::sensorUnits.7 = STRING: "V DC"
  OPENBSD-SENSORS-MIB::sensorUnits.8 = STRING: "V DC"
  OPENBSD-SENSORS-MIB::sensorUnits.9 = STRING: "V DC"
The same results can be viewed as a relational table array:
 $ snmptable -v2c -Cl -c [community] [host:161] OPENBSD-SENSORS-MIB::sensorTable
 SNMP table: OPENBSD-SENSORS-MIB::sensorTable

 sensorIndex sensorDescr  sensorType sensorDevice sensorValue sensorUnits sensorStatus
           1    "Remote" temperature       "adt0"      "0.00"      "degC"  unspecified
           2  "Internal" temperature       "adt0"     "39.00"      "degC"  unspecified
           3    "Remote" temperature       "adt0"      "0.00"      "degC"  unspecified
           4      "fan0"         fan       "adt0"       "700"       "RPM"  unspecified
           5      "fan1"         fan       "adt0"       "600"       "RPM"  unspecified
           6      "fan2"         fan       "adt0"      "2334"       "RPM"  unspecified
           7   "+2.5Vin"     voltsdc       "adt0"      "1.82"      "V DC"  unspecified
           8      "Vccp"     voltsdc       "adt0"      "2.04"      "V DC"  unspecified
           9       "Vcc"     voltsdc       "adt0"      "3.37"      "V DC"  unspecified
          10       "+5V"     voltsdc       "adt0"      "5.13"      "V DC"  unspecified
          11      "+12V"     voltsdc       "adt0"     "12.06"      "V DC"  unspecified
An example of fetching the CARP MIB table (the -Cl causes left alignment):
 $ snmptable -v2c -Cl -c [community] [host:161] OPENBSD-CARP-MIB::carpIfTable 

  carpIfIndex carpIfDescr carpIfVhid carpIfDev carpIfAdvbase carpIfAdvskew carpIfState 
  1           "carp10"    10         "vlan10"  1             99            master      
  2           "carp20"    20         "vlan20"  1             99            master      
  3           "carp21"    21         "vlan21"  1             99            master    
Other tables with a large array of columns can be truncated (such as the Interface table - note that this is simply an enumeration of /usr/include/net/if.h):
 $ snmptable -v2c -Cb -Cw 150 -c [comm] [host:161] IF-MIB::ifTable
 SNMP table: IF-MIB::ifTable

 Index     Descr     Type Refs Rules In4PassPkts In4PassBytes In4BlockPkts In4BlockBytes Out4PassPkts Out4PassBytes Out4BlockPkts Out4BlockBytes
     1     "all"    group    0     1           0            0            0             0            0             0             0              0
     2    "carp"    group    0     1           0            0            0             0            0             0             0              0
     3  "carp10" instance    0     8           0            0            0             0            0             0             0              0
     4  "carp20" instance    0     6           0            0            0             0            0             0             0              0
     5  "carp21" instance    0     6           0            0            0             0            0             0             0              0
     6  "egress"    group    0     1           0            0            0             0            0             0             0              0
     7     "em0" instance    0     1       58903     19438448            0             0        13185       3945016             0              0
     8    "enc0" instance    0     1           0            0            0             0            0             0             0              0
     9      "lo"    group    0     1           0            0            0             0            0             0             0              0
    10     "lo0" instance    0     1         947       244547            0             0          947        244547             0              0
    11  "pfsync"    group    0     1           0            0            0             0            0             0             0              0
    12 "pfsync0" instance    0     1           0            0            0             0            0             0             0              0
    13    "vlan"    group    0     1           0            0            0             0            0             0             0              0
    14  "vlan10" instance    0     8   625075226 360716252112         5250        563915    559452066  116656439151             0              0
    15  "vlan20" instance    0     6   478218213  86100293352         3037        242547    543485078  299297890231             0              0
    16  "vlan21" instance    0     6    76263648  29910496513            0             0     78119871   60855739027             0              0
    17     "xl0" instance    0     1       64180      9193310            0             0       181716      21603871             0              0
A few notes about data types. The SNMP RFCs specify abstraction of OS/Vendor-specific data types into RFC-specified types. Most values are of "Counter64" integer type, meaning they increment over time upward until they overflow or administrative command to reset the value is issued.
 $ snmpget -v2c -c [comm] [host:161] OPENBSD-PF-MIB::searches.0
 OPENBSD-PF-MIB::searches.0 = Counter64: 2324725824
Others are of type "Guage", meaning that the values fluctuate:
 $ snmpget -v2c -Pd -c [comm] [host:161] OPENBSD-PF-MIB::count.0 OPENBSD-PF-MIB::states.0

  OPENBSD-PF-MIB::count.0 = Gauge32: 64
  OPENBSD-PF-MIB::states.0 = Gauge32: 200000
And other that have unpredictable types are strings (seen here as fan RPMs):
 $ snmpget -v2c -c [comm] [host:161] OPENBSD-SENSORS-MIB::sensorValue.6
 OPENBSD-SENSORS-MIB::sensorValue.6 = STRING: "2333"
NOTE: MRTG will later safety translate strings to integers, as PERL is an untyped interpreted language. Either way, you'll often need to translate the prefix-format MIB identifier into an OID for use with MRTG:
 $ snmptranslate -On -Td OPENBSD-SENSORS-MIB::sensorValue.2
 .1.3.6.1.4.1.64512.2.1.2.1.5.2
 sensorValue OBJECT-TYPE
   -- FROM       OPENBSD-SENSORS-MIB
   SYNTAX        OCTET STRING
   MAX-ACCESS    read-only
   STATUS        current
   DESCRIPTION   "The value the sensor is currently reporting."
 ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) openBSD(64512) \
 sensorsMIBObjects(2) sensors(1) sensorTable(2) sensorEntry(1) sensorValue(5) 2 }
As you can see, snmptranslate(1) can also be used to enumerate object "Descriptions" from ambiguously named objects (w/o picking through the cryptic MIB file)
 $ snmptranslate -On -Td OPENBSD-PF-MIB::state-limit.0 
 .1.3.6.1.4.1.64512.1.2.13.0
 state-limit OBJECT-TYPE
   -- FROM       OPENBSD-PF-MIB
   SYNTAX        Counter64
   MAX-ACCESS    read-only
   STATUS        current
   DESCRIPTION   "The number of packets that were dropped due to the per-rule max state limit being reached."
As opposed to:
  OPENBSD-PF-MIB::states.0 = Gauge32: 200000  ::
  DESCRIPTION   "The maximum number of entries in the memory pool used by state
        table entries (filter rules that specify 'keep state')."
As you will find in MRTG, some object translate properly by their logical reference names:
$ sudo -H -u mrtg /usr/local/bin/mrtg --debug=snpo /usr/local/etc/mrtg/mrtg-br0-ng.conf 2>&1|more

  --snpo: SNMPGet from [comm]@[host]:::::2 -- pfsyncIpPktsRecv.0,pfsyncIpPktsSent.0,sysUptime,sysName
  --snpo: SNMPfound -- '58903', '13513', '12 days, 22:29:26.88', 'br0'
  --snpo: run snmpget from pfsyncNoMemory&pfsyncOutputErrors:[comm]@[host]
Others fail inexplicably miserably translation due to MRTG's SNMP library:
  --snpo: run snmpget from pfsyncNoMemory&pfsyncOutputErrors:[comm]@[host]
  --snpo: simple If: .0
  --snpo: simple If: .0
  --snpo: SNMPGet from [comm]@[host]:::::2 -- pfsyncNoMemory.0,pfsyncOutputErrors.0,sysUptime,sysName
  --snpo: SNMPfound -- 'undef', 'undef', '12 days, 22:33:03.60', 'br0'

Example MRTG Graph Template

pf(4) State Table Entries


pf(4) State Table Searches and/or pf(4) State Table Matches & Mis-Matches


pf(4) State Table Inserts & Removals


  
Screenshots:



pfsync(4) control IP packets

Target[br0.pfsyncPkts]: pfsyncIpPktsRecv.0&pfsyncIpPktsSent.0:[comm]@[host]:::::2
PageTop[br0.pfsyncPkts]: <H1>pfsync(4) control IP packets<H1>
Title[br0.pfsyncPkts]: pfsync(4) control IP packets
Options[br0.pfsyncPkts]: nopercent,noinfo,integer
MaxBytes[br0.pfsyncPkts]: 999999999
#kMG[br0.pfsyncPkts]:
YLegend[br0.pfsyncPkts]: Packets
ShortLegend[br0.pfsyncPkts]: pkts
LegendI[br0.pfsyncPkts]:  pkts/s RX
LegendO[br0.pfsyncPkts]:  pkts/s TX
Legend1[br0.pfsyncPkts]: Packets
Legend2[br0.pfsyncPkts]: Packets
Screenshots:

pf(4) CARP Packets RX/TX

# PF number of OPENBSD-CARP-MIB::carpIpPktsRecv.0 && OPENBSD-CARP-MIB::carpIpPktsSent.0
#Target[br0_pf_carpPktsTX]: carpIpPktsRecv.0&carpIpPktsSent.0:[comm]@[host]:::::2
Target[br0_pf_carpPktsTX]: .1.3.6.1.4.1.64512.3.3.1.0&.1.3.6.1.4.1.64512.3.3.12.0:[comm]@[host]:::::2
Title[br0_pf_carpPktsTX]: pf(4) carp(4) Packets RX/TX
PageTop[br0_pf_carpPktsTX]: <H1>pf(4) CARP Packets RX/TX<H1>
LegendI[br0_pf_carpPktsTX]: Packets RX
LegendO[br0_pf_carpPktsTX]: Packets TX
Legend1[br0_pf_carpPktsTX]: Packets RX
Legend2[br0_pf_carpPktsTX]: Packets TX
YLegend[br0_pf_carpPktsTX]: Packets
ShortLegend[br0_pf_carpPktsTX]: pkts
Options[br0_pf_carpPktsTX]: nopercent, integer, perminute
MaxBytes[br0_pf_carpPktsTX]: 900000000
WithPeak[br0_pf_carpPktsTX]: dwmy
# Unscaled[myrouter]: dwmy
Screenshots:

sensor(4) MIB ADT7460 Sensor CPU Temperature

Target[br0sensor_cpu]: .1.3.6.1.4.1.64512.2.1.2.1.5.2&.1.3.6.1.4.1.64512.2.1.2.1.5.2:[comm]@[host]:::::2
#Target[br0sensor_cpu]: sensorValue.2&sensorValue.0:[comm]@[host]:::::2
Title[br0sensor_cpu]: PF Sensor MIB ADT7460 Sensor CPU Temperature
PageTop[br0sensor_cpu]: <H1>PF Sensor MIB ADT7460 Sensor CPU Temperature<h1>
LegendI[br0sensor_cpu]: degC
LegendO[br0sensor_cpu]: degC
Legend1[br0sensor_cpu]: degC
Legend2[br0sensor_cpu]: degC
YLegend[br0sensor_cpu]: degC
ShortLegend[br0sensor_cpu]: deg
Options[br0sensor_cpu]: nopercent, integer, gauge
MaxBytes[br0sensor_cpu]: 100000
WithPeak[br0sensor_cpu]: dw

sensor(4) MIB ADT7460 Sensor CPU Fan RPMs

Target[br0sensor_cpufanrpm]: .1.3.6.1.4.1.64512.2.1.2.1.5.6&.1.3.6.1.4.1.64512.2.1.2.1.5.6:[comm]@[host]:::::2
#Target[br0sensor_cpufanrpm]: OPENBSD-SENSORS-MIB::sensorValue.6
Title[br0sensor_cpufanrpm]: PF Sensor MIB ADT7460 Sensor CPU Fan RPMs
PageTop[br0sensor_cpufanrpm]: <H1>PF Sensor MIB ADT7460 Sensor CPU Fan RPMs<h1>
LegendI[br0sensor_cpufanrpm]: rpms
LegendO[br0sensor_cpufanrpm]: rpms
Legend1[br0sensor_cpufanrpm]: rpms
Legend2[br0sensor_cpufanrpm]: rpms
YLegend[br0sensor_cpufanrpm]: rpms
ShortLegend[br0sensor_cpufanrpm]: rpms
Options[br0sensor_cpufanrpm]: nopercent, integer, gauge, noo
MaxBytes[br0sensor_cpufanrpm]: 100000
WithPeak[br0sensor_cpufanrpm]: dw
Screenshots:


External Links:

ChangeLog

Contact Me: bseklecki@collaborativefusion.com