example.coffee
author Tomas Zeman <tzeman@volny.cz>
Thu, 28 Mar 2013 21:55:07 +0100
changeset 5 2db4f3d512bb
parent 3 edd377ebd4ca
permissions -rw-r--r--
Server prototype

snmp = require('snmp-native')
snmpTypes = require('snmp-native/lib/asn1ber').types

typeStr = {}
typeStr[snmpTypes.Integer] =           'Integer'
typeStr[snmpTypes.OctetString] =       'OctetString'
typeStr[snmpTypes.Null] =              'Null'
typeStr[snmpTypes.ObjectIdentifier] =  'ObjectIdentifier'
typeStr[snmpTypes.Sequence] =          'Sequence'
typeStr[snmpTypes.IpAddress] =         'IpAddress'
typeStr[snmpTypes.Counter] =           'Counter'
typeStr[snmpTypes.Gauge] =             'Gauge'
typeStr[snmpTypes.TimeTicks] =         'TimeTicks'
typeStr[snmpTypes.Opaque] =            'Opaque'
typeStr[snmpTypes.NsapAddress] =       'NsapAddress'
typeStr[snmpTypes.Counter64] =         'Counter64'
typeStr[snmpTypes.NoSuchObject] =      'NoSuchObject'
typeStr[snmpTypes.NoSuchInstance] =    'NoSuchInstance'
typeStr[snmpTypes.EndOfMibView] =      'EndOfMibView'
typeStr[snmpTypes.PDUBase] =           'PDUBase'

###
Converts TimeTicks value to easy-to-use structure.
###
convertTimeTicks = (v) ->
  intDiv = (a, b) -> Math.floor(a / b)
  msec = v % 100
  v = intDiv(v, 100)
  secs = v % 60
  v = intDiv(v, 60)
  mins = v % 60
  v = intDiv(v, 60)
  hours = v % 24
  days = intDiv(v, 24)
  
  days: days
  hours: hours
  mins: mins
  secs: secs
  msecs: msec

###
Processes SNMP result value.
###
processVarBind = (vb) ->
  rv =
    oid: "." + vb.oid.reduce (x,y) -> x+"."+y
    value: vb.value
    type: vb.type
    typeStr: typeStr[vb.type] ? 'Unknown'
  if (rv.type == snmpTypes.TimeTicks)
    rv.timeTicks = convertTimeTicks(vb.value)
  rv

###
Creates SNMP session and retrieves values for the supplied OIDs.
###
snmpget = (opts, cb) ->
  sess = new snmp.Session(opts)
  res = []
  snmpgetOne = (i) ->
    if (i < opts.oids.length)
      oid = opts.oids[i]
      sess.get({oid: oid}, (err, vbs) ->
        if (err)
          res.push { error: err, oid: oid }
          if (opts.abortOnError)
            i = opts.oids.length
        else
          res.push vbs.map(processVarBind)...
        snmpgetOne ++i
      )
    else
      sess.close()
      cb(res)
  snmpgetOne 0

# Example OIDs (some intentionally wrong).
oids = [
  '.1.3.6.1.2.1.1.1',
  '.1.3.6.1.2.1.1.1.0',
  '.1.3.6.1.2.1.1.2.0',
  '.1.3.6.1.2.1.1.3.0',
  '.1.3.6.1.4.1.9.2.1.57.0',
  '.1.3.6.1.4.1.9.2.1.58.0',
  '.1.3.6.1.4.1.9.9.48.1.1.1.5.1',
  '.1.3.6.1.4.1.9.9.48.1.1.1.6.1',
  '.1.3.6.1.4.1.9.9.13.1.3.1.3.1'
]

opts =
  host:  process.env.HOST ? "localhost"
  community: process.env.COMMUNITY ? "public"
  oids: oids
  abortOnError: true

###
Do the work
###
snmpget(opts, (res) -> console.log res)