Asynchronous SNMP (trollius, v3arch)

In order to use asyncio features with older Python (2.6+), you could download and install Trollius module. PySNMP’s asyncio bindings will work with Trollius as well.

In most examples approximate analogues of well known Net-SNMP snmp* tools command line options are shown. That may help those readers who, by chance are familiar with Net-SNMP tools, better understanding what example code doe

Here’s a quick example on a simple SNMP GET by high-level API:

  • with SNMPv1, community ‘public’
  • over IPv4/UDP
  • to an Agent at demo.snmplabs.com:161
  • for an instance of SNMPv2-MIB::sysDescr.0 MIB object
  • Based on trollius I/O framework
import trollius
from pysnmp.hlapi.v3arch.asyncio import *


@trollius.coroutine
def run():

    snmpEngine = SnmpEngine()

    iterator = getCmd(
        snmpEngine,
        CommunityData('public', mpModel=0),
        UdpTransportTarget(('demo.snmplabs.com', 161)),
        ContextData(),
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
    )

    (errorIndication, errorStatus,
     errorIndex, varBinds) = yield trollius.From(iterator)

    if errorIndication:
        print(errorIndication)

    elif errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(),
                            errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))

    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))

    snmpEngine.transportDispatcher.closeDispatcher()


trollius.get_event_loop().run_until_complete(run())

To make use of SNMPv3 and USM, the following code performs a series of SNMP GETNEXT operations effectively fetching a table of SNMP variables from SNMP Agent:

  • with SNMPv3, user ‘usr-none-none’, no authentication, no privacy
  • over IPv4/UDP
  • to an Agent at demo.snmplabs.com:161
  • for all OIDs past SNMPv2-MIB::system
  • run till end-of-mib condition is reported by Agent
  • based on trollius I/O framework
import trollius
from pysnmp.hlapi.v3arch.asyncio import *


@trollius.coroutine
def run(varBinds):

    snmpEngine = SnmpEngine()

    while True:

        iterator = bulkCmd(
            snmpEngine,
            UsmUserData('usr-none-none'),
            UdpTransportTarget(('demo.snmplabs.com', 161)),
            ContextData(),
            0, 50,
            *varBinds
        )

        (errorIndication, errorStatus,
         errorIndex, varBindTable) = yield trollius.From(iterator)

        if errorIndication:
            print(errorIndication)
            break

        elif errorStatus:
            print('%s at %s' % (errorStatus.prettyPrint(),
                                errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))

        else:
            for varBindRow in varBindTable:
                for varBind in varBindRow:
                    print(' = '.join([x.prettyPrint() for x in varBind]))

        varBinds = varBindTable[-1]

        if isEndOfMib(varBinds):
            break

    snmpEngine.transportDispatcher.closeDispatcher()


loop = trollius.get_event_loop()

loop.run_until_complete(
    run([ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'))])
)

More examples on Command Generator API usage follow.

Sending SNMP TRAP’s and INFORM’s is as easy with PySNMP library. The following code sends SNMP TRAP:

  • SNMPv1
  • with community name ‘public’
  • over IPv4/UDP
  • send TRAP notification
  • with Generic Trap #1 (warmStart) and Specific Trap 0
  • with default Uptime
  • with default Agent Address
  • with Enterprise OID 1.3.6.1.4.1.20408.4.1.1.2
  • include managed object information ‘1.3.6.1.2.1.1.1.0’ = ‘my system’
  • use trollius I/O framework
import trollius
from pysnmp.hlapi.v3arch.asyncio import *


@trollius.coroutine
def run():
    snmpEngine = SnmpEngine()

    iterator = sendNotification(
        snmpEngine,
        CommunityData('public'),  # mpModel=0),
        UdpTransportTarget(('demo.snmplabs.com', 162)),
        ContextData(),
        'inform',
        NotificationType(
            ObjectIdentity('1.3.6.1.6.3.1.1.5.2')
        ).loadMibs(
            'SNMPv2-MIB'
        ).addVarBinds(
            ('1.3.6.1.6.3.1.1.4.3.0', '1.3.6.1.4.1.20408.4.1.1.2'),
            ('1.3.6.1.2.1.1.1.0', OctetString('my system'))
        )
    )

    (errorIndication, errorStatus,
     errorIndex, varBinds) = yield trollius.From(iterator)

    if errorIndication:
        print(errorIndication)

    elif errorStatus:
        print('%s: at %s' % (errorStatus.prettyPrint(),
                             errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))

    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))

    snmpEngine.transportDispatcher.closeDispatcher()


trollius.get_event_loop().run_until_complete(run())

More examples on Notification Originator API usage follow.

More sophisticated or less popular SNMP operations can still be performed with PySNMP through its Native API to Standard SNMP Applications.