From 4d1d9778f9b52752a0bb271a0bc5b69f9b4f50e3 Mon Sep 17 00:00:00 2001 From: elie Date: Sun, 27 Sep 2015 10:26:26 +0000 Subject: * Asyncore and asyncio-based APIs reworked to become functions. * Asyncio and Twisted API moved entirely into high-level domain to be aligned with other high-level APIs. This WILL BREAK backward compatibility for those apps that use Twisted API. --- .../sync/agent/ntforg/custom-contextengineid.py | 48 ++ .../sync/agent/ntforg/custom-contextname.py | 48 ++ .../asyncore/sync/agent/ntforg/custom-v1-trap.py | 50 ++ .../asyncore/sync/agent/ntforg/default-v1-trap.py | 46 ++ .../send-notification-with-additional-varbinds.py | 49 ++ .../agent/ntforg/v2c-trap-via-notification-type.py | 37 ++ .../hlapi/asyncore/sync/agent/ntforg/v3-inform.py | 49 ++ .../hlapi/asyncore/sync/agent/ntforg/v3-trap.py | 45 ++ .../manager/cmdgen/coerce-set-value-to-mib-spec.py | 39 ++ .../manager/cmdgen/custom-asn1-mib-search-path.py | 39 ++ .../custom-contextengineid-and-contextname.py | 45 ++ .../sync/manager/cmdgen/custom-contextengineid.py | 43 ++ .../cmdgen/custom-pysnmp-mibs-search-path.py | 45 ++ .../manager/cmdgen/custom-timeout-and-retries.py | 53 ++ .../sync/manager/cmdgen/custom-v3-security-name.py | 38 ++ .../manager/cmdgen/fetch-variables-over-ipv6.py | 42 ++ .../manager/cmdgen/get-table-object-by-index.py | 41 ++ .../cmdgen/get-table-object-by-multiple-indices.py | 46 ++ .../getbulk-fetch-scalar-and-table-variables.py | 48 ++ .../cmdgen/getbulk-limit-number-of-packets.py | 44 ++ .../cmdgen/getbulk-limit-number-of-variables.py | 47 ++ .../cmdgen/getnext-limit-number-of-variables.py | 46 ++ .../manager/cmdgen/getnext-multiple-oids-to-eom.py | 43 ++ .../sync/manager/cmdgen/multiple-get-calls.py | 47 ++ .../sync/manager/cmdgen/preload-pysnmp-mibs.py | 43 ++ .../asyncore/sync/manager/cmdgen/pull-whole-mib.py | 40 ++ .../sync/manager/cmdgen/pull-whole-snmp-table.py | 53 ++ .../cmdgen/query-agents-from-multuple-threads.py | 127 +++++ .../manager/cmdgen/set-multiple-scalar-values.py | 49 ++ .../sync/manager/cmdgen/specific-v3-engine-id.py | 86 +++ .../asyncore/sync/manager/cmdgen/usm-md5-des.py | 39 ++ .../asyncore/sync/manager/cmdgen/usm-md5-none.py | 38 ++ .../asyncore/sync/manager/cmdgen/usm-none-none.py | 39 ++ .../asyncore/sync/manager/cmdgen/usm-sha-aes128.py | 57 ++ .../hlapi/asyncore/sync/manager/cmdgen/v1-get.py | 37 ++ .../hlapi/asyncore/sync/manager/cmdgen/v2c-get.py | 39 ++ .../asyncore/sync/manager/cmdgen/v2c-getbulk.py | 46 ++ .../sync/manager/cmdgen/waive-mib-lookup.py | 45 ++ pysnmp/hlapi/asyncore/sync/__init__.py | 13 + pysnmp/hlapi/asyncore/sync/cmdgen.py | 605 +++++++++++++++++++++ pysnmp/hlapi/asyncore/sync/compat/cmdgen.py | 258 +++++++++ pysnmp/hlapi/asyncore/sync/compat/ntforg.py | 50 ++ pysnmp/hlapi/asyncore/sync/ntforg.py | 122 +++++ 43 files changed, 2864 insertions(+) create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/custom-contextengineid.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/custom-contextname.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/custom-v1-trap.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/default-v1-trap.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/send-notification-with-additional-varbinds.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/v2c-trap-via-notification-type.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/v3-inform.py create mode 100644 examples/hlapi/asyncore/sync/agent/ntforg/v3-trap.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/coerce-set-value-to-mib-spec.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/custom-asn1-mib-search-path.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid-and-contextname.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/custom-pysnmp-mibs-search-path.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/custom-timeout-and-retries.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/custom-v3-security-name.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/fetch-variables-over-ipv6.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-index.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-multiple-indices.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-fetch-scalar-and-table-variables.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-packets.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-variables.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/getnext-limit-number-of-variables.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/getnext-multiple-oids-to-eom.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/multiple-get-calls.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/preload-pysnmp-mibs.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-mib.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-snmp-table.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/query-agents-from-multuple-threads.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/set-multiple-scalar-values.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/specific-v3-engine-id.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-des.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-none.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/usm-none-none.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/usm-sha-aes128.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/v1-get.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/v2c-get.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/v2c-getbulk.py create mode 100644 examples/hlapi/asyncore/sync/manager/cmdgen/waive-mib-lookup.py create mode 100644 pysnmp/hlapi/asyncore/sync/__init__.py create mode 100644 pysnmp/hlapi/asyncore/sync/cmdgen.py create mode 100644 pysnmp/hlapi/asyncore/sync/compat/cmdgen.py create mode 100644 pysnmp/hlapi/asyncore/sync/compat/ntforg.py create mode 100644 pysnmp/hlapi/asyncore/sync/ntforg.py diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/custom-contextengineid.py b/examples/hlapi/asyncore/sync/agent/ntforg/custom-contextengineid.py new file mode 100644 index 0000000..2ccdafe --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/custom-contextengineid.py @@ -0,0 +1,48 @@ +""" +INFORM with custom ContextEngineId +++++++++++++++++++++++++++++++++++ + +Send SNMP notification using the following options: + +* SNMPv3 +* with user 'usr-md5-none', MD5 auth, no priv +* send INFORM notification +* in behalf of contextEngineId 0x8000000004030201, contextName '' +* over IPv4/UDP +* with TRAP ID 'warmStart' specified as a string OID + +Sending SNMPv3 Notification in behalf of non-default ContextEngineId +requires having a collection of Managed Objects registered under +the ContextEngineId being used. + +Functionally similar to: + +| $ snmpinform -v3 -l authNoPriv -u usr-md5-none -A authkey1 \ +| -E 0x8000000004030201 +| demo.snmplabs.com \ +| 12345 \ +| 1.3.6.1.6.3.1.1.5.2 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + UsmUserData('usr-md5-none', 'authkey1'), + UdpTransportTarget(('localhost', 162)), + ContextData(OctetString(hexValue='8000000004030201')), + 'inform', + NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.2'))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/custom-contextname.py b/examples/hlapi/asyncore/sync/agent/ntforg/custom-contextname.py new file mode 100644 index 0000000..a087c7e --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/custom-contextname.py @@ -0,0 +1,48 @@ +""" +INFORM with custom ContextName +++++++++++++++++++++++++++++++ + +Send SNMP notification using the following options: + +* SNMPv3 +* with user 'usr-md5-none', MD5 auth, no priv +* send INFORM notification +* in behalf of contextEngineId = SnmpEngineId, contextName 'my-context' +* over IPv4/UDP +* with TRAP ID 'warmStart' specified as a string OID + +Sending SNMPv3 Notification in behalf of non-default ContextName +requires having a collection of Managed Objects registered under +the ContextName being used. + +Functionally similar to: + +| $ snmpinform -v3 -l authNoPriv -u usr-md5-none -A authkey1 \ +| -n my-context \ +| demo.snmplabs.com \ +| 12345 \ +| 1.3.6.1.6.3.1.1.5.2 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + UsmUserData('usr-md5-none', 'authkey1'), + UdpTransportTarget(('localhost', 162)), + ContextData(contextName='my-context'), + 'inform', + NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.2'))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/custom-v1-trap.py b/examples/hlapi/asyncore/sync/agent/ntforg/custom-v1-trap.py new file mode 100644 index 0000000..768ad26 --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/custom-v1-trap.py @@ -0,0 +1,50 @@ +""" +Custom SNMPv1 TRAP +++++++++++++++++++ + +Send SNMPv1 TRAP through unified SNMPv3 message processing framework. + +Original v1 TRAP fields are mapped into dedicated variable-bindings, +(see `RFC2576 `_) for details. + +* SNMPv1 +* with community name 'public' +* over IPv4/UDP +* send TRAP notification +* with Generic Trap #6 (enterpriseSpecific) and Specific Trap 432 +* overriding Uptime value with 12345 +* overriding Agent Address with '127.0.0.1' +* overriding Enterprise OID with 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' + +Functionally similar to: + +| $ snmptrap -v1 -c public demo.snmplabs.com \ +| 1.3.6.1.4.1.20408.4.1.1.2 \ +| 127.0.0.1 \ +| 6 \ +| 432 \ +| 12345 \ +| '1.3.6.1.2.1.1.1.0' s 'my system' + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + CommunityData('public', mpModel=0), + UdpTransportTarget(('localhost', 162)), + ContextData(), + 'trap', + NotificationType( + ObjectIdentity('1.3.6.1.4.1.20408.4.1.1.2.0.432'), + ).addVarBinds( + ('1.3.6.1.2.1.1.3.0', 12345), + ('1.3.6.1.6.3.18.1.3.0', '127.0.0.1'), + ('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) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/default-v1-trap.py b/examples/hlapi/asyncore/sync/agent/ntforg/default-v1-trap.py new file mode 100644 index 0000000..7d4a9d0 --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/default-v1-trap.py @@ -0,0 +1,46 @@ +""" +SNMPv1 TRAP with defaults ++++++++++++++++++++++++++ + +Send SNMPv1 TRAP through unified SNMPv3 message processing framework +using the following options: + +* 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' + +Functionally similar to: + +| $ snmptrap -v1 -c public demo.snmplabs.com \ +| 1.3.6.1.4.1.20408.4.1.1.2 \ +| 0.0.0.0 \ +| 1 \ +| 0 \ +| 0 +| '1.3.6.1.2.1.1.1.0' s 'my system' + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + CommunityData('public', mpModel=0), + UdpTransportTarget(('localhost', 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) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/send-notification-with-additional-varbinds.py b/examples/hlapi/asyncore/sync/agent/ntforg/send-notification-with-additional-varbinds.py new file mode 100644 index 0000000..17cf899 --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/send-notification-with-additional-varbinds.py @@ -0,0 +1,49 @@ +""" +Sending additional var-binds +++++++++++++++++++++++++++++ + +Send SNMP notification using the following options: + +* SNMPv2c +* with community name 'public' +* over IPv4/UDP +* send INFORM notification +* with TRAP ID 'coldStart' specified as a MIB symbol +* include managed object information specified as a MIB symbol + +Functionally similar to: + +| $ snmpinform -v2c -c public +| demo.snmplabs.com \ +| 12345 \ +| 1.3.6.1.6.3.1.1.5.1 \ +| 1.3.6.1.2.1.1.1.0 s 'my system' + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('localhost', 162)), + ContextData(), + 'inform', + NotificationType( + ObjectIdentity('SNMPv2-MIB', 'coldStart') + ).addVarBinds( + ObjectType(ObjectIdentity('SNMPv2-MIB','sysName',0), + 'my system') + )) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/v2c-trap-via-notification-type.py b/examples/hlapi/asyncore/sync/agent/ntforg/v2c-trap-via-notification-type.py new file mode 100644 index 0000000..e5121b2 --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/v2c-trap-via-notification-type.py @@ -0,0 +1,37 @@ +""" +SNMPv2c TRAP via NOTIFICATION-TYPE +++++++++++++++++++++++++++++++++++ + +Initialize TRAP message contents from variables specified +in *NOTIFICATION-TYPE* SMI macro. + +* SNMPv2c +* with community name 'public' +* over IPv4/UDP +* send TRAP notification +* with TRAP ID 'coldStart' specified as a MIB symbol +* include managed object information specified as a MIB symbol + +Functionally similar to: + +| $ snmptrap -v2c -c public demo.snmplabs.com \ +| 12345 +| 1.3.6.1.4.1.20408.4.1.1.2 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('localhost', 162)), + ContextData(), + 'trap', + NotificationType( + ObjectIdentity('SNMPv2-MIB', 'coldStart') + ) + ) +) + +if errorIndication: + print(errorIndication) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/v3-inform.py b/examples/hlapi/asyncore/sync/agent/ntforg/v3-inform.py new file mode 100644 index 0000000..39f5127 --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/v3-inform.py @@ -0,0 +1,49 @@ +""" +INFORM, auth: MD5 privacy: DES +++++++++++++++++++++++++++++++ + +Send SNMP INFORM notification using the following options: + +* SNMPv3 +* with user 'usr-md5-des', auth: MD5, priv DES +* over IPv4/UDP +* send INFORM notification +* with TRAP ID 'warmStart' specified as a string OID +* include managed object information 1.3.6.1.2.1.1.5.0 = 'system name' + +Functionally similar to: + +| $ snmpinform -v3 -l authPriv -u usr-sha-aes -A authkey1 -X privkey1 \ +| demo.snmplabs.com \ +| 12345 \ +| 1.3.6.1.4.1.20408.4.1.1.2 \ +| '1.3.6.1.2.1.1.1.0' s 'my system' + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(), + UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), + UdpTransportTarget(('localhost', 162)), + ContextData(), + 'inform', + NotificationType( + ObjectIdentity('1.3.6.1.6.3.1.1.5.2') + ).addVarBinds( + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.5.0'), + 'system name') + )) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/agent/ntforg/v3-trap.py b/examples/hlapi/asyncore/sync/agent/ntforg/v3-trap.py new file mode 100644 index 0000000..ba62b39 --- /dev/null +++ b/examples/hlapi/asyncore/sync/agent/ntforg/v3-trap.py @@ -0,0 +1,45 @@ +""" +SNMPv3 TRAP: auth SHA, privacy: AES128 +++++++++++++++++++++++++++++++++++++++ + +Send SNMP notification using the following options: + +* SNMPv3 +* with local snmpEngineId = 0x8000000001020304 (must configure at Receiver) +* with user 'usr-sha-aes128', auth: SHA, priv: AES128 +* over IPv4/UDP +* send TRAP notification +* with TRAP ID 'authenticationFailure' specified as a MIB symbol +* do not include any additional managed object information + +SNMPv3 TRAPs requires pre-sharing the Notification Originator's +value of SnmpEngineId with Notification Receiver. To facilitate that +we will use static (e.g. not autogenerated) version of snmpEngineId. + +Functionally similar to: + +| $ snmptrap -v3 -l authPriv -u usr-sha-aes -A authkey1 -X privkey1 \ +| -a SHA -x AES \ +| demo.snmplabs.com \ +| 12345 \ +| 1.3.6.1.4.1.20408.4.1.1.2 \ +| '1.3.6.1.2.1.1.1.0' s 'my system' + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + sendNotification(SnmpEngine(OctetString(hexValue='8000000001020304')), + UsmUserData('usr-sha-aes128', 'authkey1', 'privkey1', + authProtocol=usmHMACSHAAuthProtocol, + privProtocol=usmAesCfb128Protocol), + UdpTransportTarget(('localhost', 162)), + ContextData(), + 'trap', + NotificationType( + ObjectIdentity('SNMPv2-MIB', 'authenticationFailure') + ) + ) +) +if errorIndication: + print(errorIndication) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/coerce-set-value-to-mib-spec.py b/examples/hlapi/asyncore/sync/manager/cmdgen/coerce-set-value-to-mib-spec.py new file mode 100644 index 0000000..ab2df92 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/coerce-set-value-to-mib-spec.py @@ -0,0 +1,39 @@ +""" +Coerce value to SET to MIB spec ++++++++++++++++++++++++++++++++ + +Send SNMP SET request using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* setting SNMPv2-MIB::sysName.0 to new value (type taken from MIB) + +Functionally similar to: + +| $ snmpset -v2c -c public demo.snmplabs.com SNMPv2-MIB::sysDescr.0 \ +| = "new system name" + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + setCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1), + 'new system name')) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/custom-asn1-mib-search-path.py b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-asn1-mib-search-path.py new file mode 100644 index 0000000..22fbe6d --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-asn1-mib-search-path.py @@ -0,0 +1,39 @@ +""" +Custom ASN.1 MIB path ++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for IF-MIB::ifInOctets.1 MIB object +* pass non-default ASN.1 MIB source to MIB compiler + +Functionally similar to: + +| $ snmpget -v2c -c public -M /usr/share/snmp demo.snmplabs.com \ +| IF-MIB::ifInOctets.1 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1).addAsn1MibSource('file:///usr/share/snmp', 'http://mibs.snmplabs.com/asn1/@mib@'))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid-and-contextname.py b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid-and-contextname.py new file mode 100644 index 0000000..1244583 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid-and-contextname.py @@ -0,0 +1,45 @@ +""" +Custom ContextEngineId and ContextName +++++++++++++++++++++++++++++++++++++++ + +Send SNMP SET request using the following options: + +* with SNMPv3 with user 'usr-md5-none', MD5 auth and no privacy protocols +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* addressing particular set of Managed Objects at remote SNMP Engine by: + * contextEngineId 0x80004fb805636c6f75644dab22cc and + * contextName 'a172334d7d97871b72241397f713fa12' +* setting SNMPv2-MIB::sysName.0 to new value (type taken from MIB) + +Functionally similar to: + +| $ snmpset -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 \ +| -E 80004fb805636c6f75644dab22cc -n a172334d7d97871b72241397f713fa12 \ +| demo.snmplabs.com \ +| SNMPv2-MIB::sysORDescr.1 = "new system name" + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + setCmd(SnmpEngine(), + UsmUserData('usr-md5-none', 'authkey1'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(contextEngineId=OctetString(hexValue='80004fb805636c6f75644dab22cc'), + contextName='da761cfc8c94d3aceef4f60f049105ba'), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1), + 'new system name')) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid.py b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid.py new file mode 100644 index 0000000..ea97c59 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-contextengineid.py @@ -0,0 +1,43 @@ +""" +Custom ContextEngineId +++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols +* use remote SNMP Engine ID 0x80004fb805636c6f75644dab22cc (USM + autodiscovery will run) +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* setting SNMPv2-MIB::sysName.0 to new value (type coerced from MIB) + +Functionally similar to: + +| $ snmpset -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 \ +| -E 80004fb805636c6f75644dab22cc demo.snmplabs.com \ +| SNMPv2-MIB::sysORDescr.1 = "new system name" + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + setCmd(SnmpEngine(), + UsmUserData('usr-md5-des', 'authkey1', 'privkey1', + securityEngineId=OctetString(hexValue='80004fb805636c6f75644dab22cc')), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 0), + 'new system name')) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/custom-pysnmp-mibs-search-path.py b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-pysnmp-mibs-search-path.py new file mode 100644 index 0000000..42b1df6 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-pysnmp-mibs-search-path.py @@ -0,0 +1,45 @@ +""" +Custom PySNMP MIBs location ++++++++++++++++++++++++++++ + +Send a series of SNMP GETBULK requests using the following options: + +* with SNMPv3, user 'usr-none-none', no authentication, no privacy +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for all OIDs within TCP-MIB::tcpConnTable column +* TCP-MIB Python module will be searched by a user-specified filesystem + path (/opt/mib/pysnmp) and in Python package (python_packaged_mibs) + which should be in sys.path + +Functionally similar to: + +| $ snmpbulkwalk -v3 -lnoAuthNoPriv -u usr-none-none -Cn0 -Cr50 \ +| demo.snmplabs.com TCP-MIB::tcpConnTable + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in bulkCmd(SnmpEngine(), + UsmUserData('usr-none-none'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + 0, 50, + ObjectType(ObjectIdentity('TCP-MIB', 'tcpConnTable').addMibSource('/opt/mibs/pysnmp').addMibSource('python_packaged_mibs')), + lexicographicMode=False): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/custom-timeout-and-retries.py b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-timeout-and-retries.py new file mode 100644 index 0000000..cfa274f --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-timeout-and-retries.py @@ -0,0 +1,53 @@ +""" +Custom request timeout +++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for an OID in string form +* use custom timeout and request retries values + +Transport timing settings (maximum number of request retries and +individual request timeout in seconds) can be set on a per-target basis +as explained by the code that follows. + +Keep in mind that while timeout value can be specified in fractions of a +second, default pysnmp timer resolution is quite low (about 0.5 sec) +so there's no much point in using timeouts which is not a multiple of 0.5 +Internal timer can be programmatically adjusted to finer resolution if needed. + +If retries value is set to 0, pysnmp will issue a single request. Even +if no response arrives, there will be no retry. Likewise, retries=1 +means one initial request plus one retry. + +Functionally similar to: + +| $ snmpget -v1 -c public -t 2 -r 0 demo.snmplabs.com 1.3.6.1.2.1.1.1.0 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget( + ('demo.snmplabs.com', 161), timeout=2.0, retries=0 + ), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/custom-v3-security-name.py b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-v3-security-name.py new file mode 100644 index 0000000..4346b26 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/custom-v3-security-name.py @@ -0,0 +1,38 @@ +""" +Custom SecurityName ++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-md5-none', securityName 'myuser' + MD5 authentication, no privacy +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for an OID in text form + +The securityName parameter can be thought as an alias to userName and +allows you to address a USM Table row just as userName does. However +securityName can be made human-readable, also it is not an index in +usmUserTable, thus duplicate securityName parameters are possible. +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-md5-none', 'authkey1', securityName='myuser'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/fetch-variables-over-ipv6.py b/examples/hlapi/asyncore/sync/manager/cmdgen/fetch-variables-over-ipv6.py new file mode 100644 index 0000000..d431659 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/fetch-variables-over-ipv6.py @@ -0,0 +1,42 @@ +""" +GET over IPv6 ++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols +* over IPv6/UDP +* to an Agent at [::1]:161 +* for three OIDs in string form + +Functionally similar to: + +| $ snmpget -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 \ +| udp6:[::1]:161 \ +| 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 +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), + Udp6TransportTarget(('::1', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.2.0')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.3.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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-index.py b/examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-index.py new file mode 100644 index 0000000..fc8a882 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-index.py @@ -0,0 +1,41 @@ +""" +GET table row ++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-none-none', no authentication, no privacy +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for IF-MIB::ifInOctets.1 and IF-MIB::ifOutOctets.1 MIB object +* perform response OIDs and values resolution at MIB + +Functionally similar to: + +| $ snmpget -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 \ +| demo.snmplabs.com \ +| IF-MIB::ifInOctets.1 IF-MIB::ifOutOctets.1 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-none-none'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1)), + ObjectType(ObjectIdentity('IF-MIB', 'ifOutOctets', 1))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-multiple-indices.py b/examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-multiple-indices.py new file mode 100644 index 0000000..5d0621d --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/get-table-object-by-multiple-indices.py @@ -0,0 +1,46 @@ +""" +Fetch table row by composite index +++++++++++++++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-sha-aes128', SHA auth, AES128 privacy +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for TCP-MIB::tcpConnLocalAddress."0.0.0.0".22."0.0.0.0".0 MIB object + +Functionally similar to: + +| $ snmpget -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 \ +| -a SHA -x AES \ +| demo.snmplabs.com \ +| TCP-MIB::tcpConnLocalAddress."0.0.0.0".22."0.0.0.0".0 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-sha-aes128', 'authkey1', 'privkey1', + authProtocol=usmHMACSHAAuthProtocol, + privProtocol=usmAesCfb128Protocol ), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('TCP-MIB', + 'tcpConnLocalAddress', + '0.0.0.0', 22, + '0.0.0.0', 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-fetch-scalar-and-table-variables.py b/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-fetch-scalar-and-table-variables.py new file mode 100644 index 0000000..6b18d42 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-fetch-scalar-and-table-variables.py @@ -0,0 +1,48 @@ +""" +Fetch scalar and table variables +++++++++++++++++++++++++++++++++ + +Send a series of SNMP GETBULK requests using the following options: + +* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols +* over IPv6/UDP +* to an Agent at [::1]:161 +* with values non-repeaters = 1, max-repetitions = 25 +* for IP-MIB::ipAdEntAddr and all columns of the IF-MIB::ifEntry table +* stop when response OIDs leave the scopes of the table + +Functionally similar to: + +| $ snmpbulkwalk -v3 -lauthPriv -u usr-md5-des -A authkey1 -X privkey1 \ +| -Cn1, -Cr25 \ +| demo.snmplabs.com \ +| IP-MIB::ipAdEntAddr \ +| IP-MIB::ipAddrEntry + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in bulkCmd(SnmpEngine(), + UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), + Udp6TransportTarget(('::1', 161)), + ContextData(), + 1, 25, + ObjectType(ObjectIdentity('IP-MIB', 'ipAdEntAddr')), + ObjectType(ObjectIdentity('IP-MIB', 'ipAddrEntry')), + lexicographicMode=False): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-packets.py b/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-packets.py new file mode 100644 index 0000000..5146808 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-packets.py @@ -0,0 +1,44 @@ +""" +Walk Agent, limit number of packets ++++++++++++++++++++++++++++++++++++ + +Send a series of SNMP GETBULK requests using the following options: + +* 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 OR + maxCalls == 10 request-response interactions occur + +Functionally similar to: + +| $ snmpbulkwalk -v3 -lnoAuthNoPriv -u usr-none-none -Cn0 -Cr50 \ +| demo.snmplabs.com SNMPv2-MIB::system + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in bulkCmd(SnmpEngine(), + UsmUserData('usr-none-none'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + 0, 50, + ObjectType(ObjectIdentity('SNMPv2-MIB', 'system')), + maxCalls=10): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-variables.py b/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-variables.py new file mode 100644 index 0000000..ef95f5a --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/getbulk-limit-number-of-variables.py @@ -0,0 +1,47 @@ +""" +Walk MIB, limit number of response rows ++++++++++++++++++++++++++++++++++++++++ + +Send a series of SNMP GETBULK requests using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* with values non-repeaters = 0, max-repetitions = 25 +* for two OIDs in string form +* stop when response OIDs leave the scopes of initial OIDs OR + number of response rows reach fixed value (20) + +Functionally similar to: + +| $ snmpbulkwalk -v2c -c public demo.snmplabs.com \ +| -Cn0 -Cr25 \ +| 1.3.6.1.2.1.2.2 1.3.6.1.2.1.2.3 + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in bulkCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + 0, 25, + ObjectType(ObjectIdentity('1.3.6.1.2.1.2.2')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.2.3')), + lexicographicMode=False, maxRows=20): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/getnext-limit-number-of-variables.py b/examples/hlapi/asyncore/sync/manager/cmdgen/getnext-limit-number-of-variables.py new file mode 100644 index 0000000..9536ebb --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/getnext-limit-number-of-variables.py @@ -0,0 +1,46 @@ +""" +Fetch fixed amount of MIB variables ++++++++++++++++++++++++++++++++++++ + +Send a series of SNMP GETNEXT requests using the following options: + +* with SNMPv3, user 'usr-sha-aes128', SHA auth, AES128 privacy +* over UDP/IPv4 +* to an Agent at demo.snmplabs.com:161 +* for all OIDs past SNMPv2-MIB +* run till end-of-mib condition is reported by Agent OR maxRows == 100 +* ignoring non-increasing OIDs whenever reported by Agent + +Functionally similar to: + +| $ snmpwalk -v3 -lauthPriv -u usr-sha-aes128 -A authkey1 -X privkey1 \ +| -a MD5 -x AES demo.snmplabs.com \ +| SNMPv2-MIB::system + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in nextCmd(SnmpEngine(), + UsmUserData('usr-sha-aes128', 'authkey1', 'privkey1', + authProtocol=usmHMACSHAAuthProtocol, + privProtocol=usmAesCfb128Protocol), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('SNMPv2-MIB')), + maxRows=100, ignoreNonIncreasingOid=True): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/getnext-multiple-oids-to-eom.py b/examples/hlapi/asyncore/sync/manager/cmdgen/getnext-multiple-oids-to-eom.py new file mode 100644 index 0000000..c2858a7 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/getnext-multiple-oids-to-eom.py @@ -0,0 +1,43 @@ +""" +Fetch two OID branches +++++++++++++++++++++++ + +Send a series of SNMP GETNEXT requests using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for two OIDs in string form +* stop when response OIDs leave the scopes of initial OIDs + +Functionally similar to: + +| $ snmpwalk -v2c -c public demo.snmplabs.com \ +| 1.3.6.1.2.1.2.2.1.2 1.3.6.1.2.1.2.2.1.3 + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in nextCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.2.2.1.2')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.2.2.1.3')), + lexicographicMode=False): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/multiple-get-calls.py b/examples/hlapi/asyncore/sync/manager/cmdgen/multiple-get-calls.py new file mode 100644 index 0000000..d8c63ef --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/multiple-get-calls.py @@ -0,0 +1,47 @@ +""" +Sequence Of GET's ++++++++++++++++++ + +Send two SNMP GET requests in a row using the following options: + +* with SNMPv3, user 'usr-md5-none', MD5 authentication, no privacy +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for IF-MIB::ifInOctets.1 and IF-MIB::ifOutOctets.1 MIB objects + +Use a queue of MIB objects to query. + +The next() call is used to forward Python iterator to the position where it +could consume input + +Functionally similar to: + +| $ snmpget -v3 -l authNoPriv -u usr-md5-none -A authkey1 demo.snmplabs.com \ +| IF-MIB::ifInOctets.1 + +"""# +from pysnmp.hlapi import * + +queue = [ [ ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1)) ], + [ ObjectType(ObjectIdentity('IF-MIB', 'ifOutOctets', 1)) ] ] + +iter = getCmd(SnmpEngine(), + UsmUserData('usr-md5-none', 'authkey1'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData()) + +next(iter) + +while queue: + errorIndication, errorStatus, errorIndex, varBinds = iter.send(queue.pop()) + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/preload-pysnmp-mibs.py b/examples/hlapi/asyncore/sync/manager/cmdgen/preload-pysnmp-mibs.py new file mode 100644 index 0000000..885dbdf --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/preload-pysnmp-mibs.py @@ -0,0 +1,43 @@ +""" +Preload PySNMP MIBs ++++++++++++++++++++ + +Send a series of SNMP GETNEXT requests using the following options: + +* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols +* over IPv6/UDP +* to an Agent at [::1]:161 +* for all OIDs starting from 1.3.6 +* preload all Python MIB modules found in search path + +Functionally similar to: + +| $ snmpwalk -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 \ +| -m ALL +| udp6:[::1]:161 \ +| 1.3.6 + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in nextCmd(SnmpEngine(), + UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), + Udp6TransportTarget(('::1', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6').loadMibs())): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-mib.py b/examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-mib.py new file mode 100644 index 0000000..10538f2 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-mib.py @@ -0,0 +1,40 @@ +""" +Walk whole MIB +++++++++++++++ + +Send a series of SNMP GETNEXT requests using the following options: + +* 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 + +Functionally similar to: + +| $ snmpwalk -v3 -lauthPriv -u usr-md5-none -A authkey1 -X privkey1 \ +| demo.snmplabs.com 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-snmp-table.py b/examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-snmp-table.py new file mode 100644 index 0000000..5b8d221 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/pull-whole-snmp-table.py @@ -0,0 +1,53 @@ +""" +Fetch whole SNMP table +++++++++++++++++++++++ + +Send a series of SNMP GETNEXT requests using the following options: + +* with SNMPv1, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for some columns of the IF-MIB::ifEntry table +* stop when response OIDs leave the scopes of initial OIDs + +Functionally similar to: + +| $ snmpwalk -v1 -c public demo.snmplabs.com \ +| IF-MIB::ifDescr \ +| IF-MIB::ifType \ +| IF-MIB::ifMtu \ +| IF-MIB::ifSpeed \ +| IF-MIB::ifPhysAddress \ +| IF-MIB::ifType \ + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, \ + errorIndex, \ + varBinds in nextCmd(SnmpEngine(), + CommunityData('public', mpModel=0), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('IF-MIB', 'ifDescr')), + ObjectType(ObjectIdentity('IF-MIB', 'ifType')), + ObjectType(ObjectIdentity('IF-MIB', 'ifMtu')), + ObjectType(ObjectIdentity('IF-MIB', 'ifSpeed')), + ObjectType(ObjectIdentity('IF-MIB', 'ifPhysAddress')), + ObjectType(ObjectIdentity('IF-MIB', 'ifType')), + lexicographicMode=False): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/query-agents-from-multuple-threads.py b/examples/hlapi/asyncore/sync/manager/cmdgen/query-agents-from-multuple-threads.py new file mode 100644 index 0000000..34ead8b --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/query-agents-from-multuple-threads.py @@ -0,0 +1,127 @@ +""" +Query Agents from multiple threads +++++++++++++++++++++++++++++++++++ + +Send a bunch of SNMP GET requests simultaneously using the following options: + +* process 5 GET requests in 3 parallel threads +* with SNMPv1, community 'public' and + with SNMPv2c, community 'public' and + with SNMPv3, user 'usr-md5-des', MD5 auth and DES privacy +* over IPv4/UDP and + over IPv6/UDP +* to an Agent at demo.snmplabs.com:161 and + to an Agent at [::1]:161 +* for instances of SNMPv2-MIB::sysDescr.0 and + SNMPv2-MIB::sysLocation.0 MIB objects + +"""# +from sys import version_info +if version_info[0] == 2: + from Queue import Queue +else: + from queue import Queue +from threading import Thread +from pysnmp.hlapi import * + +# List of targets in the followin format: +# ( ( authData, transportTarget, varNames ), ... ) +targets = ( + # 1-st target (SNMPv1 over IPv4/UDP) + ( CommunityData('public', mpModel=0), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0)))), + # 2-nd target (SNMPv2c over IPv4/UDP) + ( CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0)))), + # 3-nd target (SNMPv2c over IPv4/UDP) - same community and + # different transport address. + ( CommunityData('public'), + UdpTransportTarget(('localhost', 161)), + ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysContact', 0)), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 0)))), + # 4-nd target (SNMPv3 over IPv4/UDP) + ( UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ))), + # 5-th target (SNMPv3 over IPv6/UDP) + ( UsmUserData('usr-md5-none', 'authkey1'), + Udp6TransportTarget(('::1', 161)), + ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0)))), + # N-th target + # ... +) + +class Worker(Thread): + def __init__(self, requests, responses): + Thread.__init__(self) + self.snmpEngine = SnmpEngine() + self.requests = requests + self.responses = responses + self.setDaemon(True) + self.start() + + def run(self): + while True: + authData, transportTarget, varBinds = self.requests.get() + self.responses.append( + next( + getCmd( + self.snmpEngine, + authData, transportTarget, ContextData(), *varBinds + ) + ) + ) + if hasattr(self.requests, 'task_done'): # 2.5+ + self.requests.task_done() + +class ThreadPool: + def __init__(self, num_threads): + self.requests = Queue(num_threads) + self.responses = [] + for _ in range(num_threads): + Worker(self.requests, self.responses) + + def addRequest(self, authData, transportTarget, varBinds): + self.requests.put((authData, transportTarget, varBinds)) + + def getResponses(self): return self.responses + + def waitCompletion(self): + if hasattr(self.requests, 'join'): + self.requests.join() # 2.5+ + else: + from time import sleep + # this is a lame substitute for missing .join() + # adding an explicit synchronization might be a better solution + while not self.requests.empty(): + sleep(1) + +pool = ThreadPool(3) + +# Submit GET requests +for authData, transportTarget, varBinds in targets: + pool.addRequest(authData, transportTarget, varBinds) + +# Wait for responses or errors +pool.waitCompletion() + +# Walk through responses +for errorIndication, errorStatus, errorIndex, varBinds in pool.getResponses(): + print('Response for %s from %s:' % (authData, transportTarget)) + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/set-multiple-scalar-values.py b/examples/hlapi/asyncore/sync/manager/cmdgen/set-multiple-scalar-values.py new file mode 100644 index 0000000..c3d3c5c --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/set-multiple-scalar-values.py @@ -0,0 +1,49 @@ +""" +SET scalars values +++++++++++++++++++ + +Send SNMP SET request using the following options: + +* with SNMPv1, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* setting three var-bindings to new values + +Please note, that in this example MIB lookup is only used +for the second var-bindins. For the rest, value types are +inferred from passed objects. + +Functionally similar to: + +| $ snmpset -v1 -c public demo.snmplabs.com \ +| 1.3.6.1.2.1.1.9.1.2.1 o 1.3.6.1.4.1.20408.1.1 \ +| 1.3.6.1.2.1.1.9.1.2.1 = 1.3.6.1.4.1.20408.1.1 \ +| 1.3.6.1.2.1.1.9.1.3.1 s "new system name" + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + setCmd(SnmpEngine(), + CommunityData('public', mpModel=0), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.9.1.2.1'), + ObjectIdentifier('1.3.6.1.4.1.20408.1.1')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.9.1.2.1'), + '1.3.6.1.4.1.20408.1.1'), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.9.1.3.1'), + OctetString('new system name'))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/specific-v3-engine-id.py b/examples/hlapi/asyncore/sync/manager/cmdgen/specific-v3-engine-id.py new file mode 100644 index 0000000..72263be --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/specific-v3-engine-id.py @@ -0,0 +1,86 @@ +""" +Discover SNMPv3 SecurityEngineId +++++++++++++++++++++++++++++++++ + +Send SNMP GET request using the following scenario and options: + +* try to communicate with a SNMPv3 Engine using: + +* a non-existing user +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 + +* if remote SNMP Engine ID is discovered, send SNMP GET request: + +* with SNMPv3, user 'usr-md5-none', MD5 authentication, no privacy + at discovered securityEngineId +* to the same SNMP Engine ID +* for an OID in text form + +"""# +from pysnmp.hlapi import * + +snmpEngine = SnmpEngine() + +transportTarget = UdpTransportTarget(('demo.snmplabs.com', 161)) + +# +# To discover remote SNMP EngineID we will tap on SNMP engine inner workings +# by setting up execution point observer setup on INTERNAL class PDU processing +# + +observerContext = {} + +# Register a callback to be invoked at specified execution point of +# SNMP Engine and passed local variables at execution point's local scope +snmpEngine.observer.registerObserver( + lambda e,p,v,c: c.update(securityEngineId=v['securityEngineId']), + 'rfc3412.prepareDataElements:internal', + cbCtx=observerContext +) + +# Send probe SNMP request with invalid credentials + +authData = UsmUserData('non-existing-user') + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(snmpEngine, authData, transportTarget, ContextData(), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))) +) + +# See if our SNMP engine received REPORT PDU containing securityEngineId + +if 'securityEngineId' not in observerContext: + print("Can't discover peer EngineID, errorIndication: %s" % errorIndication) + raise Exception() + +securityEngineId = observerContext.pop('securityEngineId') + +print('Remote securityEngineId = %s' % securityEngineId.prettyPrint()) + +# +# Query remote SNMP Engine using usmUserTable entry configured for it +# + +authData = UsmUserData('usr-md5-none', 'authkey1', + securityEngineId=securityEngineId) + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(snmpEngine, + authData, + transportTarget, + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))) +) + +if errorIndication: + print(errorIndication) +elif errorStatus: + print('%s at %s' % ( + errorStatus.prettyPrint(), + errorIndex and varBinds[int(errorIndex)-1][0] or '?' + ) + ) +else: + for name, val in varBinds: + print('%s = %s' % (name.prettyPrint(), val.prettyPrint())) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-des.py b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-des.py new file mode 100644 index 0000000..1d8030d --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-des.py @@ -0,0 +1,39 @@ +""" +SNMPv3: auth MD5, privacy DES ++++++++++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-md5-des', MD5 authentication, DES encryption +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for IF-MIB::ifInOctets.1 MIB object + +Functionally similar to: + +| $ snmpget -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 \ +| demo.snmplabs.com \ +| IF-MIB::ifInOctets.1 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-none.py b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-none.py new file mode 100644 index 0000000..c38d2f3 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-md5-none.py @@ -0,0 +1,38 @@ +""" +SNMPv3: auth MD5, no privacy +++++++++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-md5-none', MD5 authentication, no privacy +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for IF-MIB::ifInOctets.1 MIB object + +Functionally similar to: + +| $ snmpget -v3 -l authNoPriv -u usr-md5-none -A authkey1 demo.snmplabs.com \ +| IF-MIB::ifInOctets.1 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-md5-none', 'authkey1'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/usm-none-none.py b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-none-none.py new file mode 100644 index 0000000..15f570a --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-none-none.py @@ -0,0 +1,39 @@ +""" +SNMPv3: no auth, no privacy ++++++++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-none-none', no authentication, no encryption +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for IF-MIB::ifInOctets.1 MIB object + +Functionally similar to: + +| $ snmpget -v3 -l noAuthNoPriv -u usr-none-none +| demo.snmplabs.com \ +| IF-MIB::ifInOctets.1 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-none-none'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1))) +) + +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/usm-sha-aes128.py b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-sha-aes128.py new file mode 100644 index 0000000..1e985f5 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/usm-sha-aes128.py @@ -0,0 +1,57 @@ +""" +SNMPv3: auth SHA, privacy AES128 +++++++++++++++++++++++++++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv3, user 'usr-sha-aes', SHA authentication, AES128 encryption +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for SNMPv2-MIB::sysDescr.0 MIB object + +Available authentication protocols: + +#. usmHMACMD5AuthProtocol +#. usmHMACSHAAuthProtocol +#. usmNoAuthProtocol + +Available privacy protocols: + +#. usmDESPrivProtocol +#. usm3DESEDEPrivProtocol +#. usmAesCfb128Protocol +#. usmAesCfb192Protocol +#. usmAesCfb256Protocol +#. usmNoPrivProtocol + +Functionally similar to: + +| $ snmpget -v3 -l authPriv -u usr-sha-aes -A authkey1 -X privkey1 \ +| -a SHA -x AES \ +| demo.snmplabs.com \ +| SNMPv2-MIB::sysDescr.0 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + UsmUserData('usr-sha-aes', 'authkey1', 'privkey1', + authProtocol=usmHMACSHAAuthProtocol, + privProtocol=usmAesCfb128Protocol), + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/v1-get.py b/examples/hlapi/asyncore/sync/manager/cmdgen/v1-get.py new file mode 100644 index 0000000..3f03c7c --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/v1-get.py @@ -0,0 +1,37 @@ +""" +SNMPv1 +++++++ + +Send SNMP GET request using the following options: + + * 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, + +Functionally similar to: + +| $ snmpget -v1 -c public demo.snmplabs.com SNMPv2-MIB::sysDescr.0 + +"""# +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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/v2c-get.py b/examples/hlapi/asyncore/sync/manager/cmdgen/v2c-get.py new file mode 100644 index 0000000..169b6a6 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/v2c-get.py @@ -0,0 +1,39 @@ +""" +SNMPv2c ++++++++ + +Send SNMP GET request using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for two OIDs in string form + +Functionally similar to: + +| $ snmpget -v2c -c public demo.snmplabs.com 1.3.6.1.2.1.1.1.0 \ +| 1.3.6.1.2.1.1.6.0 + +"""# +from pysnmp.hlapi import * + +errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1.6.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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/v2c-getbulk.py b/examples/hlapi/asyncore/sync/manager/cmdgen/v2c-getbulk.py new file mode 100644 index 0000000..a65bb35 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/v2c-getbulk.py @@ -0,0 +1,46 @@ +""" +Bulk walk MIB ++++++++++++++ + +Send a series of SNMP GETBULK requests using the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* with values non-repeaters = 0, max-repetitions = 25 +* for two OIDs in string form +* stop when response OIDs leave the scopes of initial OIDs + +Functionally similar to: + +| $ snmpbulkwalk -v2c -c public demo.snmplabs.com \ +| -Cn0 -Cr25 \ +| 1.3.6.1.2.1.2.2 1.3.6.1.2.1.2.3 + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in bulkCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + 0, 25, + ObjectType(ObjectIdentity('1.3.6.1.2.1.2.2')), + ObjectType(ObjectIdentity('1.3.6.1.2.1.2.3')), + lexicographicMode=False): + + 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 ])) diff --git a/examples/hlapi/asyncore/sync/manager/cmdgen/waive-mib-lookup.py b/examples/hlapi/asyncore/sync/manager/cmdgen/waive-mib-lookup.py new file mode 100644 index 0000000..7038d96 --- /dev/null +++ b/examples/hlapi/asyncore/sync/manager/cmdgen/waive-mib-lookup.py @@ -0,0 +1,45 @@ +""" +Waive MIB lookup +++++++++++++++++ + +Perform SNMP GETNEXT operation with the following options: + +* with SNMPv2c, community 'public' +* over IPv4/UDP +* to an Agent at demo.snmplabs.com:161 +* for an OID in string form +* do not resolve response OIDs and values into human-freidly form + +False lookupMib keyword arguments could make pysnmp waiving +OIDs and values resolution in response variable-bindings, into human +friendly form. + +Functionally similar to: + +| $ snmpwalk -v2c -c public -ObentU demo.snmplabs.com 1.3.6.1.2.1 + +"""# +from pysnmp.hlapi import * + +for errorIndication, \ + errorStatus, errorIndex, \ + varBinds in nextCmd(SnmpEngine(), + CommunityData('public'), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('1.3.6.1.2.1.1')), + lookupMib=False): + + 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 ])) diff --git a/pysnmp/hlapi/asyncore/sync/__init__.py b/pysnmp/hlapi/asyncore/sync/__init__.py new file mode 100644 index 0000000..2a14fd2 --- /dev/null +++ b/pysnmp/hlapi/asyncore/sync/__init__.py @@ -0,0 +1,13 @@ +from pysnmp.proto.rfc1902 import * +from pysnmp.smi.rfc1902 import * +from pysnmp.hlapi.auth import * +from pysnmp.hlapi.context import * +from pysnmp.hlapi.asyncore.transport import * +from pysnmp.entity.engine import * + +try: + from pysnmp.hlapi.asyncore._sync.cmdgen import * + from pysnmp.hlapi.asyncore._sync.ntforg import * +except SyntaxError: + from pysnmp.hlapi.asyncore._sync.compat.cmdgen import * + from pysnmp.hlapi.asyncore._sync.compat.ntforg import * diff --git a/pysnmp/hlapi/asyncore/sync/cmdgen.py b/pysnmp/hlapi/asyncore/sync/cmdgen.py new file mode 100644 index 0000000..5cb8ab4 --- /dev/null +++ b/pysnmp/hlapi/asyncore/sync/cmdgen.py @@ -0,0 +1,605 @@ +from pysnmp.hlapi.asyncore import cmdgen +from pysnmp.hlapi.varbinds import * +from pysnmp.proto.rfc1905 import endOfMibView +from pysnmp.proto import errind +from pyasn1.type.univ import Null + +__all__ = ['getCmd', 'nextCmd', 'setCmd', 'bulkCmd'] + +def getCmd(snmpEngine, authData, transportTarget, contextData, + *varBinds, **options): + """Creates a generator to perform one or more SNMP GET queries. + + On each iteration, new SNMP GET request is send (:RFC:`1905#section-4.2.1`). + The iterator blocks waiting for response to arrive or error to occur. + + Parameters + ---------- + snmpEngine : :py:class:`~pysnmp.hlapi.SnmpEngine` + Class instance representing SNMP engine. + + authData : :py:class:`~pysnmp.hlapi.CommunityData` or :py:class:`~pysnmp.hlapi.UsmUserData` + Class instance representing SNMP credentials. + + transportTarget : :py:class:`~pysnmp.hlapi.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.asyncore.Udp6TransportTarget` + Class instance representing transport type along with SNMP peer address. + + contextData : :py:class:`~pysnmp.hlapi.ContextData` + Class instance representing SNMP ContextEngineId and ContextName values. + + \*varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType` + One or more class instances representing MIB variables to place + into SNMP request. + + Other Parameters + ---------------- + \*\*options : + Request options: + + * `lookupMib` - load MIB and resolve response MIB variables at + the cost of slightly reduced performance. Default is `True`. + + Yields + ------ + errorIndication : str + True value indicates SNMP engine error. + errorStatus : str + True value indicates SNMP PDU error. + errorIndex : int + Non-zero value refers to `varBinds[errorIndex-1]` + varBinds : tuple + A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class + instances representing MIB variables returned in SNMP response. + + Raises + ------ + PySnmpError + Or its derivative indicating that an error occurred while + performing SNMP operation. + + Notes + ----- + The `getCmd` generator will be exhausted immidiately unless + a new sequence of `varBinds` are send back into running generator + (supported since Python 2.6). + + Examples + -------- + >>> from pysnmp.hlapi.asyncore import * + >>> g = getCmd(SnmpEngine(), + ... CommunityData('public'), + ... UdpTransportTarget(('demo.snmplabs.com', 161)), + ... ContextData(), + ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))) + >>> next(g) + (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))]) + >>> + + """ + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBinds, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBinds'] = varBinds + + cbCtx = {} + + while True: + if varBinds: + cmdgen.getCmd( + snmpEngine, + authData, + transportTarget, + contextData, + varBinds, + cbFun, cbCtx, + options.get('lookupMib', True) + ) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + varBinds = cbCtx['varBinds'] + else: + errorIndication = errorStatus = errorIndex = None + varBinds = [] + + varBinds = ( yield errorIndication, errorStatus, errorIndex, varBinds ) + + if not varBinds: + break + +def setCmd(snmpEngine, authData, transportTarget, contextData, + *varBinds, **options): + """Creates a generator to perform one or more SNMP SET queries. + + On each iteration, new SNMP SET request is send (:RFC:`1905#section-4.2.5`). + The iterator blocks waiting for response to arrive or error to occur. + + Parameters + ---------- + snmpEngine : :py:class:`~pysnmp.hlapi.SnmpEngine` + Class instance representing SNMP engine. + + authData : :py:class:`~pysnmp.hlapi.CommunityData` or :py:class:`~pysnmp.hlapi.UsmUserData` + Class instance representing SNMP credentials. + + transportTarget : :py:class:`~pysnmp.hlapi.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.asyncore.Udp6TransportTarget` + Class instance representing transport type along with SNMP peer address. + + contextData : :py:class:`~pysnmp.hlapi.ContextData` + Class instance representing SNMP ContextEngineId and ContextName values. + + \*varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType` + One or more class instances representing MIB variables to place + into SNMP request. + + Other Parameters + ---------------- + \*\*options : + Request options: + + * `lookupMib` - load MIB and resolve response MIB variables at + the cost of slightly reduced performance. Default is `True`. + Default is `True`. + + Yields + ------ + errorIndication : str + True value indicates SNMP engine error. + errorStatus : str + True value indicates SNMP PDU error. + errorIndex : int + Non-zero value refers to `varBinds[errorIndex-1]` + varBinds : tuple + A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class + instances representing MIB variables returned in SNMP response. + + Raises + ------ + PySnmpError + Or its derivative indicating that an error occurred while + performing SNMP operation. + + Notes + ----- + The `setCmd` generator will be exhausted immidiately unless + a new sequence of `varBinds` are send back into running generator + (supported since Python 2.6). + + Examples + -------- + >>> from pysnmp.hlapi.asyncore import * + >>> g = setCmd(SnmpEngine(), + ... CommunityData('public'), + ... UdpTransportTarget(('demo.snmplabs.com', 161)), + ... ContextData(), + ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), 'Linux i386')) + >>> next(g) + (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('Linux i386'))]) + >>> + + """ + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBinds, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBinds'] = varBinds + + cbCtx = {} + + while True: + if varBinds: + cmdgen.setCmd( + snmpEngine, + authData, + transportTarget, + contextData, + varBinds, + cbFun, cbCtx, + options.get('lookupMib', True) + ) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + varBinds = cbCtx['varBinds'] + else: + errorIndication = errorStatus = errorIndex = None + varBinds = [] + + varBinds = ( yield errorIndication, errorStatus, errorIndex, varBinds ) + + if not varBinds: + break + +def nextCmd(snmpEngine, authData, transportTarget, contextData, + *varBinds, **options): + """Creates a generator to perform one or more SNMP GETNEXT queries. + + On each iteration, new SNMP GETNEXT request is send + (:RFC:`1905#section-4.2.2`). The iterator blocks waiting for response + to arrive or error to occur. + + Parameters + ---------- + snmpEngine : :py:class:`~pysnmp.hlapi.SnmpEngine` + Class instance representing SNMP engine. + + authData : :py:class:`~pysnmp.hlapi.CommunityData` or :py:class:`~pysnmp.hlapi.UsmUserData` + Class instance representing SNMP credentials. + + transportTarget : :py:class:`~pysnmp.hlapi.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.asyncore.Udp6TransportTarget` + Class instance representing transport type along with SNMP peer address. + + contextData : :py:class:`~pysnmp.hlapi.ContextData` + Class instance representing SNMP ContextEngineId and ContextName values. + + \*varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType` + One or more class instances representing MIB variables to place + into SNMP request. + + Other Parameters + ---------------- + \*\*options : + Request options: + + * `lookupMib` - load MIB and resolve response MIB variables at + the cost of slightly reduced performance. Default is `True`. + Default is `True`. + * `lexicographicMode` - stop iteration when all response MIB + variables leave the scope of initial MIB variables in + `varBinds`. Default is `True`. + * `ignoreNonIncreasingOid` - continue iteration even if response + MIB variables (OIDs) are not greater then request MIB variables. + Default is `False`. + * `maxRows` - stop iteration once this generator instance processed + `maxRows` of SNMP conceptual table. Default is `0` (no limit). + * `maxCalls` - stop iteration once this generator instance processed + `maxCalls` responses. Default is 0 (no limit). + + Yields + ------ + errorIndication : str + True value indicates SNMP engine error. + errorStatus : str + True value indicates SNMP PDU error. + errorIndex : int + Non-zero value refers to `varBinds[errorIndex-1]` + varBinds : tuple + A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class + instances representing MIB variables returned in SNMP response. + + Raises + ------ + PySnmpError + Or its derivative indicating that an error occurred while + performing SNMP operation. + + Notes + ----- + The `nextCmd` generator will be exhausted on any of the following + conditions: + + * SNMP engine error occurs thus `errorIndication` is `True` + * SNMP PDU `errorStatus` is reported as `True` + * SNMP :py:class:`~pysnmp.proto.rfc1905.EndOfMibView` values + (also known as *SNMP exception values*) are reported for all + MIB variables in `varBinds` + * *lexicographicMode* option is set to `False` and all + response MIB variables leave the scope of `varBinds` + + At any moment a new sequence of `varBinds` could be send back into + running generator (supported since Python 2.6). + + Examples + -------- + >>> from pysnmp.hlapi.asyncore import * + >>> g = nextCmd(SnmpEngine(), + ... CommunityData('public'), + ... UdpTransportTarget(('demo.snmplabs.com', 161)), + ... ContextData(), + ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'))) + >>> next(g) + (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))]) + >>> g.send( [ ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets')) ] ) + (None, 0, 0, [(ObjectName('1.3.6.1.2.1.2.2.1.10.1'), Counter32(284817787))]) + """ + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBindTable, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBindTable'] = varBindTable + + lookupMib = options.get('lookupMib', True) + lexicographicMode = options.get('lexicographicMode', True) + ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False) + maxRows = options.get('maxRows', 0) + maxCalls = options.get('maxCalls', 0) + + cbCtx = {} + + vbProcessor = CommandGeneratorVarBinds() + + initialVars = [ x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds) ] + + totalRows = totalCalls = 0 + + while True: + if varBinds: + cmdgen.nextCmd(snmpEngine, + authData, + transportTarget, + contextData, + [ (x[0], Null()) for x in varBinds ], + cbFun, cbCtx, + lookupMib) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + + if ignoreNonIncreasingOid and errorIndication and \ + isinstance(errorIndication, errind.OidNotIncreasing): + errorIndication = None + + if errorIndication: + yield errorIndication, errorStatus, errorIndex, varBinds + return + elif errorStatus: + if errorStatus == 2: + # Hide SNMPv1 noSuchName error which leaks in here + # from SNMPv1 Agent through internal pysnmp proxy. + errorStatus = errorStatus.clone(0) + errorIndex = errorIndex.clone(0) + yield errorIndication, errorStatus, errorIndex, varBinds + return + else: + varBinds = cbCtx['varBindTable'] and cbCtx['varBindTable'][0] + for idx, varBind in enumerate(varBinds): + name, val = varBind + if not isinstance(val, Null): + if lexicographicMode or initialVars[idx].isPrefixOf(name): + break + else: + return + + totalRows += 1 + totalCalls += 1 + else: + errorIndication = errorStatus = errorIndex = None + varBinds = [] + + initialVarBinds = ( yield errorIndication, errorStatus, + errorIndex, varBinds ) + + if initialVarBinds: + varBinds = initialVarBinds + initialVars = [ x[0] for x in vbProcessor.makeVarBinds(snmpEngine, + varBinds) ] + + if maxRows and totalRows >= maxRows or \ + maxCalls and totalCalls >= maxCalls: + return + +def bulkCmd(snmpEngine, authData, transportTarget, contextData, + nonRepeaters, maxRepetitions, *varBinds, **options): + """Creates a generator to perform one or more SNMP GETBULK queries. + + On each iteration, new SNMP GETBULK request is send + (:RFC:`1905#section-4.2.3`). The iterator blocks waiting for response + to arrive or error to occur. + + Parameters + ---------- + snmpEngine : :py:class:`~pysnmp.hlapi.SnmpEngine` + Class instance representing SNMP engine. + + authData : :py:class:`~pysnmp.hlapi.CommunityData` or :py:class:`~pysnmp.hlapi.UsmUserData` + Class instance representing SNMP credentials. + + transportTarget : :py:class:`~pysnmp.hlapi.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.asyncore.Udp6TransportTarget` + Class instance representing transport type along with SNMP peer address. + + contextData : :py:class:`~pysnmp.hlapi.ContextData` + Class instance representing SNMP ContextEngineId and ContextName values. + + nonRepeaters : int + One MIB variable is requested in response for the first + `nonRepeaters` MIB variables in request. + + maxRepetitions : int + `maxRepetitions` MIB variables are requested in response for each + of the remaining MIB variables in the request (e.g. excluding + `nonRepeaters`). Remote SNMP engine may choose lesser value than + requested. + + \*varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType` + One or more class instances representing MIB variables to place + into SNMP request. + + Other Parameters + ---------------- + \*\*options : + Request options: + + * `lookupMib` - load MIB and resolve response MIB variables at + the cost of slightly reduced performance. Default is `True`. + Default is `True`. + * `lexicographicMode` - stop iteration when all response MIB + variables leave the scope of initial MIB variables in + `varBinds`. Default is `True`. + * `ignoreNonIncreasingOid` - continue iteration even if response + MIB variables (OIDs) are not greater then request MIB variables. + Default is `False`. + * `maxRows` - stop iteration once this generator instance processed + `maxRows` of SNMP conceptual table. Default is `0` (no limit). + * `maxCalls` - stop iteration once this generator instance processed + `maxCalls` responses. Default is 0 (no limit). + + Yields + ------ + errorIndication : str + True value indicates SNMP engine error. + errorStatus : str + True value indicates SNMP PDU error. + errorIndex : int + Non-zero value refers to \*varBinds[errorIndex-1] + varBinds : tuple + A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class + instances representing MIB variables returned in SNMP response. + + Raises + ------ + PySnmpError + Or its derivative indicating that an error occurred while + performing SNMP operation. + + Notes + ----- + The `bulkCmd` generator will be exhausted on any of the following + conditions: + + * SNMP engine error occurs thus `errorIndication` is `True` + * SNMP PDU `errorStatus` is reported as `True` + * SNMP :py:class:`~pysnmp.proto.rfc1905.EndOfMibView` values + (also known as *SNMP exception values*) are reported for all + MIB variables in `varBinds` + * *lexicographicMode* option is set to `False` and all + response MIB variables leave the scope of `varBinds` + + At any moment a new sequence of `varBinds` could be send back into + running generator (supported since Python 2.6). + + Setting `maxRepetitions` value to 15..50 might significantly improve + system performance, as many MIB variables get packed into a single + response message at once. + + Examples + -------- + >>> from pysnmp.hlapi.asyncore import * + >>> g = bulkCmd(SnmpEngine(), + ... CommunityData('public'), + ... UdpTransportTarget(('demo.snmplabs.com', 161)), + ... ContextData(), + ... 0, 25, + ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'))) + >>> next(g) + (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))]) + >>> g.send( [ ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets')) ] ) + (None, 0, 0, [(ObjectName('1.3.6.1.2.1.2.2.1.10.1'), Counter32(284817787))]) + """ + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBindTable, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBindTable'] = varBindTable + + lookupMib = options.get('lookupMib', True) + lexicographicMode = options.get('lexicographicMode', True) + ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False) + maxRows = options.get('maxRows', 0) + maxCalls = options.get('maxCalls', 0) + + cbCtx = {} + + vbProcessor = CommandGeneratorVarBinds() + + initialVars = [ x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds) ] + nullVarBinds = [ False ] * len(initialVars) + + totalRows = totalCalls = 0 + stopFlag = False + + while not stopFlag: + if maxRows and totalRows < maxRows: + maxRepetitions = min(maxRepetitions, maxRows-totalRows) + + cmdgen.bulkCmd(snmpEngine, + authData, + transportTarget, + contextData, + nonRepeaters, maxRepetitions, + [ (x[0], Null()) for x in varBinds ], + cbFun, cbCtx, + lookupMib) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + varBindTable = cbCtx['varBindTable'] + + if ignoreNonIncreasingOid and errorIndication and \ + isinstance(errorIndication, errind.OidNotIncreasing): + errorIndication = None + + if errorIndication: + yield errorIndication, errorStatus, errorIndex, \ + varBindTable and varBindTable[0] or [] + if errorIndication != errind.requestTimedOut: + return + elif errorStatus: + if errorStatus == 2: + # Hide SNMPv1 noSuchName error which leaks in here + # from SNMPv1 Agent through internal pysnmp proxy. + errorStatus = errorStatus.clone(0) + errorIndex = errorIndex.clone(0) + yield errorIndication, errorStatus, errorIndex, \ + varBindTable and varBindTable[0] or [] + return + else: + for i in range(len(varBindTable)): + stopFlag = True + if len(varBindTable[i]) != len(initialVars): + varBindTable = i and varBindTable[:i-1] or [] + break + for j in range(len(varBindTable[i])): + name, val = varBindTable[i][j] + if nullVarBinds[j]: + varBindTable[i][j] = name, endOfMibView + continue + stopFlag = False + if isinstance(val, Null): + nullVarBinds[j] = True + elif not lexicographicMode and \ + not initialVars[j].isPrefixOf(name): + varBindTable[i][j] = name, endOfMibView + nullVarBinds[j] = True + if stopFlag: + varBindTable = i and varBindTable[:i-1] or [] + break + + totalRows += len(varBindTable) + totalCalls += 1 + + if maxRows and totalRows >= maxRows: + if totalRows > maxRows: + varBindTable = varBindTable[:-(totalRows-maxRows)] + stopFlag = True + + if maxCalls and totalCalls >= maxCalls: + stopFlag = True + + for varBinds in varBindTable: + initialVarBinds = ( yield errorIndication, errorStatus, + errorIndex, varBinds ) + + if initialVarBinds: + varBinds = initialVarBinds + initialVars = [ x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds) ] diff --git a/pysnmp/hlapi/asyncore/sync/compat/cmdgen.py b/pysnmp/hlapi/asyncore/sync/compat/cmdgen.py new file mode 100644 index 0000000..701cb5f --- /dev/null +++ b/pysnmp/hlapi/asyncore/sync/compat/cmdgen.py @@ -0,0 +1,258 @@ +# +# This is a Python 2.6- version of the same file at level up +# +from pysnmp.hlapi.asyncore import cmdgen +from pysnmp.hlapi.varbinds import * +from pysnmp.proto.rfc1905 import endOfMibView +from pysnmp.proto import errind +from pyasn1.type.univ import Null + +__all__ = ['getCmd', 'nextCmd', 'setCmd', 'bulkCmd', 'next'] + +def next(iter): + return iter.next() + +def getCmd(snmpEngine, authData, transportTarget, contextData, + *varBinds, **options): + + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBinds, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBinds'] = varBinds + + cbCtx = {} + + if varBinds: + cmdgen.getCmd( + snmpEngine, + authData, + transportTarget, + contextData, + varBinds, + cbFun, cbCtx, + options.get('lookupMib', True) + ) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + varBinds = cbCtx['varBinds'] + else: + errorIndication = errorStatus = errorIndex = None + varBinds = [] + + yield errorIndication, errorStatus, errorIndex, varBinds + +def setCmd(snmpEngine, authData, transportTarget, contextData, + *varBinds, **options): + + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBinds, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBinds'] = varBinds + + cbCtx = {} + + while True: + cmdgen.setCmd( + snmpEngine, + authData, + transportTarget, + contextData, + varBinds, + cbFun, cbCtx, + options.get('lookupMib', True) + ) + + snmpEngine.transportDispatcher.runDispatcher() + + yield cbCtx['errorIndication'], \ + cbCtx['errorStatus'], cbCtx['errorIndex'], \ + cbCtx['varBinds'] + + if cbCtx['errorIndication'] != errind.requestTimedOut: + break + +def nextCmd(snmpEngine, authData, transportTarget, contextData, + *varBinds, **options): + + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBindTable, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBindTable'] = varBindTable + + lookupMib = options.get('lookupMib', True) + lexicographicMode = options.get('lexicographicMode', True) + ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False) + maxRows = options.get('maxRows', 0) + maxCalls = options.get('maxCalls', 0) + + cbCtx = {} + + vbProcessor = CommandGeneratorVarBinds() + + initialVars = [ x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds) ] + + totalRows = totalCalls = 0 + + while True: + cmdgen.nextCmd(snmpEngine, + authData, + transportTarget, + contextData, + [ (x[0], Null()) for x in varBinds ], + cbFun, cbCtx, + lookupMib) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + + if ignoreNonIncreasingOid and errorIndication and \ + isinstance(errorIndication, errind.OidNotIncreasing): + errorIndication = None + + if errorIndication: + yield errorIndication, errorStatus, errorIndex, varBinds + if errorIndication != errind.requestTimedOut: + return + elif errorStatus: + if errorStatus == 2: + # Hide SNMPv1 noSuchName error which leaks in here + # from SNMPv1 Agent through internal pysnmp proxy. + errorStatus = errorStatus.clone(0) + errorIndex = errorIndex.clone(0) + yield errorIndication, errorStatus, errorIndex, varBinds + return + else: + varBinds = cbCtx['varBindTable'] and cbCtx['varBindTable'][0] + for idx, varBind in enumerate(varBinds): + name, val = varBind + if not isinstance(val, Null): + if lexicographicMode or initialVars[idx].isPrefixOf(name): + break + else: + return + + totalRows += 1 + totalCalls += 1 + + yield errorIndication, errorStatus, errorIndex, varBinds + + if maxRows and totalRows >= maxRows or \ + maxCalls and totalCalls >= maxCalls: + return + +def bulkCmd(snmpEngine, authData, transportTarget, contextData, + nonRepeaters, maxRepetitions, *varBinds, **options): + + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBindTable, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBindTable'] = varBindTable + + lookupMib = options.get('lookupMib', True) + lexicographicMode = options.get('lexicographicMode', True) + ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False) + maxRows = options.get('maxRows', 0) + maxCalls = options.get('maxCalls', 0) + + cbCtx = {} + + vbProcessor = CommandGeneratorVarBinds() + + initialVars = [ x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds) ] + nullVarBinds = [ False ] * len(initialVars) + + totalRows = totalCalls = 0 + stopFlag = False + + while not stopFlag: + if maxRows and totalRows < maxRows: + maxRepetitions = min(maxRepetitions, maxRows-totalRows) + + cmdgen.bulkCmd(snmpEngine, + authData, + transportTarget, + contextData, + nonRepeaters, maxRepetitions, + [ (x[0], Null()) for x in varBinds ], + cbFun, cbCtx, + lookupMib) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx['errorIndication'] + errorStatus = cbCtx['errorStatus'] + errorIndex = cbCtx['errorIndex'] + varBindTable = cbCtx['varBindTable'] + + if ignoreNonIncreasingOid and errorIndication and \ + isinstance(errorIndication, errind.OidNotIncreasing): + errorIndication = None + + if errorIndication: + yield errorIndication, errorStatus, errorIndex, \ + varBindTable and varBindTable[0] or [] + if errorIndication != errind.requestTimedOut: + return + elif errorStatus: + if errorStatus == 2: + # Hide SNMPv1 noSuchName error which leaks in here + # from SNMPv1 Agent through internal pysnmp proxy. + errorStatus = errorStatus.clone(0) + errorIndex = errorIndex.clone(0) + yield errorIndication, errorStatus, errorIndex, \ + varBindTable and varBindTable[0] or [] + return + else: + for i in range(len(varBindTable)): + stopFlag = True + if len(varBindTable[i]) != len(initialVars): + varBindTable = i and varBindTable[:i-1] or [] + break + for j in range(len(varBindTable[i])): + name, val = varBindTable[i][j] + if nullVarBinds[j]: + varBindTable[i][j] = name, endOfMibView + continue + stopFlag = False + if isinstance(val, Null): + nullVarBinds[j] = True + elif not lexicographicMode and \ + not initialVars[j].isPrefixOf(name): + varBindTable[i][j] = name, endOfMibView + nullVarBinds[j] = True + if stopFlag: + varBindTable = i and varBindTable[:i-1] or [] + break + + totalRows += len(varBindTable) + totalCalls += 1 + + if maxRows and totalRows >= maxRows: + if totalRows > maxRows: + varBindTable = varBindTable[:-(totalRows-maxRows)] + stopFlag = True + + if maxCalls and totalCalls >= maxCalls: + stopFlag = True + + for varBinds in varBindTable: + yield errorIndication, errorStatus, errorIndex, varBinds diff --git a/pysnmp/hlapi/asyncore/sync/compat/ntforg.py b/pysnmp/hlapi/asyncore/sync/compat/ntforg.py new file mode 100644 index 0000000..92b32b3 --- /dev/null +++ b/pysnmp/hlapi/asyncore/sync/compat/ntforg.py @@ -0,0 +1,50 @@ +# +# This is a Python 2.6- version of the same file at level up +# +from pysnmp.hlapi.asyncore import ntforg + +__all__ = ['sendNotification', 'next'] + +def next(iter): + return iter.next() + +# +# Synchronous one-liner SNMP Notification Originator application +# + +def sendNotification(snmpEngine, authData, transportTarget, contextData, + notifyType, varBinds, **options): + + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBinds, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBinds'] = varBinds + + cbCtx = {} + + if varBinds: + ntforg.sendNotification( + snmpEngine, + authData, + transportTarget, + contextData, + notifyType, + varBinds, + cbFun, cbCtx, + options.get('lookupMib', True) + ) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx.get('errorIndication') + errorStatus = cbCtx.get('errorStatus') + errorIndex = cbCtx.get('errorIndex') + varBinds = cbCtx.get('varBinds', []) + else: + errorIndication = errorStatus = errorIndex = None + varBinds = [] + + yield errorIndication, errorStatus, errorIndex, varBinds diff --git a/pysnmp/hlapi/asyncore/sync/ntforg.py b/pysnmp/hlapi/asyncore/sync/ntforg.py new file mode 100644 index 0000000..e43a974 --- /dev/null +++ b/pysnmp/hlapi/asyncore/sync/ntforg.py @@ -0,0 +1,122 @@ +from pysnmp.hlapi.asyncore import ntforg + +__all__ = ['sendNotification'] + +def sendNotification(snmpEngine, authData, transportTarget, contextData, + notifyType, varBinds, **options): + """Creates a generator to send one or more SNMP notifications. + + On each iteration, new SNMP TRAP or INFORM notification is send + (:RFC:`1905#section-4,2,6`). The iterator blocks waiting for + INFORM acknowlegement to arrive or error to occur. + + Parameters + ---------- + snmpEngine : :py:class:`~pysnmp.hlapi.SnmpEngine` + Class instance representing SNMP engine. + + authData : :py:class:`~pysnmp.hlapi.CommunityData` or :py:class:`~pysnmp.hlapi.UsmUserData` + Class instance representing SNMP credentials. + + transportTarget : :py:class:`~pysnmp.hlapi.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.asyncore.Udp6TransportTarget` + Class instance representing transport type along with SNMP peer address. + + contextData : :py:class:`~pysnmp.hlapi.ContextData` + Class instance representing SNMP ContextEngineId and ContextName values. + + notifyType : str + Indicates type of notification to be sent. Recognized literal + values are *trap* or *inform*. + + varBinds: tuple + Single :py:class:`~pysnmp.smi.rfc1902.NotificationType` class instance + representing a minimum sequence of MIB variables required for + particular notification type. + Alternatively, a sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` + objects could be passed instead. In the latter case it is up to + the user to ensure proper Notification PDU contents. + + Other Parameters + ---------------- + \*\*options : + Request options: + + * `lookupMib` - load MIB and resolve response MIB variables at + the cost of slightly reduced performance. Default is `True`. + + Yields + ------ + errorIndication : str + True value indicates SNMP engine error. + errorStatus : str + True value indicates SNMP PDU error. + errorIndex : int + Non-zero value refers to `varBinds[errorIndex-1]` + varBinds : tuple + A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class + instances representing MIB variables returned in SNMP response. + + Raises + ------ + PySnmpError + Or its derivative indicating that an error occurred while + performing SNMP operation. + + Notes + ----- + The `sendNotification` generator will be exhausted immidiately unless + an instance of :py:class:`~pysnmp.smi.rfc1902.NotificationType` class + or a sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` `varBinds` + are send back into running generator (supported since Python 2.6). + + Examples + -------- + >>> from pysnmp.hlapi.asyncore import * + >>> g = sendNotification(SnmpEngine(), + ... CommunityData('public'), + ... UdpTransportTarget(('demo.snmplabs.com', 162)), + ... ContextData(), + ... 'trap', + ... NotificationType(ObjectIdentity('IF-MIB', 'linkDown'))) + >>> next(g) + (None, 0, 0, []) + >>> + + """ + def cbFun(snmpEngine, sendRequestHandle, + errorIndication, errorStatus, errorIndex, + varBinds, cbCtx): + cbCtx['errorIndication'] = errorIndication + cbCtx['errorStatus'] = errorStatus + cbCtx['errorIndex'] = errorIndex + cbCtx['varBinds'] = varBinds + + cbCtx = {} + + while True: + if varBinds: + ntforg.sendNotification( + snmpEngine, + authData, + transportTarget, + contextData, + notifyType, + varBinds, + cbFun, cbCtx, + lookupMib=options.get('lookupMib', True) + ) + + snmpEngine.transportDispatcher.runDispatcher() + + errorIndication = cbCtx.get('errorIndication') + errorStatus = cbCtx.get('errorStatus') + errorIndex = cbCtx.get('errorIndex') + varBinds = cbCtx.get('varBinds', []) + else: + errorIndication = errorStatus = errorIndex = None + varBinds = [] + + varBinds = ( yield errorIndication, errorStatus, errorIndex, varBinds ) + + if not varBinds: + break -- cgit v1.2.1