Synchronous SNMP
****************

This chapter illustrates various uses of the synchronous high-level
programming interface to some of Standard SNMP Applications, as
defined in RFC3413.

Note: The following examples involve creating Python iterator, the
  next() call is used to invoke iterator just once.

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 two instances of SNMPv2-MIB::sysDescr.0 MIB object,

   from pysnmp.hlapi import *

   errorIndication, errorStatus, errorIndex, varBinds = next(
       getCmd(SnmpEngine(),
              CommunityData('public', mpModel=0),
              UdpTransportTarget(('demo.snmplabs.com', 161)),
              ContextData(),
              ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
   )

   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]))

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-md5-none', MD5 authentication, no privacy

* over IPv4/UDP

* to an Agent at demo.snmplabs.com:161

* for all OIDs in IF-MIB

   from pysnmp.hlapi import *

   for (errorIndication,
        errorStatus,
        errorIndex,
        varBinds) in nextCmd(SnmpEngine(),
                             UsmUserData('usr-md5-none', 'authkey1'),
                             UdpTransportTarget(('demo.snmplabs.com', 161)),
                             ContextData(),
                             ObjectType(ObjectIdentity('IF-MIB'))):

       if errorIndication:
           print(errorIndication)
           break
       elif errorStatus:
           print('%s at %s' % (errorStatus.prettyPrint(),
                               errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
           break
       else:
           for varBind in varBinds:
               print(' = '.join([x.prettyPrint() for x in varBind]))

More examples on Command Generator API usage follow.

* SNMP versions

  * SNMPv1

  * SNMPv2c

  * SNMPv3: auth MD5, privacy DES

  * SNMPv3: auth MD5, no privacy

  * SNMPv3: no auth, no privacy

  * SNMPv3: auth SHA, privacy AES128

* Modifying variables

  * Coerce value to SET to MIB spec

  * SET scalars values

* Walking operations

  * Walk whole MIB

* Table operations

  * GET table row

  * Fetch table row by composite index

  * Fetch scalar and table variables

  * Fetch whole SNMP table

* MIB tweaks

  * Waive MIB lookup

  * Preload PySNMP MIBs

  * Custom ASN.1 MIB path

  * Custom PySNMP MIBs location

* Transport tweaks

  * Custom request timeout

  * GET over IPv6

* Advanced Command Generator

  * Walk Agent, limit number of packets

  * Sequence Of GET's

  * Custom ContextEngineId

  * Custom ContextEngineId and ContextName

  * Custom SecurityName

  * Discover SNMPv3 SecurityEngineId

  * Query Agents from multiple threads

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'

   from pysnmp.hlapi import *

   errorIndication, errorStatus, errorIndex, varBinds = next(
       sendNotification(
           SnmpEngine(),
           CommunityData('public', mpModel=0),
           UdpTransportTarget(('demo.snmplabs.com', 162)),
           ContextData(),
           'trap',
           NotificationType(
               ObjectIdentity('1.3.6.1.6.3.1.1.5.2')
           ).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'))
           )
       )
   )

   if errorIndication:
       print(errorIndication)

More examples on Notification Originator API usage follow.

* Common notifications

  * SNMPv2c TRAP via NOTIFICATION-TYPE

  * INFORM, auth: MD5 privacy: DES

  * SNMPv1 TRAP with defaults

  * SNMPv3 TRAP: auth SHA, privacy: AES128

* SNMPv1 TRAP variants

  * Custom SNMPv1 TRAP

  * SNMPv1 TRAP with defaults

* Evaluating NOTIFICATION-TYPE

  * SNMPv2c TRAP via NOTIFICATION-TYPE

  * Sending additional var-binds

* Advanced Notification Originator

  * INFORM with custom ContextName

  * INFORM with custom ContextEngineId

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