summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2015-09-14 05:20:24 +0000
committerelie <elie>2015-09-14 05:20:24 +0000
commit2f24177c361ba4d9deba2d7378f84aa96111db80 (patch)
tree383c282bfe661bef3eaf16077946124c0039d9ab
parent4397ac4bd10b626aa9355cf04ee0cdb410fe6030 (diff)
downloadpysnmp-2f24177c361ba4d9deba2d7378f84aa96111db80.tar.gz
* synchronous oneliner apps redesigned to offer Python generator-based
API along with a more comprehensive set of accepted parameters. * massively documented (in Sphinx, NumPy style)
-rw-r--r--CHANGES.txt124
-rw-r--r--TODO.txt56
-rw-r--r--examples/v1arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py145
-rw-r--r--examples/v1arch/asyncore/agent/ntforg/trap-v1-multiple-transports.py78
-rw-r--r--examples/v1arch/asyncore/manager/cmdgen/get-v1.py105
-rw-r--r--examples/v1arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py117
-rw-r--r--examples/v1arch/asyncore/manager/cmdgen/get-v2c-udp-broadcast-agent-discovery.py99
-rw-r--r--examples/v1arch/asyncore/manager/cmdgen/getbulk-v2c.py112
-rw-r--r--examples/v1arch/asyncore/manager/cmdgen/getnext-v1.py103
-rw-r--r--examples/v1arch/asyncore/manager/cmdgen/set-v2c.py85
-rw-r--r--examples/v1arch/asyncore/manager/ntfrcv/v1-multiple-transports.py100
-rw-r--r--examples/v3arch/asyncio/agent/cmdrsp/v3-multiple-users.py47
-rw-r--r--examples/v3arch/asyncio/agent/ntforg/inform-v3.py38
-rw-r--r--examples/v3arch/asyncio/agent/ntforg/trap-v1.py46
-rw-r--r--examples/v3arch/asyncio/manager/cmdgen/get-v2c-custom-timeout.py37
-rw-r--r--examples/v3arch/asyncio/manager/cmdgen/get-v2c-over-ipv6.py35
-rw-r--r--examples/v3arch/asyncio/manager/cmdgen/getbulk-v2c.py39
-rw-r--r--examples/v3arch/asyncio/manager/cmdgen/getnext-v2c-from-specific-address.py39
-rw-r--r--examples/v3arch/asyncio/manager/cmdgen/set-v2c.py36
-rw-r--r--examples/v3arch/asyncio/manager/ntfrcv/v2c-multiple-interfaces.py42
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v1-read-and-write-communities.py65
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py82
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-tabular-mib-objects.py126
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-interfaces.py67
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-transports.py68
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib-controller.py77
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib.py77
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-custom-engine-id.py65
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-snmp-engines.py93
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-users.py80
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-observe-request-processing.py90
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/v3-preserve-original-destination-address.py91
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/inform-multiple-protocols.py119
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/inform-v2c.py95
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/inform-v3.py88
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v1-from-specific-address.py82
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v1.py99
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v2c-custom-pdu.py90
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-addresses.py110
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-transports.py106
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v2c-with-objects.py108
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v2c.py95
-rw-r--r--examples/v3arch/asyncore/agent/ntforg/trap-v3.py90
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/get-v1.py76
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/get-v2c-custom-timeout.py79
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py100
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/get-v3-custom-context.py84
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/get-v3-observe-request-processing.py105
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/get-v3.py82
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getbulk-v2c.py82
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getbulk-v3.py85
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getnext-v1.py83
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-from-specific-address.py82
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py94
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getnext-v3-over-ipv6.py82
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/getnext-v3-pull-subtree.py86
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/set-v1.py80
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/set-v2c.py76
-rw-r--r--examples/v3arch/asyncore/manager/cmdgen/set-v3.py78
-rw-r--r--examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-interfaces.py70
-rw-r--r--examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-transports.py71
-rw-r--r--examples/v3arch/asyncore/manager/ntfrcv/v2c-observe-request-processing.py94
-rw-r--r--examples/v3arch/asyncore/manager/ntfrcv/v2c-with-regexp-community-name.py88
-rw-r--r--examples/v3arch/asyncore/manager/ntfrcv/v2c-with-request-details.py69
-rw-r--r--examples/v3arch/asyncore/manager/ntfrcv/v3-multiple-users.py111
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py88
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py60
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py87
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py94
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py87
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3.py87
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py51
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-custom-values.py82
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-default-values.py76
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py60
-rw-r--r--examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py78
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py106
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py106
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py127
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v1.py68
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-custom-timeout-and-retries.py98
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py72
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c.py69
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv-sha-aes128.py57
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv.py39
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-multiple-calls.py47
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-noauth-nopriv.py39
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py74
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-index.py72
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py82
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-custom-security-name.py74
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py67
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-specific-engine-id.py73
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c-limiting-number-of-rows.py47
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c.py56
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-limiting-number-of-packets.py44
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py58
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py61
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py96
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py79
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1.py61
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c-with-mib-resolution.py66
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c.py53
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py58
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py55
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py60
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v1-multiple-values.py83
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py71
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py84
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py83
-rw-r--r--examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py78
-rw-r--r--examples/v3arch/asyncore/proxy/command/udp6-to-udp4-conversion.py142
-rw-r--r--examples/v3arch/asyncore/proxy/command/v2c-to-v1-conversion.py140
-rw-r--r--examples/v3arch/asyncore/proxy/command/v2c-to-v3-conversion.py140
-rw-r--r--examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py143
-rw-r--r--examples/v3arch/trollius/agent/ntforg/inform-v3.py38
-rw-r--r--examples/v3arch/trollius/agent/ntforg/trap-v1.py46
-rw-r--r--examples/v3arch/trollius/manager/cmdgen/get-v1.py36
-rw-r--r--examples/v3arch/trollius/manager/cmdgen/get-v2c-custom-timeout.py36
-rw-r--r--examples/v3arch/trollius/manager/cmdgen/getbulk-v3.py38
-rw-r--r--examples/v3arch/trollius/manager/cmdgen/getnext-v3.py36
-rw-r--r--examples/v3arch/trollius/manager/cmdgen/set-v2c.py36
-rw-r--r--examples/v3arch/twisted/agent/cmdrsp/v1-read-and-write-communities.py36
-rw-r--r--examples/v3arch/twisted/agent/cmdrsp/v2c-custom-scalar-mib-objects.py36
-rw-r--r--examples/v3arch/twisted/agent/cmdrsp/v2c-multiple-interfaces.py36
-rw-r--r--examples/v3arch/twisted/agent/cmdrsp/v3-multiple-users.py43
-rw-r--r--examples/v3arch/twisted/agent/ntforg/inform-v2c.py38
-rw-r--r--examples/v3arch/twisted/agent/ntforg/inform-v3.py34
-rw-r--r--examples/v3arch/twisted/agent/ntforg/trap-v1.py42
-rw-r--r--examples/v3arch/twisted/agent/ntforg/trap-v2c-multiple-targets.py48
-rw-r--r--examples/v3arch/twisted/agent/ntforg/trap-v3.py34
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/get-v1.py31
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/get-v2c-custom-timeout.py32
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/get-v3-custom-context.py36
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/get-v3.py30
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/getbulk-v2c.py34
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/getbulk-v3.py34
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/getnext-v1.py32
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/getnext-v2c-from-specific-address.py34
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/getnext-v3-pull-subtree.py32
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/set-v1.py30
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/set-v2c.py30
-rw-r--r--examples/v3arch/twisted/manager/cmdgen/set-v3.py30
-rw-r--r--examples/v3arch/twisted/manager/ntfrcv/v2c-multiple-interfaces.py39
-rw-r--r--examples/v3arch/twisted/manager/ntfrcv/v3-multiple-users.py44
-rw-r--r--pysnmp/entity/rfc3413/oneliner/auth.py126
-rw-r--r--pysnmp/entity/rfc3413/oneliner/cmdgen.py313
-rw-r--r--pysnmp/entity/rfc3413/oneliner/ctx.py35
-rw-r--r--pysnmp/entity/rfc3413/oneliner/ntforg.py91
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/__init__.py1
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py602
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py1
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py256
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py48
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/ntforg.py126
-rw-r--r--pysnmp/entity/rfc3413/oneliner/target.py81
-rw-r--r--pysnmp/smi/rfc1902.py457
-rw-r--r--setup.py2
158 files changed, 10158 insertions, 2343 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 8a58ef9..7d812f6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,6 @@
-Revision 4.3.0
---------------
+Revision 4.3.0, work in progress
+--------------------------------
- Critical error fixed in key localization procedure for AES192/AES256/3DES
cyphers. Previous versions might never worked properly in this respect.
@@ -9,6 +9,7 @@ Revision 4.3.0
example scripts added. Obsolete libsmi-based scripts removed.
- Major rewrite of native SNMPv3 CommandGenerator and NotificationOriginator
applications towards the following goals:
+
* avoid binding to specific SNMP engine instance to promote single
SNMP app instance using many SNMP engine instances
* support two APIs for working with request data: one operates on the
@@ -23,6 +24,7 @@ Revision 4.3.0
* Synchronous oneliner apps redesigned to offer Python generator-based
API along with a more comprehensive set of accepted parameters.
* keep backward compatibility for all existing major/documented interfaces
+
- Execution Observer facility implemented to give app an inside view
of SNMP engine inner workings. This is thought to be a generic
framework for viewing (and modifying) various internal states
@@ -41,11 +43,13 @@ Revision 4.3.0
among other things, in the context of a transparent SNMP proxy
application. Technically, the following features were brought
into pysnmp with this update:
+
* Sending SNMP packets from a non-local IP address
* Receiving IP packets for non-local IP addresses
* Responding to SNMP requests from exactly the same IP address
the query was sent to. This proves to be useful when listening
on both primary and secondary IP interfaces.
+
- Internal oneliner apps configuration cache moved from respective
apps objects to [a singular] snmpEngine "user context" object.
That would allow for better cache reuse and allow for a single app
@@ -158,8 +162,8 @@ Revision 4.3.0
(but ENOENT) and raise IOError uniformly on any directory/egg access
failure.
-Revision 4.2.5
---------------
+Revision 4.2.5, released 2013-10-02
+-----------------------------------
- License updated to vanilla BSD 2-Clause to ease package use
(http://opensource.org/licenses/BSD-2-Clause).
@@ -281,8 +285,8 @@ Revision 4.2.5
- Missing import added to oneliner auth module.
- Cosmetic changes to v3arch example scripts.
-Revision 4.2.4
---------------
+Revision 4.2.4, released 2013-01-30
+-----------------------------------
- SNMPv3 high-level and native API examples reworked and extended to cover
many use cases.
@@ -310,7 +314,7 @@ Revision 4.2.4
- Catch possible exceptions on pyasn1 encoder invocation.
- VACM modules converted from a function into an object to let it keep
state (caches) in the future.
-- Unnecessary *MibSource explicit initialization calls removed at MibBuilder.
+- Unnecessary MibSource explicit initialization calls removed at MibBuilder.
- Example configuration for Net-SNMP's snmptrapd added.
- Cast additionalVarBinds into ObjectIdentifier type at
NotificationOriginator.sendNotification()
@@ -323,7 +327,7 @@ Revision 4.2.4
a) the notificationType param mandatory b)t e varBinds param really
optional
- Fixes to ContextEngineId/ContextName support at the oneliner API: now
- both items should be passed to request PDU through *Cmd() request
+ both items should be passed to request PDU through Cmd() request
initiation method, the items of authData object should be used only for
LCD configuration.
- Fix to MibVariable handling of the MIB, <empty-symbol> initializers.
@@ -347,8 +351,8 @@ Revision 4.2.4
SNMP working again. Wrong method (instumClone) was probed at terminal
MIB nodes values instead of the right one (setValue).
-Revision 4.2.3
---------------
+Revision 4.2.3, released 2012-09-06
+-----------------------------------
- SECURITY FIX: USM subsystem did not verify securityLevel of a request
to an authoritative SNMP engine against auth/priv protocols
@@ -464,8 +468,8 @@ Revision 4.2.3
- Typo fix to snmpInASNParseErrs MIB instance object.
- Typo fix to errind.EngineIdMismatch class and its instance.
-Revision 4.2.2
---------------
+Revision 4.2.2, released 2012-04-21
+-----------------------------------
- Oneliner CommandGenerator can now limit the number of SNMP table
rows returned by nextCmd()/bulkCmd() methods.
@@ -526,20 +530,21 @@ Revision 4.2.2
params.
- Fix to libsmi2pysnmp to support inheritance of MIB types.
-Revision 4.2.1
---------------
+Revision 4.2.1, released 2011-11-07
+-----------------------------------
- Support string OIDs at one-liner API.
- Code quality of libsmi2pysnmp tool improved, MIBs re-built.
- SNMP-PROXY-MIB & SNMP-USER-BASED-SM-3DES-MIB added
- v1arch bulkgen.py example added
- Major overhawl for Python 2.4 -- 3.2 compatibility:
+
+ get rid of old-style types
+ drop string module usage
+ switch to rich comparation
+ drop explicit long integer type use
+ map()/filter() replaced with list comprehension
- + apply() replaced with */**args
+ + apply() replaced with var-args
+ dictionary operations made 2K/3K compatible
+ division operator made 2K/3K compatible
+ sorting function now operates on key
@@ -548,18 +553,18 @@ Revision 4.2.1
+ tuple function arguments resolved to scalars to become py3k compatible
+ BER octetstream is now of type bytes (Py3k) or still string (Py2k)
-Revision 4.1.16d
-----------------
+Revision 4.1.16d, released 2011-09-22
+-------------------------------------
- Fix to SNMPv1 Trap PDU agentAddress setter shortcut method.
-Revision 4.1.16c
-----------------
+Revision 4.1.16c, released 2011-08-14
+-------------------------------------
- Missing module import fixed in privacy subsystem
-Revision 4.1.16b
-----------------
+Revision 4.1.16b, released 2011-08-13
+-------------------------------------
- Oneliner CommandGenerator can now optionally ignore non-increasing OIDs.
- Default CommandResponder now skips non-compliant (Counter64) values
@@ -568,8 +573,8 @@ Revision 4.1.16b
- Fix to Twisted reactor shutdown condition.
- Fix to distutils dependencies syntax.
-Revision 4.1.16a
-----------------
+Revision 4.1.16a, released 2011-03-17
+-------------------------------------
- Extended Security Options (3DESEDE, AES192, AES256) privacy
protocols implemented.
@@ -586,6 +591,7 @@ Revision 4.1.16a
- MsgAndPduDsp expectResponse parameters passing reworked.
- GetNext/GetBulk response processing logic moved to getNextVarBinds()
- Changes towards performance improvement:
+
+ all dict.has_key() & dict.get() invocations replaced with modern syntax
(this breaks compatibility with Python 2.1 and older).
+ introduce the MibInstrumControlle.readVarsFast() method (which skips
@@ -602,8 +608,8 @@ Revision 4.1.16a
+ cache MIB columnar objects instance ID <-> symbolic index representation
mapping
-Revision 4.1.15a
-----------------
+Revision 4.1.15a, released 2010-12-13
+-------------------------------------
- SNMP Proxy example added.
- End-of-MIB condition detection reworked what caused backward
@@ -662,8 +668,8 @@ Revision 4.1.15a
- Fix to oneliner GETBULK table collection code to make it stripping
uneven rows off table tail.
-Revision 4.1.14a
-----------------
+Revision 4.1.14a, released 2010-07-15
+-------------------------------------
- Fix to maxSizeResponseScopedPDU calculation at USM security module: now
more precise and robust against screwed values on input.
@@ -699,8 +705,8 @@ Revision 4.1.14a
now send up to two packets, not just one as it used to be.
- Debugging printout now escapes non-printable characters.
-Revision 4.1.13a
-----------------
+Revision 4.1.13a, released 2010-02-09
+-------------------------------------
- UDP over IPv6 transport implemented.
- Fix to MIB tree walking code that used to fail on table columns where
@@ -708,8 +714,8 @@ Revision 4.1.13a
- SNMPv1/v2c snmpCommunityTransportTag-based imcoming message filtering
implemented (rfc2576).
-Revision 4.1.12a
-----------------
+Revision 4.1.12a, released 2009-12-03
+-------------------------------------
- API versioning retired (pysnmp.v4 -> pysnmp).
- MIB loading mechanics re-designed to allow ZIP import.
@@ -721,8 +727,8 @@ Revision 4.1.12a
code reworked.
- Fix to sysUpTime OID at SNMPv2 TRAP PDU.
-Revision 4.1.11a
-----------------
+Revision 4.1.11a, released 2009-08-21
+-------------------------------------
- Twisted integration implemented.
- Attempt to use hashlib whenever available.
@@ -751,8 +757,8 @@ Revision 4.1.11a
- Minor usability improvements to tools/build-pysnmp-mib.
- Made MIB objects unexport feature operational.
-Revision 4.1.10a
-----------------
+Revision 4.1.10a, released 2008-05-25
+-------------------------------------
- Internal MIB indexing method __indexMib() unmangled to facilitate
setting up mutex there for sharing MIB stuff between threads.
@@ -773,8 +779,8 @@ Revision 4.1.10a
request IDs and handlers.
- Built-in MIBs re-generated to include text fields.
-Revision 4.1.9a
----------------
+Revision 4.1.9a, released 2007-11-28
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- At onliner CommandGenerator, close transport on destruction to
@@ -801,8 +807,8 @@ Revision 4.1.9a
This might fix a significant memory leak.
- Typo fix to rfc3411 confirmed class PDU members.
-Revision 4.1.8a
----------------
+Revision 4.1.8a, released 2007-08-14
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- SMI/dispatcher timeout convertion multiplier is actually 100 (1/100 sec)
@@ -845,8 +851,8 @@ Revision 4.1.8a
- Fix to errorIndex generation at CommandResponder application, the value
should be a one-based.
-Revision 4.1.7a
----------------
+Revision 4.1.7a, released 2007-02-19
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- Low-level debugging facility implemented.
@@ -909,8 +915,8 @@ Revision 4.1.7a
#1537600, #1537659, #1548208, #1560939, #1563715, #1575697, #1599220,
#1615077, #1615365, #1616579).
-Revision 4.1.6a
----------------
+Revision 4.1.6a, released 2006-05-25
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- pysnmpUsmSecretAuthKey and pysnmpUsmSecretPrivKey length increased
@@ -937,8 +943,8 @@ Revision 4.1.6a
- Documentation improved
- Minor fixes towards Python 1.5 compatibility
-Revision 4.1.5a
----------------
+Revision 4.1.5a, released 2005-11-04
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- Multi-lingual SNMP Trap/Inform Applications completed; examples added
@@ -948,8 +954,8 @@ Revision 4.1.5a
- Minor, though backward incompatible, changes to one-liner API
- Many bugfixes
-Revision 4.1.4a
----------------
+Revision 4.1.4a, released 2005-08-16
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- SHA-based authentication fixed and privacy implemented
@@ -957,8 +963,8 @@ Revision 4.1.4a
authProtocol and privProtocol parameters in a backward incompatible
manner.
-Revision 4.1.3a
----------------
+Revision 4.1.3a, released 2005-07-28
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- rfc3413 applications API changes (related to callback function
@@ -967,8 +973,8 @@ Revision 4.1.3a
for better control of dispatcher's execution.
- Many minor fixes.
-Revision 4.1.2a
----------------
+Revision 4.1.2a, released 2005-07-12
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- Top-level application classes renamed into longer, self descripting names
@@ -977,26 +983,26 @@ Revision 4.1.2a
stand-alone SnmpContext for application registration.
- Many minor fixes (inspired by testing on WinXP)
-Revision 4.1.1a
----------------
+Revision 4.1.1a, released 2005-06-29
+------------------------------------
- UNSTABLE ALPHA RELEASE.
- SNMPv3 code first published
- SNMP engine and applications implemented on library level
- Major re-design towards SNMPv3-style API.
-Release 4.0.2a
---------------
+Revision 4.0.2a, released 2005-03-01
+------------------------------------
- Adopted to slightly changed asyncore API (as shipped with python 2,4)
-Release 4.0.1a
---------------
+Revision 4.0.1a, released 2004-11-18
+------------------------------------
- Minor bug/typo fixes, mostly in example/ scripts.
-Release 4.0.0a
---------------
+Revision 4.0.0a, released 2004-11-15
+------------------------------------
- UNSTABLE EARLY ALPHA RELEASE.
- Major re-design and re-implementation.
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..ae8ded1
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,56 @@
+Sparse notes on major existing problems/plans
+
+* SMI issues remained include:
+
+ 1) multiple OID registration should be posible for
+ customizing Managed Objects classes
+ 2) in MIBVIEW object model: MIB module name, MIB object
+ name and object instance should be clearly separated.
+ Dedicated, simple API for table cells mangling should be
+ provided.
+
+* Walking over VACM shadowed OIDs is painfully slow
+
+* Notification filtering (RFC3413) not implemented.
+
+* MsgAndPduDispatcher should use TransportDispatcher jobs interface
+ to handle SNMPv3 handshake
+
+* Implement 'oneliner' API for v1arch, possibly compatible with v3arch API
+
+* Implement prettyIn value format parser at TC
+
+* Disallow SNMP access to USM objects
+
+* Maybe MibInstrumentationController should be async what
+ implies callback function interface.
+
+* Re-work ACL to get rid of linear search there
+
+* Implement partial context name match at isAccessAllowed()
+
+* Sort out whether pyasn1 objects should probably have either clone() or
+ subtype() methods.
+
+* Review PDU components coercion code at proxy/rfc2576
+
+* TextualConvention subclassing order now depends upon DisplayHint
+ clause presense in MIB definition (for useful prettyIn/Out()). Maybe
+ this should be re-worked.
+
+* exclude SNMP-COMMUNITY-MIB from view for better security
+
+* re-design something to get rid of an ugly hack coercing MIB values into
+ SNMP message header as it has incompatible constraints set
+
+* Implement OID prefix to MIB module mapping then dynamic MIB modules
+ loading on OID to MIB symbol resolution
+
+* Implement TCP transport support
+
+* Rework UNIX sockets transport to make it STREAM-type.
+
+* The get-first/get-last operations of pysnmp.smi.rfc1902.ObjectIdentity()
+ may need a means to deal only with specific node types.
+
+* redesign proto.errind.ErrorIndication
diff --git a/examples/v1arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py b/examples/v1arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
new file mode 100644
index 0000000..5119a15
--- /dev/null
+++ b/examples/v1arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
@@ -0,0 +1,145 @@
+"""
+Implementing scalar MIB objects
++++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/GETNEXT queries with the following options:
+
+* SNMPv1 or SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:161
+* over IPv6/UDP, listening at [::1]:161
+* serving two Managed Objects Instances (sysDescr.0 and sysUptime.0)
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
+| $ snmpwalk -v2c -c public udp6:[::1] .1.3.6
+
+The Command Receiver below uses two distinct transports for communication
+with Command Generators - UDP over IPv4 and UDP over IPv6.
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp, udp6, unix
+from pyasn1.codec.ber import encoder, decoder
+from pysnmp.proto import api
+import time, bisect
+
+class SysDescr:
+ name = (1,3,6,1,2,1,1,1,0)
+ def __eq__(self, other): return self.name == other
+ def __ne__(self, other): return self.name != other
+ def __lt__(self, other): return self.name < other
+ def __le__(self, other): return self.name <= other
+ def __gt__(self, other): return self.name > other
+ def __ge__(self, other): return self.name >= other
+ def __call__(self, protoVer):
+ return api.protoModules[protoVer].OctetString(
+ 'PySNMP example command responder'
+ )
+
+class Uptime:
+ name = (1,3,6,1,2,1,1,3,0)
+ birthday = time.time()
+ def __eq__(self, other): return self.name == other
+ def __ne__(self, other): return self.name != other
+ def __lt__(self, other): return self.name < other
+ def __le__(self, other): return self.name <= other
+ def __gt__(self, other): return self.name > other
+ def __ge__(self, other): return self.name >= other
+ def __call__(self, protoVer):
+ return api.protoModules[protoVer].TimeTicks(
+ (time.time()-self.birthday)*100
+ )
+
+mibInstr = (
+ SysDescr(), Uptime() # sorted by object name
+ )
+
+mibInstrIdx = {}
+for mibVar in mibInstr:
+ mibInstrIdx[mibVar.name] = mibVar
+
+def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
+ while wholeMsg:
+ msgVer = api.decodeMessageVersion(wholeMsg)
+ if msgVer in api.protoModules:
+ pMod = api.protoModules[msgVer]
+ else:
+ print('Unsupported SNMP version %s' % msgVer)
+ return
+ reqMsg, wholeMsg = decoder.decode(
+ wholeMsg, asn1Spec=pMod.Message(),
+ )
+ rspMsg = pMod.apiMessage.getResponse(reqMsg)
+ rspPDU = pMod.apiMessage.getPDU(rspMsg)
+ reqPDU = pMod.apiMessage.getPDU(reqMsg)
+ varBinds = []; pendingErrors = []
+ errorIndex = 0
+ # GETNEXT PDU
+ if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()):
+ # Produce response var-binds
+ for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
+ errorIndex = errorIndex + 1
+ # Search next OID to report
+ nextIdx = bisect.bisect(mibInstr, oid)
+ if nextIdx == len(mibInstr):
+ # Out of MIB
+ varBinds.append((oid, val))
+ pendingErrors.append(
+ (pMod.apiPDU.setEndOfMibError, errorIndex)
+ )
+ else:
+ # Report value if OID is found
+ varBinds.append(
+ (mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer))
+ )
+ elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()):
+ for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
+ if oid in mibInstrIdx:
+ varBinds.append((oid, mibInstrIdx[oid](msgVer)))
+ else:
+ # No such instance
+ varBinds.append((oid, val))
+ pendingErrors.append(
+ (pMod.apiPDU.setNoSuchInstanceError, errorIndex)
+ )
+ break
+ else:
+ # Report unsupported request type
+ pMod.apiPDU.setErrorStatus(rspPDU, 'genErr')
+ pMod.apiPDU.setVarBinds(rspPDU, varBinds)
+ # Commit possible error indices to response PDU
+ for f, i in pendingErrors:
+ f(rspPDU, i)
+ transportDispatcher.sendMessage(
+ encoder.encode(rspMsg), transportDomain, transportAddress
+ )
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+transportDispatcher.registerRecvCbFun(cbFun)
+
+# UDP/IPv4
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161))
+)
+
+# UDP/IPv6
+transportDispatcher.registerTransport(
+ udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 161))
+)
+
+## Local domain socket
+#transportDispatcher.registerTransport(
+# unix.domainName, unix.UnixSocketTransport().openServerMode('/tmp/snmp-agent')
+#)
+
+transportDispatcher.jobStarted(1)
+
+try:
+ # Dispatcher will never finish as job#1 never reaches zero
+ transportDispatcher.runDispatcher()
+except:
+ transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v1arch/asyncore/agent/ntforg/trap-v1-multiple-transports.py b/examples/v1arch/asyncore/agent/ntforg/trap-v1-multiple-transports.py
new file mode 100644
index 0000000..e0be25a
--- /dev/null
+++ b/examples/v1arch/asyncore/agent/ntforg/trap-v1-multiple-transports.py
@@ -0,0 +1,78 @@
+"""
+TRAP over multiple transports
++++++++++++++++++++++++++++++
+
+The following script sends two SNMP TRAP notification using the
+following options:
+
+* with SNMPv1
+* with community name 'public'
+* over IPv4/UDP and IPv6/UDP
+* send TRAP notification
+* to a Manager at 127.0.0.1:162 and [::1]
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+* with default Uptime value
+* with default Agent Address with '127.0.0.1'
+* overriding Enterprise OID with 1.3.6.1.4.1.20408.4.1.1.2
+
+The following Net-SNMP commands will produce similar SNMP notification:
+
+| $ snmptrap -v1 -c public udp:127.0.0.1 1.3.6.1.4.1.20408.4.1.1.2 127.0.0.1 1 0 12345
+| $ snmptrap -v1 -c public udp6:[::1] 1.3.6.1.4.1.20408.4.1.1.2 127.0.0.1 1 0 12345
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp, udp6, unix
+from pyasn1.codec.ber import encoder
+from pysnmp.proto import api
+
+# Protocol version to use
+pMod = api.protoModules[api.protoVersion1]
+#pMod = api.protoModules[api.protoVersion2c]
+
+# Build PDU
+trapPDU = pMod.TrapPDU()
+pMod.apiTrapPDU.setDefaults(trapPDU)
+
+# Traps have quite different semantics across proto versions
+if pMod == api.protoModules[api.protoVersion1]:
+ pMod.apiTrapPDU.setEnterprise(trapPDU, (1,3,6,1,1,2,3,4,1))
+ pMod.apiTrapPDU.setGenericTrap(trapPDU, 'coldStart')
+
+# Build message
+trapMsg = pMod.Message()
+pMod.apiMessage.setDefaults(trapMsg)
+pMod.apiMessage.setCommunity(trapMsg, 'public')
+pMod.apiMessage.setPDU(trapMsg, trapPDU)
+
+transportDispatcher = AsyncoreDispatcher()
+
+# UDP/IPv4
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openClientMode()
+ )
+transportDispatcher.sendMessage(
+ encoder.encode(trapMsg), udp.domainName, ('localhost', 162)
+ )
+
+# UDP/IPv6
+transportDispatcher.registerTransport(
+ udp6.domainName, udp6.Udp6SocketTransport().openClientMode()
+)
+transportDispatcher.sendMessage(
+ encoder.encode(trapMsg), udp6.domainName, ('::1', 162)
+)
+
+## Local domain socket
+#transportDispatcher.registerTransport(
+# unix.domainName, unix.UnixSocketTransport().openClientMode()
+#)
+#transportDispatcher.sendMessage(
+# encoder.encode(trapMsg), unix.domainName, '/tmp/snmp-manager'
+#)
+
+# Dispatcher will finish as all scheduled messages are sent
+transportDispatcher.runDispatcher()
+
+transportDispatcher.closeDispatcher()
diff --git a/examples/v1arch/asyncore/manager/cmdgen/get-v1.py b/examples/v1arch/asyncore/manager/cmdgen/get-v1.py
new file mode 100644
index 0000000..e7fa029
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/cmdgen/get-v1.py
@@ -0,0 +1,105 @@
+"""
+Fetch scalar MIB variables (SNMPv1)
++++++++++++++++++++++++++++++++++++
+
+Perform SNMP GET operation with the following options:
+
+* with SNMPv1, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0 1.3.6.1.2.1.1.3.0
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp, udp6, unix
+from pyasn1.codec.ber import encoder, decoder
+from pysnmp.proto import api
+from time import time
+
+# Protocol version to use
+pMod = api.protoModules[api.protoVersion1]
+#pMod = api.protoModules[api.protoVersion2c]
+
+# Build PDU
+reqPDU = pMod.GetRequestPDU()
+pMod.apiPDU.setDefaults(reqPDU)
+pMod.apiPDU.setVarBinds(
+ reqPDU, ( ('1.3.6.1.2.1.1.1.0', pMod.Null('')),
+ ('1.3.6.1.2.1.1.3.0', pMod.Null('')) )
+ )
+
+# Build message
+reqMsg = pMod.Message()
+pMod.apiMessage.setDefaults(reqMsg)
+pMod.apiMessage.setCommunity(reqMsg, 'public')
+pMod.apiMessage.setPDU(reqMsg, reqPDU)
+
+startedAt = time()
+
+def cbTimerFun(timeNow):
+ if timeNow - startedAt > 3:
+ raise Exception("Request timed out")
+
+def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
+ wholeMsg, reqPDU=reqPDU):
+ while wholeMsg:
+ rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
+ rspPDU = pMod.apiMessage.getPDU(rspMsg)
+ # Match response to request
+ if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
+ # Check for SNMP errors reported
+ errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
+ if errorStatus:
+ print(errorStatus.prettyPrint())
+ else:
+ for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ transportDispatcher.jobFinished(1)
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbRecvFun)
+transportDispatcher.registerTimerCbFun(cbTimerFun)
+
+# UDP/IPv4
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openClientMode()
+)
+
+# Pass message to dispatcher
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp.domainName, ('demo.snmplabs.com', 161)
+)
+transportDispatcher.jobStarted(1)
+
+## UDP/IPv6 (second copy of the same PDU will be sent)
+transportDispatcher.registerTransport(
+ udp6.domainName, udp6.Udp6SocketTransport().openClientMode()
+)
+
+# Pass message to dispatcher
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp6.domainName, ('::1', 161)
+)
+transportDispatcher.jobStarted(1)
+
+## Local domain socket
+#transportDispatcher.registerTransport(
+# unix.domainName, unix.UnixSocketTransport().openClientMode()
+#)
+#
+# Pass message to dispatcher
+#transportDispatcher.sendMessage(
+# encoder.encode(reqMsg), unix.domainName, '/tmp/snmp-agent'
+#)
+#transportDispatcher.jobStarted(1)
+
+# Dispatcher will finish as job#1 counter reaches zero
+transportDispatcher.runDispatcher()
+
+transportDispatcher.closeDispatcher()
diff --git a/examples/v1arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py b/examples/v1arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py
new file mode 100644
index 0000000..16009ab
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py
@@ -0,0 +1,117 @@
+"""
+Spoof IPv4 source address
++++++++++++++++++++++++++
+
+Send SNMP GET request from a non-local IP address:
+
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* from a non-local, spoofed IP 1.2.3.4 (root and Python 3.3+ required)
+* for OIDs in string form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0 1.3.6.1.2.1.1.3.0
+
+But unlike the above command, this script issues SNMP request from a
+non-default, non-local IP address.
+
+It is indeed possible to originate SNMP traffic from any valid local IP
+addresses. It could be a secondary IP interface, for instance. Superuser
+privileges are only required to send spoofed packets. Alternatively,
+sending from local interface could also be achieved by binding to
+it (via openClientMode() parameter).
+
+Agent would respond to the IP address you used as a source. So this script
+could only get a response if that source address is somehow routed to the
+host this script is running on. Otherwise it just times out.
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.proto import api
+from pyasn1.codec.ber import encoder, decoder
+from time import time
+
+# Send request message to this address
+transportAddress = udp.UdpTransportAddress(('195.218.195.228', 161))
+
+# Send request message from this non-local (!) IP address
+transportAddress.setLocalAddress(('1.2.3.4', 0))
+
+# Protocol version to use
+#pMod = api.protoModules[api.protoVersion1]
+pMod = api.protoModules[api.protoVersion2c]
+
+# Build PDU
+reqPDU = pMod.GetRequestPDU()
+pMod.apiPDU.setDefaults(reqPDU)
+pMod.apiPDU.setVarBinds(
+ reqPDU, ( ('1.3.6.1.2.1.1.1.0', pMod.Null('')),
+ ('1.3.6.1.2.1.1.3.0', pMod.Null('')) )
+ )
+
+# Build message
+reqMsg = pMod.Message()
+pMod.apiMessage.setDefaults(reqMsg)
+pMod.apiMessage.setCommunity(reqMsg, 'public')
+pMod.apiMessage.setPDU(reqMsg, reqPDU)
+
+startedAt = time()
+
+class StopWaiting(Exception): pass
+
+def cbTimerFun(timeNow):
+ if timeNow - startedAt > 3:
+ raise StopWaiting()
+
+def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
+ wholeMsg, reqPDU=reqPDU):
+ while wholeMsg:
+ rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
+ rspPDU = pMod.apiMessage.getPDU(rspMsg)
+ # Match response to request
+ if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
+ # Check for SNMP errors reported
+ errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
+ if errorStatus:
+ print(errorStatus.prettyPrint())
+ else:
+ for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ transportDispatcher.jobFinished(1)
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbRecvFun)
+transportDispatcher.registerTimerCbFun(cbTimerFun)
+
+# Initialize UDP/IPv4 transport
+udpSocketTransport = udp.UdpSocketTransport().openClientMode()
+
+# Use sendmsg()/recvmsg() for socket communication (required for
+# IP source spoofing functionality)
+udpSocketTransport.enablePktInfo()
+
+# Enable IP source spoofing (requires root privileges)
+udpSocketTransport.enableTransparent()
+
+transportDispatcher.registerTransport(udp.domainName, udpSocketTransport)
+
+# Pass message to dispatcher
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp.domainName, transportAddress
+)
+
+# We might never receive any response as we sent request with fake source IP
+transportDispatcher.jobStarted(1)
+
+# Dispatcher will finish as all jobs counter reaches zero
+try:
+ transportDispatcher.runDispatcher()
+except StopWaiting:
+ transportDispatcher.closeDispatcher()
+else:
+ raise
diff --git a/examples/v1arch/asyncore/manager/cmdgen/get-v2c-udp-broadcast-agent-discovery.py b/examples/v1arch/asyncore/manager/cmdgen/get-v2c-udp-broadcast-agent-discovery.py
new file mode 100644
index 0000000..cd8c3c9
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/cmdgen/get-v2c-udp-broadcast-agent-discovery.py
@@ -0,0 +1,99 @@
+"""
+Broadcast SNMP message (IPv4)
++++++++++++++++++++++++++++++
+
+Send SNMP GET request to broadcast address and wait for respons(es):
+
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to all Agents via broadcast address 255.255.255.255:161
+* for OIDs in tuple form
+
+Here we send out a single SNMP request and wait for potentially many SNMP
+responses from multiple SNMP Agents listening in local broadcast domain.
+Since we can't predict the exact number of Agents responding, this script
+just waits for arbitrary time for collecting all responses. This technology
+is also known as SNMP-based discovery.
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU 255.255.255.255 1.3.6.1.2.1.1.1.0 1.3.6.1.2.1.1.3.0
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp
+from pyasn1.codec.ber import encoder, decoder
+from pysnmp.proto import api
+from time import time
+
+# Broadcast manager settings
+maxWaitForResponses = 5
+maxNumberResponses = 10
+
+# Protocol version to use
+#pMod = api.protoModules[api.protoVersion1]
+pMod = api.protoModules[api.protoVersion2c]
+
+# Build PDU
+reqPDU = pMod.GetRequestPDU()
+pMod.apiPDU.setDefaults(reqPDU)
+pMod.apiPDU.setVarBinds(
+ reqPDU, ( ('1.3.6.1.2.1.1.1.0', pMod.Null('')),
+ ('1.3.6.1.2.1.1.3.0', pMod.Null('')) )
+ )
+
+# Build message
+reqMsg = pMod.Message()
+pMod.apiMessage.setDefaults(reqMsg)
+pMod.apiMessage.setCommunity(reqMsg, 'public')
+pMod.apiMessage.setPDU(reqMsg, reqPDU)
+
+startedAt = time()
+
+class StopWaiting(Exception): pass
+
+def cbTimerFun(timeNow):
+ if timeNow - startedAt > maxWaitForResponses:
+ raise StopWaiting()
+
+def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
+ wholeMsg, reqPDU=reqPDU):
+ while wholeMsg:
+ rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
+ rspPDU = pMod.apiMessage.getPDU(rspMsg)
+ # Match response to request
+ if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
+ # Check for SNMP errors reported
+ errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
+ if errorStatus:
+ print(errorStatus.prettyPrint())
+ else:
+ for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ transportDispatcher.jobFinished(1)
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbRecvFun)
+transportDispatcher.registerTimerCbFun(cbTimerFun)
+
+# UDP/IPv4
+udpSocketTransport = udp.UdpSocketTransport().openClientMode().enableBroadcast()
+transportDispatcher.registerTransport(udp.domainName, udpSocketTransport)
+
+# Pass message to dispatcher
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp.domainName, ('255.255.255.255', 161)
+)
+
+# wait for a maximum of 10 responses or time out
+transportDispatcher.jobStarted(1, maxNumberResponses)
+
+# Dispatcher will finish as all jobs counter reaches zero
+try:
+ transportDispatcher.runDispatcher()
+except StopWaiting:
+ transportDispatcher.closeDispatcher()
+else:
+ raise
diff --git a/examples/v1arch/asyncore/manager/cmdgen/getbulk-v2c.py b/examples/v1arch/asyncore/manager/cmdgen/getbulk-v2c.py
new file mode 100644
index 0000000..8ba9af6
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/cmdgen/getbulk-v2c.py
@@ -0,0 +1,112 @@
+"""
+Bulk walk Agent MIB (SNMPv2c)
++++++++++++++++++++++++++++++
+
+Perform SNMP GETBULK operation with the following options:
+
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OID in tuple form
+* with non-repeaters=0 and max-repeaters=25
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v2c -c public -ObentU -Cn0 -Cr25 195.218.195.228 1.3.6
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp
+from pyasn1.codec.ber import encoder, decoder
+from pysnmp.proto.api import v2c
+from time import time
+
+# SNMP table header
+headVars = [ v2c.ObjectIdentifier((1,3,6)) ]
+
+# Build PDU
+reqPDU = v2c.GetBulkRequestPDU()
+v2c.apiBulkPDU.setDefaults(reqPDU)
+v2c.apiBulkPDU.setNonRepeaters(reqPDU, 0)
+v2c.apiBulkPDU.setMaxRepetitions(reqPDU, 25)
+v2c.apiBulkPDU.setVarBinds(reqPDU, [ (x, v2c.null) for x in headVars ])
+
+# Build message
+reqMsg = v2c.Message()
+v2c.apiMessage.setDefaults(reqMsg)
+v2c.apiMessage.setCommunity(reqMsg, 'public')
+v2c.apiMessage.setPDU(reqMsg, reqPDU)
+
+startedAt = time()
+
+def cbTimerFun(timeNow):
+ if timeNow - startedAt > 3:
+ raise Exception("Request timed out")
+
+def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
+ wholeMsg, reqPDU=reqPDU, headVars=headVars):
+ while wholeMsg:
+ rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message())
+
+ rspPDU = v2c.apiMessage.getPDU(rspMsg)
+
+ # Match response to request
+ if v2c.apiBulkPDU.getRequestID(reqPDU)==v2c.apiBulkPDU.getRequestID(rspPDU):
+ # Format var-binds table
+ varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU)
+
+ # Check for SNMP errors reported
+ errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU)
+ if errorStatus and errorStatus != 2:
+ errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU)
+ print('%s at %s' % (errorStatus.prettyPrint(),
+ errorIndex and varBindTable[int(errorIndex)-1] or '?'))
+ transportDispatcher.jobFinished(1)
+ break
+
+ # Report SNMP table
+ for tableRow in varBindTable:
+ for name, val in tableRow:
+ print('from: %s, %s = %s' % (
+ transportAddress, name.prettyPrint(), val.prettyPrint()
+ )
+ )
+
+ # Stop on EOM
+ for oid, val in varBindTable[-1]:
+ if not isinstance(val, v2c.Null):
+ break
+ else:
+ transportDispatcher.jobFinished(1)
+
+ # Generate request for next row
+ v2c.apiBulkPDU.setVarBinds(
+ reqPDU, [ (x, v2c.null) for x,y in varBindTable[-1] ]
+ )
+ v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID())
+ transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), transportDomain, transportAddress
+ )
+ global startedAt
+ if time() - startedAt > 3:
+ raise Exception('Request timed out')
+ startedAt = time()
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbRecvFun)
+transportDispatcher.registerTimerCbFun(cbTimerFun)
+
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openClientMode()
+)
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp.domainName, ('demo.snmplabs.com', 161)
+)
+transportDispatcher.jobStarted(1)
+
+# Dispatcher will finish as job#1 counter reaches zero
+transportDispatcher.runDispatcher()
+
+transportDispatcher.closeDispatcher()
diff --git a/examples/v1arch/asyncore/manager/cmdgen/getnext-v1.py b/examples/v1arch/asyncore/manager/cmdgen/getnext-v1.py
new file mode 100644
index 0000000..b3e16f1
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/cmdgen/getnext-v1.py
@@ -0,0 +1,103 @@
+"""
+Walk Agent MIB (SNMPv1)
++++++++++++++++++++++++
+
+Perform SNMP GETNEXT operation with the following options:
+
+* with SNMPv1, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v1 -c public -ObentU 195.218.195.228 1.3.6
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp
+from pyasn1.codec.ber import encoder, decoder
+from pysnmp.proto import api
+from time import time
+
+# Protocol version to use
+pMod = api.protoModules[api.protoVersion1]
+#pMod = api.protoModules[api.protoVersion2c]
+
+# SNMP table header
+headVars = [ pMod.ObjectIdentifier((1,3,6)) ]
+
+# Build PDU
+reqPDU = pMod.GetNextRequestPDU()
+pMod.apiPDU.setDefaults(reqPDU)
+pMod.apiPDU.setVarBinds(reqPDU, [ (x, pMod.null) for x in headVars ])
+
+# Build message
+reqMsg = pMod.Message()
+pMod.apiMessage.setDefaults(reqMsg)
+pMod.apiMessage.setCommunity(reqMsg, 'public')
+pMod.apiMessage.setPDU(reqMsg, reqPDU)
+
+startedAt = time()
+
+def cbTimerFun(timeNow):
+ if timeNow - startedAt > 3:
+ raise Exception("Request timed out")
+
+def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
+ wholeMsg, reqPDU=reqPDU, headVars=headVars):
+ while wholeMsg:
+ rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
+ rspPDU = pMod.apiMessage.getPDU(rspMsg)
+ # Match response to request
+ if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
+ # Check for SNMP errors reported
+ errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
+ if errorStatus and errorStatus != 2:
+ raise Exception(errorStatus)
+ # Format var-binds table
+ varBindTable = pMod.apiPDU.getVarBindTable(reqPDU, rspPDU)
+ # Report SNMP table
+ for tableRow in varBindTable:
+ for name, val in tableRow:
+ print('from: %s, %s = %s' % (
+ transportAddress, name.prettyPrint(), val.prettyPrint()
+ )
+ )
+ # Stop on EOM
+ for oid, val in varBindTable[-1]:
+ if not isinstance(val, pMod.Null):
+ break
+ else:
+ transportDispatcher.jobFinished(1)
+
+ # Generate request for next row
+ pMod.apiPDU.setVarBinds(
+ reqPDU, [ (x, pMod.null) for x,y in varBindTable[-1] ]
+ )
+ pMod.apiPDU.setRequestID(reqPDU, pMod.getNextRequestID())
+ transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), transportDomain, transportAddress
+ )
+ global startedAt
+ if time() - startedAt > 3:
+ raise Exception('Request timed out')
+ startedAt = time()
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbRecvFun)
+transportDispatcher.registerTimerCbFun(cbTimerFun)
+
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openClientMode()
+)
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp.domainName, ('demo.snmplabs.com', 161)
+)
+transportDispatcher.jobStarted(1)
+
+transportDispatcher.runDispatcher()
+
+transportDispatcher.closeDispatcher()
diff --git a/examples/v1arch/asyncore/manager/cmdgen/set-v2c.py b/examples/v1arch/asyncore/manager/cmdgen/set-v2c.py
new file mode 100644
index 0000000..a30bebb
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/cmdgen/set-v2c.py
@@ -0,0 +1,85 @@
+"""
+SET string and integer scalars (SNMPv2c)
+++++++++++++++++++++++++++++++++++++++++
+
+Perform SNMP SET operation with the following options:
+
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in string form and values in form of pyasn1 objects
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.9.1.3.1 s 'New description' 1.3.6.1.2.1.1.9.1.4.1 t 12
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp
+from pyasn1.codec.ber import encoder, decoder
+from pysnmp.proto import api
+from time import time
+
+# Protocol version to use
+#pMod = api.protoModules[api.protoVersion1]
+pMod = api.protoModules[api.protoVersion2c]
+
+# Build PDU
+reqPDU = pMod.SetRequestPDU()
+pMod.apiPDU.setDefaults(reqPDU)
+pMod.apiPDU.setVarBinds(
+ reqPDU,
+ # A list of Var-Binds to SET
+ ( ('1.3.6.1.2.1.1.9.1.3.1', pMod.OctetString('New system description')),
+ ('1.3.6.1.2.1.1.9.1.4.1', pMod.TimeTicks(12)) )
+ )
+
+# Build message
+reqMsg = pMod.Message()
+pMod.apiMessage.setDefaults(reqMsg)
+pMod.apiMessage.setCommunity(reqMsg, 'public')
+pMod.apiMessage.setPDU(reqMsg, reqPDU)
+
+startedAt = time()
+
+def cbTimerFun(timeNow):
+ if timeNow - startedAt > 3:
+ raise Exception("Request timed out")
+
+def cbRecvFun(transportDispatcher, transportDomain, transportAddress,
+ wholeMsg, reqPDU=reqPDU):
+ while wholeMsg:
+ rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=pMod.Message())
+ rspPDU = pMod.apiMessage.getPDU(rspMsg)
+ # Match response to request
+ if pMod.apiPDU.getRequestID(reqPDU)==pMod.apiPDU.getRequestID(rspPDU):
+ # Check for SNMP errors reported
+ errorStatus = pMod.apiPDU.getErrorStatus(rspPDU)
+ if errorStatus:
+ print(errorStatus.prettyPrint())
+ else:
+ for oid, val in pMod.apiPDU.getVarBinds(rspPDU):
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ transportDispatcher.jobFinished(1)
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbRecvFun)
+transportDispatcher.registerTimerCbFun(cbTimerFun)
+
+# UDP/IPv4
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openClientMode()
+)
+
+# Pass message to dispatcher
+transportDispatcher.sendMessage(
+ encoder.encode(reqMsg), udp.domainName, ('demo.snmplabs.com', 161)
+)
+transportDispatcher.jobStarted(1)
+
+# Dispatcher will finish as job#1 counter reaches zero
+transportDispatcher.runDispatcher()
+
+transportDispatcher.closeDispatcher()
diff --git a/examples/v1arch/asyncore/manager/ntfrcv/v1-multiple-transports.py b/examples/v1arch/asyncore/manager/ntfrcv/v1-multiple-transports.py
new file mode 100644
index 0000000..b9073cf
--- /dev/null
+++ b/examples/v1arch/asyncore/manager/ntfrcv/v1-multiple-transports.py
@@ -0,0 +1,100 @@
+"""
+Listen for notifications at IPv4 & IPv6 interfaces
+++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:162
+* over IPv6/UDP, listening at [::1]:162
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v1 -c public 127.0.0.1 1.3.6.1.4.1.20408.4.1.1.2 127.0.0.1 1 1 123 1.3.6.1.2.1.1.1.0 s test
+| $ snmptrap -v2c -c public udp6:[::1] 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+
+Notification Receiver below uses two different transports for communication
+with Notification Originators - UDP over IPv4 and UDP over IPv6.
+
+"""#
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp, udp6, unix
+from pyasn1.codec.ber import decoder
+from pysnmp.proto import api
+
+def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
+ while wholeMsg:
+ msgVer = int(api.decodeMessageVersion(wholeMsg))
+ if msgVer in api.protoModules:
+ pMod = api.protoModules[msgVer]
+ else:
+ print('Unsupported SNMP version %s' % msgVer)
+ return
+ reqMsg, wholeMsg = decoder.decode(
+ wholeMsg, asn1Spec=pMod.Message(),
+ )
+ print('Notification message from %s:%s: ' % (
+ transportDomain, transportAddress
+ )
+ )
+ reqPDU = pMod.apiMessage.getPDU(reqMsg)
+ if reqPDU.isSameTypeWith(pMod.TrapPDU()):
+ if msgVer == api.protoVersion1:
+ print('Enterprise: %s' % (
+ pMod.apiTrapPDU.getEnterprise(reqPDU).prettyPrint()
+ )
+ )
+ print('Agent Address: %s' % (
+ pMod.apiTrapPDU.getAgentAddr(reqPDU).prettyPrint()
+ )
+ )
+ print('Generic Trap: %s' % (
+ pMod.apiTrapPDU.getGenericTrap(reqPDU).prettyPrint()
+ )
+ )
+ print('Specific Trap: %s' % (
+ pMod.apiTrapPDU.getSpecificTrap(reqPDU).prettyPrint()
+ )
+ )
+ print('Uptime: %s' % (
+ pMod.apiTrapPDU.getTimeStamp(reqPDU).prettyPrint()
+ )
+ )
+ varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU)
+ else:
+ varBinds = pMod.apiPDU.getVarBindList(reqPDU)
+ print('Var-binds:')
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return wholeMsg
+
+transportDispatcher = AsyncoreDispatcher()
+
+transportDispatcher.registerRecvCbFun(cbFun)
+
+# UDP/IPv4
+transportDispatcher.registerTransport(
+ udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 162))
+)
+
+# UDP/IPv6
+transportDispatcher.registerTransport(
+ udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162))
+)
+
+## Local domain socket
+#transportDispatcher.registerTransport(
+# unix.domainName, unix.UnixSocketTransport().openServerMode('/tmp/snmp-manager')
+#)
+
+transportDispatcher.jobStarted(1)
+
+try:
+ # Dispatcher will never finish as job#1 never reaches zero
+ transportDispatcher.runDispatcher()
+except:
+ transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncio/agent/cmdrsp/v3-multiple-users.py b/examples/v3arch/asyncio/agent/cmdrsp/v3-multiple-users.py
index cdc264b..b0b7e5b 100644
--- a/examples/v3arch/asyncio/agent/cmdrsp/v3-multiple-users.py
+++ b/examples/v3arch/asyncio/agent/cmdrsp/v3-multiple-users.py
@@ -1,25 +1,28 @@
-#
-# Command Responder
-#
-# Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
-# the following options:
-#
-# * SNMPv3
-# * with USM user 'usr-md5-des', auth: MD5, priv DES or
-# with USM user 'usr-sha-none', auth: SHA, no privacy
-# with USM user 'usr-sha-aes128', auth: SHA, priv AES
-# * allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
-# * over IPv4/UDP, listening at 127.0.0.1:161
-# * using asyncio network transport (available since Python 3.4)
-#
-# Either of the following Net-SNMP's commands will walk this Agent:
-#
-# $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
-# $ snmpwalk -v3 -u usr-sha-none -l authNoPriv -a SHA -A authkey1 localhost .1.3.6
-# $ snmpwalk -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 localhost .1.3.6
-#
-# Requires Python 3.4 and later!
-#
+"""
+Multiple SNMP USM users
++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with USM user:
+ - 'usr-md5-des', auth: MD5, priv DES or
+ - 'usr-sha-none', auth: SHA, no privacy
+ - 'usr-sha-aes128', auth: SHA, priv AES
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+* using asyncio network transport (available since Python 3.4)
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
+| $ snmpwalk -v3 -u usr-sha-none -l authNoPriv -a SHA -A authkey1 localhost .1.3.6
+| $ snmpwalk -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 localhost .1.3.6
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
from pysnmp.carrier.asyncio.dgram import udp
diff --git a/examples/v3arch/asyncio/agent/ntforg/inform-v3.py b/examples/v3arch/asyncio/agent/ntforg/inform-v3.py
index 133ff05..3474495 100644
--- a/examples/v3arch/asyncio/agent/ntforg/inform-v3.py
+++ b/examples/v3arch/asyncio/agent/ntforg/inform-v3.py
@@ -1,19 +1,25 @@
-#
-# Notification Originator
-#
-# Send SNMP INFORM notification using the following options:
-#
-# * SNMPv3
-# * with user 'usr-md5-none', auth: MD5, priv NONE
-# * over IPv4/UDP
-# * using asyncio network transport (available from Python 3.4)
-# * to a Manager at 127.0.0.1:162
-# * send INFORM notification
-# * with TRAP ID 'warmStart' specified as an OID
-# * include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
-#
-# Requires Python 3.4 and later!
-#
+"""
+SNMP IMFORM notification
+++++++++++++++++++++++++
+
+Send SNMP INFORM notification using the following options:
+
+* SNMPv3
+* with user 'usr-md5-none', auth: MD5, priv NONE
+* over IPv4/UDP
+* using asyncio network transport (available from Python 3.4)
+* to a Manager at 127.0.0.1:162
+* send INFORM notification
+* with TRAP ID 'warmStart' specified as an 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-md5-none -A authkey1 127.0.0.1 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s 'system name'
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import context
from pysnmp.entity.rfc3413.asyncio import ntforg
diff --git a/examples/v3arch/asyncio/agent/ntforg/trap-v1.py b/examples/v3arch/asyncio/agent/ntforg/trap-v1.py
index 5104f90..28f8ba5 100644
--- a/examples/v3arch/asyncio/agent/ntforg/trap-v1.py
+++ b/examples/v3arch/asyncio/agent/ntforg/trap-v1.py
@@ -1,23 +1,29 @@
-#
-# Notification Originator
-#
-# Send SNMP notification using the following options:
-#
-# * SNMPv1
-# * with community name 'public'
-# * over IPv4/UDP
-# * using asyncio network transport (available from Python 3.4)
-# * to a Manager at 127.0.0.1:162
-# * send TRAP notification
-# * with TRAP ID 'coldStart' specified as an OID
-# * include managed objects information:
-# * 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'
-#
-# Requires Python 3.4 and later!
-#
+"""
+SNMP TRAP notification
+++++++++++++++++++++++
+
+Send SNMP notification using the following options:
+
+* SNMPv1
+* with community name 'public'
+* over IPv4/UDP
+* using asyncio network transport (available from Python 3.4)
+* to a Manager at 127.0.0.1:162
+* send TRAP notification
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+* 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'
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import context
from pysnmp.entity.rfc3413.asyncio import ntforg
diff --git a/examples/v3arch/asyncio/manager/cmdgen/get-v2c-custom-timeout.py b/examples/v3arch/asyncio/manager/cmdgen/get-v2c-custom-timeout.py
index c2ef8b5..93efaba 100644
--- a/examples/v3arch/asyncio/manager/cmdgen/get-v2c-custom-timeout.py
+++ b/examples/v3arch/asyncio/manager/cmdgen/get-v2c-custom-timeout.py
@@ -1,20 +1,23 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv2c, community 'public'
-# using Asyncio framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# wait 3 seconds for response, retry 5 times (plus one initial attempt)
-# for an OID in string form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
-#
-# Requires Python 3.4 and later!
-#
+"""
+Fetch scalar value
+++++++++++++++++++
+
+Send SNMP GET request with the following options:
+
+* with SNMPv2c, community 'public'
+* using Asyncio framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* wait 3 seconds for response, retry 5 times (plus one initial attempt)
+* for an OID in string form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity.rfc3413.asyncio import cmdgen
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/asyncio/manager/cmdgen/get-v2c-over-ipv6.py b/examples/v3arch/asyncio/manager/cmdgen/get-v2c-over-ipv6.py
index e1b3171..da3a0d0 100644
--- a/examples/v3arch/asyncio/manager/cmdgen/get-v2c-over-ipv6.py
+++ b/examples/v3arch/asyncio/manager/cmdgen/get-v2c-over-ipv6.py
@@ -1,19 +1,22 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv2c, community 'public'
-# using Asyncio framework for network transport
-# over IPv6/UDP
-# to an Agent at [::]:161
-# for an OID in string form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v2c -c public -ObentU udp6:[::1]:161 1.3.6.1.2.1.1.1.0
-#
-# Requires Python 3.4 and later!
-#
+"""
+Fetch scalar value over IPv6
+++++++++++++++++++++++++++++
+
+Send SNMP GET request with the following options:
+
+* with SNMPv2c, community 'public'
+* using Asyncio framework for network transport
+* over IPv6/UDP
+* to an Agent at [::]:161
+* for an OID in string form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU udp6:[::1]:161 1.3.6.1.2.1.1.1.0
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.carrier.asyncio.dgram import udp6
from pysnmp.entity.rfc3413.asyncio import cmdgen
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/asyncio/manager/cmdgen/getbulk-v2c.py b/examples/v3arch/asyncio/manager/cmdgen/getbulk-v2c.py
index 5cbe619..939c846 100644
--- a/examples/v3arch/asyncio/manager/cmdgen/getbulk-v2c.py
+++ b/examples/v3arch/asyncio/manager/cmdgen/getbulk-v2c.py
@@ -1,21 +1,24 @@
-#
-# GETBULK Command Generator
-#
-# Send a series of SNMP GETBULK requests
-# with SNMPv2c, community 'public'
-# using Asyncio framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# with values non-repeaters = 0, max-repetitions = 25
-# for two OIDs in string form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
-# Requires Python 3.4 and later!
-#
+"""
+Bulk walk MIB
++++++++++++++
+
+Send a series of SNMP GETBULK requests with the following options:
+
+* with SNMPv2c, community 'public'
+* using Asyncio framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* with values non-repeaters = 0, max-repetitions = 25
+* for two OIDs in string form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.proto import rfc1905
from pysnmp.entity.rfc3413.asyncio import cmdgen
diff --git a/examples/v3arch/asyncio/manager/cmdgen/getnext-v2c-from-specific-address.py b/examples/v3arch/asyncio/manager/cmdgen/getnext-v2c-from-specific-address.py
index e50eac8..10a97eb 100644
--- a/examples/v3arch/asyncio/manager/cmdgen/getnext-v2c-from-specific-address.py
+++ b/examples/v3arch/asyncio/manager/cmdgen/getnext-v2c-from-specific-address.py
@@ -1,21 +1,24 @@
-#
-# GETNEXT Command Generator
-#
-# Send a series of SNMP GETNEXT requests
-# with SNMPv2c, community 'public'
-# using Asyncio framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# sending packets from any local interface (0.0.0.0), local port 61024
-# for two OIDs in string form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
-# Requires Python 3.4 and later!
-#
+"""
+Send packets from specific local interface
+++++++++++++++++++++++++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests with the following options:
+
+* with SNMPv2c, community 'public'
+* using Asyncio framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* sending packets from any local interface (0.0.0.0), local port 61024
+* for two OIDs in string form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.proto import rfc1905
from pysnmp.entity.rfc3413.asyncio import cmdgen
diff --git a/examples/v3arch/asyncio/manager/cmdgen/set-v2c.py b/examples/v3arch/asyncio/manager/cmdgen/set-v2c.py
index 1e512f2..381f11a 100644
--- a/examples/v3arch/asyncio/manager/cmdgen/set-v2c.py
+++ b/examples/v3arch/asyncio/manager/cmdgen/set-v2c.py
@@ -1,20 +1,22 @@
-#
-# Command Generator
-#
-# Send SNMP SET request using the following options:
-#
-# * with SNMPv1, community 'public'
-# * using Asyncio framework for network transport
-# * over IPv4/UDP
-# * to an Agent at 195.218.195.228:161
-# * for OIDs in tuple form and an integer and string-typed values
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
-#
-# Requires Python 3.4 and later!
-#
+"""
+SET string and integer scalars
+++++++++++++++++++++++++++++++
+
+Send SNMP SET request using the following options:
+
+* with SNMPv1, community 'public'
+* using Asyncio framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in tuple form and an integer and string-typed values
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity.rfc3413.asyncio import cmdgen
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/asyncio/manager/ntfrcv/v2c-multiple-interfaces.py b/examples/v3arch/asyncio/manager/ntfrcv/v2c-multiple-interfaces.py
index a5fa241..30dc511 100644
--- a/examples/v3arch/asyncio/manager/ntfrcv/v2c-multiple-interfaces.py
+++ b/examples/v3arch/asyncio/manager/ntfrcv/v2c-multiple-interfaces.py
@@ -1,23 +1,25 @@
-#
-# Notification Receiver
-#
-# Receive SNMP TRAP/INFORM messages with the following options:
-#
-# * SNMPv1/SNMPv2c
-# * with SNMP community "public"
-# * over IPv4/UDP, listening at 127.0.0.1:162
-# over IPv4/UDP, listening at 127.0.0.1:2162
-# * using Asyncio framework for network transport
-# * print received data on stdout
-#
-# Either of the following Net-SNMP's commands will send notifications to this
-# receiver:
-#
-# $ snmptrap -v2c -c public 127.0.0.1:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
-# $ snmpinform -v2c -c public 127.0.0.1:2162 123 1.3.6.1.6.3.1.1.5.1
-#
-# Requires Python 3.4 and later!
-#
+"""
+Serving multiple network interfaces
++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:162
+ over IPv4/UDP, listening at 127.0.0.1:2162
+* using Asyncio framework for network transport
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v2c -c public 127.0.0.1:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+| $ snmpinform -v2c -c public 127.0.0.1:2162 123 1.3.6.1.6.3.1.1.5.1
+
+Requires Python 3.4 and later!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity.rfc3413 import ntfrcv
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v1-read-and-write-communities.py b/examples/v3arch/asyncore/agent/cmdrsp/v1-read-and-write-communities.py
new file mode 100644
index 0000000..5780025
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v1-read-and-write-communities.py
@@ -0,0 +1,65 @@
+"""
+Multiple SNMP communities
++++++++++++++++++++++++++
+
+Respond to SNMP GET/SET/GETNEXT queries with the following options:
+
+* SNMPv1
+* with SNMP community "public" (read access) or "private" (write access)
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+Allow read/write access to all objects in the same MIB subtree.
+
+The following Net-SNMP's commands will GET/SET a value at this Agent:
+
+| $ snmpget -v1 -c public 127.0.0.1 SNMPv2-MIB::sysLocation.0
+| $ snmpset -v1 -c private 127.0.0.1 SNMPv2-MIB::sysLocation.0 s "far away"
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv1 setup
+
+# SecurityName <-> CommunityName mapping.
+# Here we configure two distinct CommunityName's to control read and write
+# operations.
+config.addV1System(snmpEngine, 'my-read-area', 'public')
+config.addV1System(snmpEngine, 'my-write-area', 'private')
+
+# Allow full MIB access for this user / securityModels at VACM
+config.addVacmUser(snmpEngine, 1, 'my-read-area', 'noAuthNoPriv', (1,3,6,1,2,1))
+config.addVacmUser(snmpEngine, 1, 'my-write-area', 'noAuthNoPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py b/examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
new file mode 100644
index 0000000..196ee9c
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
@@ -0,0 +1,82 @@
+"""
+Implementing scalar MIB objects
++++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv2c
+* with SNMP community "public"
+* serving custom Managed Object Instance defined within this script
+* allow read access only to the subtree where the custom MIB object resides
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+The following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
+
+"""#
+import sys
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv2c setup
+
+# SecurityName <-> CommunityName mapping.
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Allow read MIB access for this user / securityModels at VACM
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1,3,6,5))
+
+# Create an SNMP context
+snmpContext = context.SnmpContext(snmpEngine)
+
+# --- create custom Managed Object Instance ---
+
+mibBuilder = snmpContext.getMibInstrum().getMibBuilder()
+
+MibScalar, MibScalarInstance = mibBuilder.importSymbols(
+ 'SNMPv2-SMI', 'MibScalar', 'MibScalarInstance'
+)
+
+class MyStaticMibScalarInstance(MibScalarInstance):
+ def getValue(self, name, idx):
+ return self.getSyntax().clone(
+ 'Python %s running on a %s platform' % (sys.version, sys.platform)
+ )
+
+mibBuilder.exportSymbols(
+ '__MY_MIB', MibScalar((1,3,6,5,1), v2c.OctetString()),
+ MyStaticMibScalarInstance((1,3,6,5,1), (0,), v2c.OctetString())
+)
+
+# --- end of Managed Object Instance initialization ----
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-tabular-mib-objects.py b/examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-tabular-mib-objects.py
new file mode 100644
index 0000000..bf6d042
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v2c-custom-tabular-mib-objects.py
@@ -0,0 +1,126 @@
+"""
+Implementing conceptual table
++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv2c
+* with SNMP community "public"
+* define a simple SNMP Table within a newly created EXAMPLE-MIB
+* pre-populate SNMP Table with a single row of values
+* allow read access only to the subtree where example SNMP Table resides
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+The following Net-SNMP commands will populate and walk a table:
+
+| $ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.2.97.98.99 s 'my value'
+| $ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 4
+| $ snmpwalk -v2c -c public 127.0.0.1 1.3.6
+
+...while the following command will destroy the same row
+
+| $ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 6
+| $ snmpwalk -v2c -c public 127.0.0.1 1.3.6
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv2c setup
+
+# SecurityName <-> CommunityName mapping.
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Allow read MIB access for this user / securityModels at VACM
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1,3,6,6), (1,3,6,6))
+
+# Create an SNMP context
+snmpContext = context.SnmpContext(snmpEngine)
+
+# --- define custom SNMP Table within a newly defined EXAMPLE-MIB ---
+
+mibBuilder = snmpContext.getMibInstrum().getMibBuilder()
+
+( MibTable,
+ MibTableRow,
+ MibTableColumn,
+ MibScalarInstance ) = mibBuilder.importSymbols(
+ 'SNMPv2-SMI',
+ 'MibTable',
+ 'MibTableRow',
+ 'MibTableColumn',
+ 'MibScalarInstance'
+ )
+
+RowStatus, = mibBuilder.importSymbols('SNMPv2-TC', 'RowStatus')
+
+mibBuilder.exportSymbols(
+ '__EXAMPLE-MIB',
+ # table object
+ exampleTable=MibTable((1,3,6,6,1)).setMaxAccess('readcreate'),
+ # table row object, also carries references to table indices
+ exampleTableEntry=MibTableRow((1,3,6,6,1,5)).setMaxAccess('readcreate').setIndexNames((0, '__EXAMPLE-MIB', 'exampleTableColumn1')),
+ # table column: string index
+ exampleTableColumn1=MibTableColumn((1,3,6,6,1,5,1), v2c.OctetString()).setMaxAccess('readcreate'),
+ # table column: string value
+ exampleTableColumn2=MibTableColumn((1,3,6,6,1,5,2), v2c.OctetString()).setMaxAccess('readcreate'),
+ # table column: integer value with default
+ exampleTableColumn3=MibTableColumn((1,3,6,6,1,5,3), v2c.Integer32(123)).setMaxAccess('readcreate'),
+ # table column: row status
+ exampleTableStatus=MibTableColumn((1,3,6,6,1,5,4), RowStatus('notExists')).setMaxAccess('readcreate')
+)
+
+# --- end of custom SNMP table definition, empty table now exists ---
+
+# --- populate custom SNMP table with one row ---
+
+( exampleTableEntry,
+ exampleTableColumn2,
+ exampleTableColumn3,
+ exampleTableStatus ) = mibBuilder.importSymbols(
+ '__EXAMPLE-MIB',
+ 'exampleTableEntry',
+ 'exampleTableColumn2',
+ 'exampleTableColumn3',
+ 'exampleTableStatus'
+)
+rowInstanceId = exampleTableEntry.getInstIdFromIndices('example record one')
+mibInstrumentation = snmpContext.getMibInstrum()
+mibInstrumentation.writeVars(
+ ( (exampleTableColumn2.name+rowInstanceId, 'my string value'),
+ (exampleTableColumn3.name+rowInstanceId, 123456),
+ (exampleTableStatus.name+rowInstanceId, 'createAndGo') )
+)
+
+# --- end of SNMP table population ---
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-interfaces.py b/examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-interfaces.py
new file mode 100644
index 0000000..25beef3
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-interfaces.py
@@ -0,0 +1,67 @@
+"""
+Listen on multiple network interfaces
++++++++++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv2c
+* with SNMP community "public"
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161 and 127.0.0.2:161 interfaces
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
+| $ snmpwalk -v2c -c public 127.0.0.2 .1.3.6
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4 at 127.0.0.1:161
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+# UDP over IPv4 at 127.0.0.2:161
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (2,),
+ udp.UdpTransport().openServerMode(('127.0.0.2', 161))
+)
+
+# SNMPv2c setup
+
+# SecurityName <-> CommunityName mapping.
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Allow full MIB access for this user / securityModels at VACM
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-transports.py b/examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-transports.py
new file mode 100644
index 0000000..24de061
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v2c-multiple-transports.py
@@ -0,0 +1,68 @@
+"""
+Serve multiple network transports
++++++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv2c
+* with SNMP community "public"
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161 and
+ over IPv6/UDP, listening at [::1]:161
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
+| $ snmpwalk -v2c -c public udp6:[::1] .1.3.6
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp, udp6
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4 at 127.0.0.1:161
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+# UDP over IPv6 at [::1]:161
+config.addTransport(
+ snmpEngine,
+ udp6.domainName,
+ udp6.Udp6Transport().openServerMode(('::1', 161))
+)
+
+# SNMPv2c setup
+
+# SecurityName <-> CommunityName mapping.
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Allow full MIB access for this user / securityModels at VACM
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib-controller.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib-controller.py
new file mode 100644
index 0000000..1711133
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib-controller.py
@@ -0,0 +1,77 @@
+"""
+Custom MIB Controller
++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with USM username usr-none-none
+* using alternative set of Managed Objects addressed by
+ contextName: my-context
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+The following Net-SNMP command will send GET request to this Agent:
+
+| $ snmpget -v3 -u usr-none-none -l noAuthNoPriv -n my-context -Ir 127.0.0.1 sysDescr.0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.smi import instrum
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv3/USM setup
+
+# user: usr-none-none, auth: NONE, priv NONE
+config.addV3User(
+ snmpEngine, 'usr-none-none'
+)
+
+# Allow full MIB access for each user at VACM
+config.addVacmUser(snmpEngine, 3, 'usr-none-none', 'noAuthNoPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Create an SNMP context
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Very basic Management Instrumentation Controller without
+# any Managed Objects attached. It supports only GET's and
+# always echos request var-binds in response.
+class EchoMibInstrumController(instrum.AbstractMibInstrumController):
+ def readVars(self, vars, acInfo=(None, None)):
+ return [ (ov[0], v2c.OctetString('You queried OID %s' % ov[0])) for ov in vars]
+
+# Create a custom Management Instrumentation Controller and register at
+# SNMP Context under ContextName 'my-context'
+snmpContext.registerContextName(
+ v2c.OctetString('my-context'), # Context Name
+ EchoMibInstrumController() # Management Instrumentation
+)
+
+# Register GET&SET Applications at the SNMP engine for a custom SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib.py
new file mode 100644
index 0000000..fa3bc6b
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-alternative-mib.py
@@ -0,0 +1,77 @@
+"""
+Serve non-default MIB tree
+++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with USM username usr-md5-none
+* using alternative set of Managed Objects addressed by
+ contextEngineId: 8000000001020304, contextName: my-context
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-none -l authNoPriv -A authkey1 -E 8000000001020304 -n my-context 127.0.0.1 .1.3.6
+| $ snmpwalk -v3 -u usr-md5-none -l authNoPriv -A authkey1 -E 8000000001020304 127.0.0.1 .1.3.6
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.smi import instrum, builder
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv3/USM setup
+
+# user: usr-md5-none, auth: MD5, priv NONE
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+
+# Allow full MIB access for each user at VACM
+config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Create an SNMP context with ContextEngineId = 8000000001020304
+snmpContext = context.SnmpContext(
+ snmpEngine, contextEngineId=v2c.OctetString(hexValue='8000000001020304')
+)
+
+# Create an [empty] set of Managed Objects (MibBuilder), pass it to
+# Management Instrumentation Controller and register at SNMP Context
+# under ContextName 'my-context'
+snmpContext.registerContextName(
+ v2c.OctetString('my-context'), # Context Name
+ instrum.MibInstrumController(builder.MibBuilder()) # Managed Objects
+)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-custom-engine-id.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-custom-engine-id.py
new file mode 100644
index 0000000..e2452ca
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-custom-engine-id.py
@@ -0,0 +1,65 @@
+"""
+Specific SNMP Engine ID
++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with SNMP EngineID: 8000000004030201
+* with USM user 'usr-md5-des', auth: MD5, priv DES
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+The following Net-SNMP command will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 -e 8000000004030201 localhost .1.3.6
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.proto import rfc1902
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine(rfc1902.OctetString(hexValue='8000000004030201'))
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv3/USM setup
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+
+# Allow full MIB access for each user at VACM
+config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-snmp-engines.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-snmp-engines.py
new file mode 100644
index 0000000..0a7b3a2
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-snmp-engines.py
@@ -0,0 +1,93 @@
+"""
+Multiple SNMP Engines
++++++++++++++++++++++
+
+Run multiple SNMP Engines each with a complete Command Responder.
+Bind each SNMP Engine to a dedicated network transport endpoint:
+
+* IPv4/UDP, listening at 127.0.0.1:161
+* IPv4/UDP, listening at 127.0.0.2:161
+
+Each Command Responder will respond to SNMP GET/SET/GETNEXT/GETBULK
+queries with the following options:
+
+* SNMPv3
+* with USM user 'usr-md5-des', auth: MD5, priv DES
+* allow read access to SNMPv2-MIB objects (1.3.6)
+* allow write access to SNMPv2-MIB objects (1.3.6.1.2.1)
+
+The following Net-SNMP commands will walk the first and the second
+Agent respectively:
+
+| $ snmpwalk -Ob -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 127.0.0.1 usmUserEntry
+| $ snmpwalk -Ob -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 127.0.0.2 usmUserEntry
+
+Notice differently configured snmpEngineId's in usmUserEntry columns.
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.proto import rfc1902
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Configuration parameters for each of SNMP Engines
+snmpEngineInfo = (
+ ( '0102030405060708', udp.domainName + (0,), ('127.0.0.1', 161) ),
+ ( '0807060504030201', udp.domainName + (1,), ('127.0.0.2', 161) )
+)
+
+# Instantiate the single transport dispatcher object
+transportDispatcher = AsyncoreDispatcher()
+
+# Setup a custom data routing function to select snmpEngine by transportDomain
+transportDispatcher.registerRoutingCbFun(lambda td,t,d: td)
+
+# Instantiate and configure SNMP Engines
+for snmpEngineId, transportDomain, transportAddress in snmpEngineInfo:
+ # Create SNMP engine with specific engineID
+ snmpEngine = engine.SnmpEngine(rfc1902.OctetString(hexValue=snmpEngineId))
+
+ # Register SNMP Engine object with transport dispatcher. Request incoming
+ # data from specific transport endpoint to be funneled to this SNMP Engine.
+ snmpEngine.registerTransportDispatcher(transportDispatcher, transportDomain)
+
+ # Transport setup
+
+ # UDP over IPv4
+ config.addTransport(
+ snmpEngine,
+ transportDomain,
+ udp.UdpTransport().openServerMode(transportAddress)
+ )
+
+ # SNMPv3/USM setup
+
+ # user: usr-md5-des, auth: MD5, priv DES
+ config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+ )
+
+ # Allow full MIB access for this user / securityModels at VACM
+ config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1,3,6), (1,3,6,1,2,1))
+
+ # Get default SNMP context this SNMP engine serves
+ snmpContext = context.SnmpContext(snmpEngine)
+
+ # Register SNMP Applications at the SNMP engine for particular SNMP context
+ cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+ cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+ cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+ cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ transportDispatcher.runDispatcher()
+except:
+ transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-users.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-users.py
new file mode 100644
index 0000000..150a0f4
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-multiple-users.py
@@ -0,0 +1,80 @@
+"""
+Multiple SNMP USM users
++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with USM user 'usr-md5-des', auth: MD5, priv DES or
+ with USM user 'usr-sha-none', auth: SHA, no privacy
+ with USM user 'usr-sha-aes128', auth: SHA, priv AES
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
+| $ snmpwalk -v3 -u usr-sha-none -l authNoPriv -a SHA -A authkey1 localhost .1.3.6
+| $ snmpwalk -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 localhost .1.3.6
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv3/USM setup
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+# user: usr-sha-none, auth: SHA, priv NONE
+config.addV3User(
+ snmpEngine, 'usr-sha-none',
+ config.usmHMACSHAAuthProtocol, 'authkey1'
+)
+# user: usr-sha-none, auth: SHA, priv AES
+config.addV3User(
+ snmpEngine, 'usr-sha-aes128',
+ config.usmHMACSHAAuthProtocol, 'authkey1',
+ config.usmAesCfb128Protocol, 'privkey1'
+)
+
+# Allow full MIB access for each user at VACM
+config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+config.addVacmUser(snmpEngine, 3, 'usr-sha-none', 'authNoPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+config.addVacmUser(snmpEngine, 3, 'usr-sha-aes128', 'authPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-observe-request-processing.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-observe-request-processing.py
new file mode 100644
index 0000000..d03c52c
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-observe-request-processing.py
@@ -0,0 +1,90 @@
+"""
+Observe SNMP engine operations
+++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with USM user 'usr-md5-des', auth: MD5, priv DES or
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+* registers its own execution observer to snmpEngine
+
+The following Net-SNMP command will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
+
+This script will report some details on request processing as seen
+by rfc3412.receiveMessage() and rfc3412.returnResponsePdu()
+abstract interfaces.
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Execution point observer setup
+
+# Register a callback to be invoked at specified execution point of
+# SNMP Engine and passed local variables at code point's local scope
+def requestObserver(snmpEngine, execpoint, variables, cbCtx):
+ print('Execution point: %s' % execpoint)
+ print('* transportDomain: %s' % '.'.join([str(x) for x in variables['transportDomain']]))
+ print('* transportAddress: %s (local %s)' % ('@'.join([str(x) for x in variables['transportAddress']]), '@'.join([str(x) for x in variables['transportAddress'].getLocalAddress()])))
+ print('* securityModel: %s' % variables['securityModel'])
+ print('* securityName: %s' % variables['securityName'])
+ print('* securityLevel: %s' % variables['securityLevel'])
+ print('* contextEngineId: %s' % variables['contextEngineId'].prettyPrint())
+ print('* contextName: %s' % variables['contextName'].prettyPrint())
+ print('* PDU: %s' % variables['pdu'].prettyPrint())
+
+snmpEngine.observer.registerObserver(
+ requestObserver,
+ 'rfc3412.receiveMessage:request',
+ 'rfc3412.returnResponsePdu'
+)
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# SNMPv3/USM setup
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+
+# Allow full MIB access for each user at VACM
+config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.observer.unregisterObserver()
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/v3-preserve-original-destination-address.py b/examples/v3arch/asyncore/agent/cmdrsp/v3-preserve-original-destination-address.py
new file mode 100644
index 0000000..1e86270
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/cmdrsp/v3-preserve-original-destination-address.py
@@ -0,0 +1,91 @@
+"""
+Running at secondary network interface
+++++++++++++++++++++++++++++++++++++++
+
+Listen on all local IPv4 interfaces respond to SNMP GET/SET/GETNEXT/GETBULK
+queries with the following options:
+
+* SNMPv3
+* with USM user 'usr-md5-des', auth: MD5, priv DES
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 0.0.0.0:161
+* preserve local IP address when responding (Python 3.3+ required)
+
+The following Net-SNMP command will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
+
+In the situation when UDP responder receives a datagram targeted to
+a secondary (AKA virtial) IP interface or a non-local IP interface
+(e.g. routed through policy routing or iptables TPROXY facility),
+OS stack will by default put primary local IP interface address into
+the IP source field of the response IP packet. Such datagram may not
+reach the sender as either the sender itself or a stateful firewall
+somewhere in between would not be able to match response to original
+request.
+
+The following script solves this problem by preserving original request
+destination IP address and put it back into response IP packet's source
+address field.
+
+To respond from a non-local (e.g. spoofed) IP address, uncomment the
+.enableTransparent() method call and run this script as root.
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, context
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# Initialize asyncore-based UDP/IPv4 transport
+udpSocketTransport = udp.UdpSocketTransport().openServerMode(('0.0.0.0', 161))
+
+# Use sendmsg()/recvmsg() for socket communication (used for preserving
+# original destination IP address when responding)
+udpSocketTransport.enablePktInfo()
+
+# Enable IP source spoofing (requires root privileges)
+# udpSocketTransport.enableTransparent()
+
+# Register this transport at SNMP Engine
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udpSocketTransport
+)
+
+# SNMPv3/USM setup
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+
+# Allow full MIB access for each user at VACM
+config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1,3,6,1,2,1), (1,3,6,1,2,1))
+
+# Get default SNMP context this SNMP engine serves
+snmpContext = context.SnmpContext(snmpEngine)
+
+# Register SNMP Applications at the SNMP engine for particular SNMP context
+cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
+cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
+cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
+
+# Register an imaginary never-ending job to keep I/O dispatcher running forever
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.observer.unregisterObserver()
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/agent/ntforg/inform-multiple-protocols.py b/examples/v3arch/asyncore/agent/ntforg/inform-multiple-protocols.py
new file mode 100644
index 0000000..ab5f641
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/inform-multiple-protocols.py
@@ -0,0 +1,119 @@
+"""
+Notification over multiple SNMP versions
+++++++++++++++++++++++++++++++++++++++++
+
+Send SNMP INFORM notifications to multiple Managers using different
+security settings:
+
+* SNMPv2c
+* with community name 'public'
+* AND
+* SNMPv3
+* with user 'usr-md5-none', auth: MD5, priv NONE
+* over IPv4/UDP
+* send INFORM notification
+* to multiple Managers at 127.0.0.1:162, 127.0.0.2:162
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+
+Functionally similar to:
+
+| $ snmpinform -v3 -l authPriv -u usr-md5-none -A authkey1 127.0.0.1 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification'
+
+and
+
+| $ snmpinform -v2c -c public 127.0.0.2 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SNMPv2c:
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds-1', 'my-area', 'noAuthNoPriv', 1)
+
+# SNMPv3:
+
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds-2', 'usr-md5-none', 'authNoPriv')
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+# First target
+config.addTargetAddr(
+ snmpEngine, 'my-nms-1',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds-1',
+ tagList='all-my-managers'
+)
+# Second target
+config.addTargetAddr(
+ snmpEngine, 'my-nms-2',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds-2',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'inform'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (2&3), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Error/confirmation receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ print('Notification %s, status - %s' % (
+ sendRequestHandle, errorIndication and errorIndication or 'delivered'
+ )
+ )
+
+# Build and submit notification message to dispatcher
+sendRequestHandle = ntfOrg.sendVarBinds(
+ snmpEngine,
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ # additional var-binds: ( (oid, value), ... )
+ ((1,3,6,1,2,1,1,1,0), v2c.OctetString('Example Notificator'))
+ ],
+ cbFun
+)
+
+print('Notifications %s are scheduled to be sent' % sendRequestHandle)
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/inform-v2c.py b/examples/v3arch/asyncore/agent/ntforg/inform-v2c.py
new file mode 100644
index 0000000..026d36f
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/inform-v2c.py
@@ -0,0 +1,95 @@
+"""
+INFORM notification
++++++++++++++++++++
+
+Send SNMP INFORM notification using the following options:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* send INFORM notification
+* to a Manager at 127.0.0.1:162
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+ 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
+
+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 'Example Notificator' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping (+ transport binding)
+config.addV1System(snmpEngine, 'my-area', 'public',
+ transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('195.218.195.228', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'inform'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Error/confirmation receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ print('Notification %s, status - %s' % (
+ sendRequestHandle, errorIndication and errorIndication or 'delivered'
+ )
+ )
+
+# Build and submit notification message to dispatcher
+sendRequestHandle = ntfOrg.sendVarBinds(
+ snmpEngine,
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ # additional var-binds: ( (oid, value), ... )
+ ((1,3,6,1,2,1,1,1,0), v2c.OctetString('Example Notificator')),
+ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('Notificator Example'))
+ ],
+ cbFun
+)
+
+print('Notification %s scheduled to be sent' % sendRequestHandle)
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/inform-v3.py b/examples/v3arch/asyncore/agent/ntforg/inform-v3.py
new file mode 100644
index 0000000..116d679
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/inform-v3.py
@@ -0,0 +1,88 @@
+"""
+SNMPv3 INFORM, auth: MD5, privacy: none
++++++++++++++++++++++++++++++++++++++++
+
+Send SNMP INFORM notification using the following options:
+
+* SNMPv3
+* with user 'usr-md5-none', auth: MD5, priv NONE
+* over IPv4/UDP
+* to a Manager at 127.0.0.1:162
+* send INFORM notification
+* with TRAP ID 'warmStart' specified as an OID
+* include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
+
+Functionally similar to:
+
+| $ snmpinform -v3 -l authNoPriv -u usr-md5-none -A authkey1 demo.snmplabs.com 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 = 'system name'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# Add USM user
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-md5-none', 'authNoPriv')
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'inform'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (3), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Error/confirmation receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ print('Notification %s, status - %s' % (
+ sendRequestHandle, errorIndication and errorIndication or 'delivered'
+ )
+ )
+
+# Build and submit notification message to dispatcher
+sendRequestHandle = ntfOrg.sendVarBinds(
+ snmpEngine,
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds: SNMPv2-MIB::coldStart, ...
+ [ ((1,3,6,1,6,3,1,1,5,1), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('system name')) ],
+ cbFun
+)
+
+print('Notification %s scheduled to be sent' % sendRequestHandle)
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v1-from-specific-address.py b/examples/v3arch/asyncore/agent/ntforg/trap-v1-from-specific-address.py
new file mode 100644
index 0000000..c7dfedb
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v1-from-specific-address.py
@@ -0,0 +1,82 @@
+"""
+Send packet from specific network interface/port
+++++++++++++++++++++++++++++++++++++++++++++++++
+
+Send SNMP notification using the following options:
+
+* SNMPv1
+* with community name 'public'
+* over IPv4/UDP
+* to a Manager at 127.0.0.1 UDP port 162
+* from local address 127.0.0.1, UDP port 61024
+* send TRAP notification
+* with TRAP ID 'coldStart' specified as an OID
+
+Functionally similar to:
+
+| $ snmptrap -v1 -c public 127.0.0.1 1.3.6.1.6.3.1.1.5.1 0.0.0.0 1 0 0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public',
+ transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv1 -> 0)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name. Pay attention to the openClientMode() parameter -- it's
+# used to originate packets from particular local IP:port
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode(iface=('127.0.0.1', 61024))
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (1), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 1, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendVarBinds(
+ snmpEngine,
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1)))
+ ]
+)
+
+print('Notification is scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and stop
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v1.py b/examples/v3arch/asyncore/agent/ntforg/trap-v1.py
new file mode 100644
index 0000000..226788a
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v1.py
@@ -0,0 +1,99 @@
+"""
+SNMPv1 TRAP
++++++++++++
+
+Send SNMP notification using the following options:
+
+* SNMPv1
+* with community name 'public'
+* over IPv4/UDP
+* to a Manager at 127.0.0.1:162
+* send TRAP notification
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+* 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 127.0.0.1 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.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv1 -> 0)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (1), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 1, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendVarBinds(
+ snmpEngine,
+ # Notification targets
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # Uptime value with 12345
+ (v2c.ObjectIdentifier('1.3.6.1.2.1.1.3.0'),
+ v2c.TimeTicks(12345)),
+ # trap OID: Generic Trap #6 (enterpriseSpecific)
+ # and Specific Trap 432
+ (v2c.ObjectIdentifier('1.3.6.1.6.3.1.1.5.1'),
+ v2c.ObjectIdentifier('1.3.6.1.4.1.20408.4.1.1.2.0.432')),
+ # Agent Address with '127.0.0.1'
+ (v2c.ObjectIdentifier('1.3.6.1.6.3.18.1.3.0'),
+ v2c.IpAddress('127.0.0.1')),
+ # Enterprise OID with 1.3.6.1.4.1.20408.4.1.1.2
+ (v2c.ObjectIdentifier('1.3.6.1.6.3.1.1.4.3.0'),
+ v2c.ObjectIdentifier('1.3.6.1.4.1.20408.4.1.1.2')),
+ # managed object '1.3.6.1.2.1.1.1.0' = 'my system'
+ (v2c.ObjectIdentifier('1.3.6.1.2.1.1.1.0'),
+ v2c.OctetString('my system'))
+ ]
+)
+
+print('Notification is scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and stop
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v2c-custom-pdu.py b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-custom-pdu.py
new file mode 100644
index 0000000..1051754
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-custom-pdu.py
@@ -0,0 +1,90 @@
+"""
+Send crafted TRAP PDU
++++++++++++++++++++++
+
+Initialize TRAP PDU and pass it over to unified SNMPv3 message processing
+framework for further treatment.
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* send TRAP notification
+* initialize TRAP PDU with the following var-binds:
+ 1.3.6.1.2.1.1.3.0 = 123
+ 1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.1
+
+Functionally similar to:
+
+| $ snmptrap -v1 -c public 127.0.0.1 1.3.6.1.6.3.1.1.5.1 0.0.0.0 1 0 123
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+
+# Create named target
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds'
+)
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create SNMP v2c TRAP PDU with defaults
+trapPDU = v2c.TrapPDU()
+v2c.apiTrapPDU.setDefaults(trapPDU)
+
+# Set custom var-binds to TRAP PDU
+v2c.apiTrapPDU.setVarBinds(
+ trapPDU, [
+ # sysUpTime
+ ( v2c.ObjectIdentifier('1.3.6.1.2.1.1.3.0'), v2c.TimeTicks(123) ),
+ # snmpTrapPDU
+ ( (1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1)) )
+ ]
+)
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Error/confirmation receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ print('Notification %s, status - %s' % (
+ sendRequestHandle, errorIndication and errorIndication or 'delivered'
+ )
+ )
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendPdu(
+ snmpEngine,
+ # Notification targets
+ 'my-nms', # target address
+ None, '', # contextEngineId, contextName
+ trapPDU,
+ cbFun
+)
+
+print('Notification is scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-addresses.py b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-addresses.py
new file mode 100644
index 0000000..ce82f60
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-addresses.py
@@ -0,0 +1,110 @@
+"""
+Notification to multiple addresses
+++++++++++++++++++++++++++++++++++
+
+Send SNMP TRAP notifications to multiple Managers using different
+security settings:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* send TRAP notification
+* to multiple Managers at 127.0.0.1:162, 127.0.0.2:162
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+ 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
+
+Functionally similar to:
+
+| $ snmptrap -v2c -c public 127.0.0.1 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+and
+
+| $ snmptrap -v2c -c public 127.0.0.2 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+and
+
+| $ snmptrap -v2c -c public 127.0.0.3 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+# First target
+config.addTargetAddr(
+ snmpEngine, 'my-nms-1',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+# Second target
+config.addTargetAddr(
+ snmpEngine, 'my-nms-2',
+ udp.domainName, ('127.0.0.2', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+# Third target
+config.addTargetAddr(
+ snmpEngine, 'my-nms-3',
+ udp.domainName, ('127.0.0.3', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendVarBinds(
+ snmpEngine,
+ # Notification targets
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ # additional var-binds: ( (oid, value), ... )
+ ((1,3,6,1,2,1,1,1,0), v2c.OctetString('Example Notificator')),
+ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('Notificator Example'))
+ ]
+)
+
+print('Notifications are scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-transports.py b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-transports.py
new file mode 100644
index 0000000..1c93e62
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-multiple-transports.py
@@ -0,0 +1,106 @@
+"""
+Notification over multiple network protocols
+++++++++++++++++++++++++++++++++++++++++++++
+
+Send SNMP INFORM notifications to multiple Managers over different
+network protocols:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP and UDP/IPv6
+* send TRAP notification
+* to two Managers through different network transports
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+ 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
+
+Functionally similar to:
+
+| $ snmptrap -v2c -c public udp:127.0.0.1 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+and
+
+| $ snmptrap -v2c -c public udp6:[::1] 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp, udp6
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+# Setup transport endpoints and bind it with security settings yielding
+# a target name:
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms-1',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# UDP/IPv6
+config.addTransport(
+ snmpEngine,
+ udp6.domainName,
+ udp6.Udp6SocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms-2',
+ udp6.domainName, ('::1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendVarBinds(
+ snmpEngine,
+ # Notification targets
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ # additional var-binds: ( (oid, value), ... )
+ ((1,3,6,1,2,1,1,1,0), v2c.OctetString('Example Notificator')),
+ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('Notificator Example'))
+ ]
+)
+
+print('Notification is scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v2c-with-objects.py b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-with-objects.py
new file mode 100644
index 0000000..b72c5a7
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v2c-with-objects.py
@@ -0,0 +1,108 @@
+"""
+Sending notification with OBJECT's
+++++++++++++++++++++++++++++++++++
+
+Send SNMP TRAP notification using the following options:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* send TRAP notification
+* to a Manager at 127.0.0.1:162
+* with TRAP ID IF-MIB::ifLink as MIB symbol
+
+The IF-MIB::ifLink NOTIFICATION-TYPE implies including four other
+var-binds into the notification message describing the incident
+occurred. These var-binds are:
+IF-MIB::ifIndex."x"
+IF-MIB::ifAdminStatus."x"
+IF-MIB::ifOperStatus."x"
+IF-MIB::ifDescr."x"
+
+Where "x" is MIB table index (instance index).
+
+Functionally similar to:
+
+| $ snmptrap -v2c -c public 127.0.0.1 0 1.3.6.1.6.3.1.1.5.3 IF-MIB::ifIndex."1" IF-MIB::ifAdminStatus."1" IF-MIB::ifOperStatus."1" IF-MIB::ifDescr."1"
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.smi import rfc1902, view
+
+#
+# Here we fill in some values for Managed Objects Instances (invoked
+# later while building TRAP message) by NOTIFICATION-TYPE macro evaluation.
+# In real Agent app, these values should already be initialized during
+# Agent runtime.
+#
+instanceIndex = (1,)
+objects = {
+ ('IF-MIB', 'ifIndex'): instanceIndex[0],
+ ('IF-MIB', 'ifAdminStatus'): 'up',
+ ('IF-MIB', 'ifOperStatus'): 'down',
+ ('IF-MIB', 'ifDescr'): 'eth0'
+}
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# MIB view controller is used for MIB lookup purposes
+mibViewController = view.MibViewController(snmpEngine.getMibBuilder())
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+# Setup transport endpoints and bind it with security settings yielding
+# a target name:
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms-1',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendVarBinds(
+ snmpEngine,
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ rfc1902.NotificationType(
+ rfc1902.ObjectIdentity('IF-MIB', 'linkUp'),
+ instanceIndex=instanceIndex,
+ objects=objects
+ ).resolveWithMib(mibViewController)
+)
+
+print('Notification is scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v2c.py b/examples/v3arch/asyncore/agent/ntforg/trap-v2c.py
new file mode 100644
index 0000000..2a926d8
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v2c.py
@@ -0,0 +1,95 @@
+"""
+SNMPv2c TRAP
+++++++++++++
+
+Send SNMP TRAP notification using the following options:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* send TRAP notification
+* to a Manager at 127.0.0.1:162
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+ 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
+
+Functionally similar to:
+
+| $ snmptrap -v2c -c public 127.0.0.1 12345 1.3.6.1.4.1.20408.4.1.1.2
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers')
+
+# Specify security settings per SecurityName (SNMPv2c -> 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Error/confirmation receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ print('Notification %s, status - %s' % (
+ sendRequestHandle, errorIndication and errorIndication or 'delivered'
+ )
+ )
+
+# Build and submit notification message to dispatcher
+sendRequestHandle = ntfOrg.sendVarBinds(
+ snmpEngine,
+ # Notification targets
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ # additional var-binds: ( (oid, value), ... )
+ ((1,3,6,1,2,1,1,1,0), v2c.OctetString('Example Notificator')),
+ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('Notificator Example'))
+ ],
+ cbFun
+)
+
+print('Notification %s is scheduled to be sent' % sendRequestHandle)
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/agent/ntforg/trap-v3.py b/examples/v3arch/asyncore/agent/ntforg/trap-v3.py
new file mode 100644
index 0000000..d43fe27
--- /dev/null
+++ b/examples/v3arch/asyncore/agent/ntforg/trap-v3.py
@@ -0,0 +1,90 @@
+"""
+SNMPv3 TRAP, auth: MD5, privacy: DES
+++++++++++++++++++++++++++++++++++++
+
+Send SNMP TRAP notification using the following options:
+
+* SNMPv3
+* with user 'usr-md5-des', auth: MD5, priv DES
+* over IPv4/UDP
+* send TRAP notification
+* to a Manager at 127.0.0.1:162
+* with TRAP ID 'warmStart' specified as an OID
+* include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
+
+Functionally similar to:
+
+| $ snmptrap -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -e 800000000
+1020304 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s 'my system'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntforg
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine instance with specific (and locally unique)
+# SnmpEngineId -- it must also be known to the receiving party
+# and configured at its VACM users table.
+snmpEngine = engine.SnmpEngine(
+ snmpEngineID=v2c.OctetString(hexValue='8000000001020304')
+)
+
+# Add USM user
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-md5-des', 'authPriv')
+
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-nms',
+ udp.domainName, ('127.0.0.1', 162),
+ 'my-creds',
+ tagList='all-my-managers'
+)
+
+# Specify what kind of notification should be sent (TRAP or INFORM),
+# to what targets (chosen by tag) and what filter should apply to
+# the set of targets (selected by tag)
+config.addNotificationTarget(
+ snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap'
+)
+
+# Allow NOTIFY access to Agent's MIB by this SNMP model (3), securityLevel
+# and SecurityName
+config.addContext(snmpEngine, '')
+config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (), (), (1,3,6))
+
+# *** SNMP engine configuration is complete by this line ***
+
+# Create Notification Originator App instance.
+ntfOrg = ntforg.NotificationOriginator()
+
+# Build and submit notification message to dispatcher
+ntfOrg.sendVarBinds(
+ snmpEngine,
+ # Notification targets
+ 'my-notification', # notification targets
+ None, '', # contextEngineId, contextName
+ # var-binds
+ [
+ # SNMPv2-SMI::snmpTrapOID.0 = SNMPv2-MIB::coldStart
+ ((1,3,6,1,6,3,1,1,4,1,0), v2c.ObjectIdentifier((1,3,6,1,6,3,1,1,5,1))),
+ # additional var-binds: ( (oid, value), ... )
+ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('Notificator Example'))
+ ]
+)
+
+print('Notification is scheduled to be sent')
+
+# Run I/O dispatcher which would send pending message and process response
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/get-v1.py b/examples/v3arch/asyncore/manager/cmdgen/get-v1.py
new file mode 100644
index 0000000..234d414
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/get-v1.py
@@ -0,0 +1,76 @@
+"""
+SNMPv1
+++++++
+
+* with SNMPv1, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv1 setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
+ # so we ignore noSuchName error here
+ elif errorStatus and errorStatus != 2:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.GetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,1,0), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/get-v2c-custom-timeout.py b/examples/v3arch/asyncore/manager/cmdgen/get-v2c-custom-timeout.py
new file mode 100644
index 0000000..b91a4b6
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/get-v2c-custom-timeout.py
@@ -0,0 +1,79 @@
+"""
+SNMPv2c, custom timeout
++++++++++++++++++++++++
+
+Send a SNMP GET request:
+
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* wait 3 seconds for response, retry 5 times (plus one initial attempt)
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv2c setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds',
+ timeout=300, # in 1/100 sec
+ retryCount=5
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ elif errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.GetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,1,0), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py b/examples/v3arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py
new file mode 100644
index 0000000..998d40f
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/get-v2c-spoof-source-address.py
@@ -0,0 +1,100 @@
+"""
+Spoof source address
+++++++++++++++++++++
+
+Send a SNMP GET request
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* from a non-local, spoofed IP 1.2.3.4 (root and Python 3.3+ required)
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+But unlike the above command, this script issues SNMP request from
+a non-default, non-local IP address.
+
+It is indeed possible to originate SNMP traffic from any valid local
+IP addresses. It could be a secondary IP interface, for instance.
+Superuser privileges are only required to send spoofed packets.
+Alternatively, sending from local interface could also be achieved by
+binding to it (via openClientMode() parameter).
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv1 setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# Initialize asyncore-based UDP/IPv4 transport
+udpSocketTransport = udp.UdpSocketTransport().openClientMode()
+
+# Use sendmsg()/recvmsg() for socket communication (required for
+# IP source spoofing functionality)
+udpSocketTransport.enablePktInfo()
+
+# Enable IP source spoofing (requires root privileges)
+udpSocketTransport.enableTransparent()
+
+# Register this transport at SNMP Engine
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udpSocketTransport
+)
+
+# Configure destination IPv4 address as well as source IPv4 address
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds',
+ sourceAddress=('1.2.3.4', 0)
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
+ # so we ignore noSuchName error here
+ elif errorStatus and errorStatus != 2:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.GetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,1,0), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/get-v3-custom-context.py b/examples/v3arch/asyncore/manager/cmdgen/get-v3-custom-context.py
new file mode 100644
index 0000000..e61e538
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/get-v3-custom-context.py
@@ -0,0 +1,84 @@
+"""
+Custom ContextEngineId and ContextName
+++++++++++++++++++++++++++++++++++++++
+
+Send a SNMP GET request with the following options:
+
+* with SNMPv3 with user 'usr-md5-none', SHA auth and no privacy protocols
+* for MIB instance identified by
+* contextEngineId: 0x80004fb805636c6f75644dab22cc,
+* contextName: da761cfc8c94d3aceef4f60f049105ba
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v3 -l authNoPriv -u usr-md5-none -A authkey1 -E 80004fb805636c6f75644dab22cc -n da761cfc8c94d3aceef4f60f049105ba -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.proto import rfc1902
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-md5-none, auth: MD5, priv: NONE
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-md5-none', 'authNoPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ elif errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message, pass custom ContextEngineId & ContextName
+cmdgen.GetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ # contextEngineId
+ rfc1902.OctetString(hexValue='80004fb805636c6f75644dab22cc'),
+ # contextName
+ rfc1902.OctetString('da761cfc8c94d3aceef4f60f049105ba'),
+ [ ((1,3,6,1,2,1,1,1,0), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/get-v3-observe-request-processing.py b/examples/v3arch/asyncore/manager/cmdgen/get-v3-observe-request-processing.py
new file mode 100644
index 0000000..0914ac3
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/get-v3-observe-request-processing.py
@@ -0,0 +1,105 @@
+"""
+Report SNMP engine processing details
++++++++++++++++++++++++++++++++++++++
+
+Send SNMP GET request with the following options:
+
+* with SNMPv3 with user 'usr-sha-aes', SHA auth and AES128 privacy protocols
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+* also registers its own execution observer to snmpEngine
+
+While execution, this script will report some details on request processing
+as seen by rfc3412.sendPdu() and rfc3412.receiveMessage() abstract interfaces.
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v3 -l authPriv -u usr-sha-aes -a SHA -A authkey1 -x AES -X privkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# Execution point observer setup
+
+# Register a callback to be invoked at specified execution point of
+# SNMP Engine and passed local variables at code point's local scope
+def requestObserver(snmpEngine, execpoint, variables, cbCtx):
+ print('Execution point: %s' % execpoint)
+ print('* transportDomain: %s' % '.'.join([str(x) for x in variables['transportDomain']]))
+ print('* transportAddress: %s' % '@'.join([str(x) for x in variables['transportAddress']]))
+ print('* securityModel: %s' % variables['securityModel'])
+ print('* securityName: %s' % variables['securityName'])
+ print('* securityLevel: %s' % variables['securityLevel'])
+ print('* contextEngineId: %s' % (variables['contextEngineId'] and variables['contextEngineId'].prettyPrint() or '<empty>',))
+ print('* contextName: %s' % variables['contextName'].prettyPrint())
+ print('* PDU: %s' % variables['pdu'].prettyPrint())
+
+snmpEngine.observer.registerObserver(
+ requestObserver,
+ 'rfc3412.sendPdu',
+ 'rfc3412.receiveMessage:response'
+)
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-sha-aes, auth: SHA, priv AES
+config.addV3User(
+ snmpEngine, 'usr-sha-aes',
+ config.usmHMACSHAAuthProtocol, 'authkey1',
+ config.usmAesCfb128Protocol, 'privkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-sha-aes', 'authPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ elif errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.GetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,1,0), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
+
+snmpEngine.observer.unregisterObserver()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/get-v3.py b/examples/v3arch/asyncore/manager/cmdgen/get-v3.py
new file mode 100644
index 0000000..f7ff4ee
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/get-v3.py
@@ -0,0 +1,82 @@
+"""
+SNMPv3, auth: SHA, privacy: AES128
+++++++++++++++++++++++++++++++++++
+
+Send a SNMP GET request
+* with SNMPv3 with user 'usr-sha-aes', SHA auth and AES128 privacy protocols
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v3 -l authPriv -u usr-sha-aes -a SHA -A authkey1 -x AES -X privkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-sha-aes, auth: SHA, priv AES
+config.addV3User(
+ snmpEngine, 'usr-sha-aes',
+ config.usmHMACSHAAuthProtocol, 'authkey1',
+ config.usmAesCfb128Protocol, 'privkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-sha-aes', 'authPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ elif errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.GetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,1,0), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
+
+config.delTransport(
+ snmpEngine,
+ udp.domainName
+).closeTransport()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getbulk-v2c.py b/examples/v3arch/asyncore/manager/cmdgen/getbulk-v2c.py
new file mode 100644
index 0000000..9f5db70
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getbulk-v2c.py
@@ -0,0 +1,82 @@
+"""
+Bulk walk MIB
++++++++++++++
+
+Send a series of SNMP GETBULK requests
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* with values non-repeaters = 0, max-repetitions = 25
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv2c setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequesthandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return # stop on error
+ if errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for oid, val in varBindRow:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return True # signal dispatcher to continue walking
+
+# Prepare initial request to be sent
+cmdgen.BulkCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ 0, 25, # non-repeaters, max-repetitions
+ [ ((1,3,6,1,2,1,1), None),
+ ((1,3,6,1,4,1,1), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getbulk-v3.py b/examples/v3arch/asyncore/manager/cmdgen/getbulk-v3.py
new file mode 100644
index 0000000..8bd04a5
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getbulk-v3.py
@@ -0,0 +1,85 @@
+"""
+Fetch scalar and table variables
+++++++++++++++++++++++++++++++++
+
+Send a series of SNMP GETBULK requests with the following options:
+
+* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* with values non-repeaters = 1, max-repetitions = 25
+* for two OIDs in tuple form (first OID is non-repeating)
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -C n1 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.carrier.asyncore.dgram import udp
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-md5-des', 'authPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequesthandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return # stop on error
+ if errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for oid, val in varBindRow:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return True # signal dispatcher to continue walking
+
+# Prepare initial request to be sent
+cmdgen.BulkCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ 0, 25, # non-repeaters, max-repetitions
+ ( ((1,3,6,1,2,1,1), None),
+ ((1,3,6,1,4,1,1), None) ),
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getnext-v1.py b/examples/v3arch/asyncore/manager/cmdgen/getnext-v1.py
new file mode 100644
index 0000000..0a41a41
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getnext-v1.py
@@ -0,0 +1,83 @@
+"""
+Fetch two subtrees in parallel
+++++++++++++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests with the following options:
+
+* with SNMPv1, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv1/2c setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return
+ # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
+ # so we ignore noSuchName error here
+ if errorStatus and errorStatus != 2:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for oid, val in varBindRow:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return 1 # signal dispatcher to continue
+
+# Prepare initial request to be sent
+cmdgen.NextCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1), None),
+ ((1,3,6,1,4,1,1), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-from-specific-address.py b/examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-from-specific-address.py
new file mode 100644
index 0000000..022742a
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-from-specific-address.py
@@ -0,0 +1,82 @@
+"""
+Send packets from specific local interface
+++++++++++++++++++++++++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests with the following options:
+
+* with SNMPv2c, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* sending packets from primary local interface 0.0.0.0, local port 61024
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv1/2c setup (if you use SNMPv1 or v2c)
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode(('0.0.0.0', 61024))
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return
+ if errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for oid, val in varBindRow:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return 1 # signal dispatcher to continue
+
+# Prepare initial request to be sent
+cmdgen.NextCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1), None),
+ ((1,3,6,1,2,1,11), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py b/examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py
new file mode 100644
index 0000000..d69abfe
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py
@@ -0,0 +1,94 @@
+"""
+Walk Agent and resolve variables at MIB
++++++++++++++++++++++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests with the following options:
+
+* with SNMPv1, community 'public'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.smi import compiler, view, rfc1902
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+# Attach MIB compiler to SNMP Engine (MIB Builder)
+# This call will fail if PySMI is not present on the system
+compiler.addMibCompiler(snmpEngine.getMibBuilder())
+# ... alternatively, this call will not complain on missing PySMI
+#compiler.addMibCompiler(snmpEngine.getMibBuilder(), ifAvailable=True)
+
+# Used for MIB objects resolution
+mibViewController = view.MibViewController(snmpEngine.getMibBuilder())
+
+#
+#
+# SNMPv1/2c setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return
+ # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
+ # so we ignore noSuchName error here
+ if errorStatus and errorStatus != 2:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for varBind in varBindRow:
+ print(rfc1902.ObjectType(rfc1902.ObjectIdentity(varBind[0]), varBind[1]).resolveWithMib(mibViewController).prettyPrint())
+ return 1 # signal dispatcher to continue
+
+# Prepare initial request to be sent
+cmdgen.NextCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ rfc1902.ObjectType(rfc1902.ObjectIdentity('iso.org.dod')).resolveWithMib(mibViewController),
+ rfc1902.ObjectType(rfc1902.ObjectIdentity('IF-MIB', 'ifMIB')).resolveWithMib(mibViewController) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getnext-v3-over-ipv6.py b/examples/v3arch/asyncore/manager/cmdgen/getnext-v3-over-ipv6.py
new file mode 100644
index 0000000..1856d80
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getnext-v3-over-ipv6.py
@@ -0,0 +1,82 @@
+"""
+Walk Agent over IPv6
+++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests with the following options:
+
+* with SNMPv3 with user 'usr-md5-none', MD5 auth and no privacy protocols
+* over IPv6/UDP
+* to an Agent at [::1]:161
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v3 -l authNoPriv -u usr-md5-none -A authkey1 -ObentU udp6:[::1]:161 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp6
+from pysnmp.entity.rfc3413 import cmdgen
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-md5-des, auth: MD5, priv NONE
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-md5-none', 'authNoPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv6
+config.addTransport(
+ snmpEngine,
+ udp6.domainName,
+ udp6.Udp6SocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp6.domainName, ('::1', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return
+ if errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for oid, val in varBindRow:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return True # signal dispatcher to continue
+
+# Prepare initial request to be sent
+cmdgen.NextCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1), None),
+ ((1,3,6,1,4,1,1), None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/getnext-v3-pull-subtree.py b/examples/v3arch/asyncore/manager/cmdgen/getnext-v3-pull-subtree.py
new file mode 100644
index 0000000..5edc744
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/getnext-v3-pull-subtree.py
@@ -0,0 +1,86 @@
+"""
+Pull MIB subtree
+++++++++++++++++
+
+Send a series of SNMP GETNEXT requests
+* with SNMPv3 with user 'usr-none-none', no auth and no privacy protocols
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in string form
+* stop whenever received OID goes out of initial prefix (it may be a table)
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v3 -l noAuthNoPriv -u usr-none-none -ObentU 195.218.195.228:161 1.3.6.1.2.1.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.proto import rfc1902
+
+# Initial OID prefix
+initialOID = rfc1902.ObjectName('1.3.6.1.2.1.1')
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-none-none, auth: none, priv: none
+config.addV3User(
+ snmpEngine, 'usr-none-none',
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-none-none', 'noAuthNoPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBindTable, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ return
+ if errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
+ )
+ )
+ return # stop on error
+ for varBindRow in varBindTable:
+ for oid, val in varBindRow:
+ if initialOID.isPrefixOf(oid):
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ else:
+ return False # signal dispatcher to stop
+ return True # signal dispatcher to continue
+
+# Prepare initial request to be sent
+cmdgen.NextCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ (initialOID, None) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/set-v1.py b/examples/v3arch/asyncore/manager/cmdgen/set-v1.py
new file mode 100644
index 0000000..55a8720
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/set-v1.py
@@ -0,0 +1,80 @@
+"""
+SET string and integer scalars
+++++++++++++++++++++++++++++++
+
+Send SNMP SET request with the following options:
+
+* with SNMPv1 with community name 'private'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in tuple form and an integer and string-typed values
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.proto import rfc1902
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv1 setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'private')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
+ # so we ignore noSuchName error here
+ elif errorStatus and errorStatus != 2:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.SetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,9,1,3,1), rfc1902.OctetString('my value')),
+ ((1,3,6,1,2,1,1,9,1,4,1), rfc1902.TimeTicks(123)) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/set-v2c.py b/examples/v3arch/asyncore/manager/cmdgen/set-v2c.py
new file mode 100644
index 0000000..9f7068f
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/set-v2c.py
@@ -0,0 +1,76 @@
+"""
+Set scalar value
+++++++++++++++++
+
+Send a SNMP SET request
+* with SNMPv2c with community name 'private'
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form and an integer-typed value
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v2c -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.4.1 t 123
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.proto import rfc1902
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv2c setup
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'private')
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ elif errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.SetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,9,1,4,1), rfc1902.TimeTicks(123)) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/cmdgen/set-v3.py b/examples/v3arch/asyncore/manager/cmdgen/set-v3.py
new file mode 100644
index 0000000..1c39d33
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/cmdgen/set-v3.py
@@ -0,0 +1,78 @@
+"""
+Set string value
+++++++++++++++++
+
+Send a SNMP SET request with the following options:
+
+* with SNMPv3 with user 'usr-sha-none', SHA auth and no privacy protocols
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form and a string-typed value
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v3 -l authNoPriv -u usr-sha-none -a SHA -A authkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my new value'
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import cmdgen
+from pysnmp.proto import rfc1902
+
+# Create SNMP engine instance
+snmpEngine = engine.SnmpEngine()
+
+#
+# SNMPv3/USM setup
+#
+
+# user: usr-sha-none, auth: SHA, priv none
+config.addV3User(
+ snmpEngine, 'usr-sha-none',
+ config.usmHMACSHAAuthProtocol, 'authkey1'
+)
+config.addTargetParams(snmpEngine, 'my-creds', 'usr-sha-none', 'authNoPriv')
+
+#
+# Setup transport endpoint and bind it with security settings yielding
+# a target name
+#
+
+# UDP/IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpSocketTransport().openClientMode()
+)
+config.addTargetAddr(
+ snmpEngine, 'my-router',
+ udp.domainName, ('195.218.195.228', 161),
+ 'my-creds'
+)
+
+# Error/response receiver
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ if errorIndication:
+ print(errorIndication)
+ elif errorStatus:
+ print('%s at %s' % (
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ )
+ )
+ else:
+ for oid, val in varBinds:
+ print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+
+# Prepare and send a request message
+cmdgen.SetCommandGenerator().sendVarBinds(
+ snmpEngine,
+ 'my-router',
+ None, '', # contextEngineId, contextName
+ [ ((1,3,6,1,2,1,1,9,1,3,1), rfc1902.OctetString('my new value')) ],
+ cbFun
+)
+
+# Run I/O dispatcher which would send pending queries and process responses
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-interfaces.py b/examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-interfaces.py
new file mode 100644
index 0000000..402f930
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-interfaces.py
@@ -0,0 +1,70 @@
+"""
+Serving multiple network interfaces
++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:162
+ over IPv4/UDP, listening at 127.0.0.1:2162
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v2c -c public 127.0.0.1:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+| $ snmpinform -v2c -c public 127.0.0.1:2162 123 1.3.6.1.6.3.1.1.5.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntfrcv
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4, first listening interface/port
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 162))
+)
+
+# UDP over IPv4, second listening interface/port
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (2,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 2162))
+)
+
+# SNMPv1/2c setup
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Callback function for receiving notifications
+def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
+ varBinds, cbCtx):
+ print('Notification from ContextEngineId "%s", ContextName "%s"' % (
+ contextEngineId.prettyPrint(),
+ contextName.prettyPrint()
+ )
+ )
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbFun)
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-transports.py b/examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-transports.py
new file mode 100644
index 0000000..31fcb2b
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/ntfrcv/v2c-multiple-transports.py
@@ -0,0 +1,71 @@
+"""
+Using multiple network transports
++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:162
+ over IPv6/UDP, listening at [::1]:162
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v1 -c public 127.0.0.1 1.3.6.1.4.1.20408.4.1.1.2 127.0.0.1 1 1 123 1.3.6.1.2.1.1.1.0 s test
+| $ snmptrap -v2c -c public udp6:[::1]:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+| $ snmpinform -v2c -c public 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp, udp6
+from pysnmp.entity.rfc3413 import ntfrcv
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 162))
+)
+
+# UDP over IPv6
+config.addTransport(
+ snmpEngine,
+ udp6.domainName,
+ udp6.Udp6Transport().openServerMode(('::1', 162))
+ )
+
+# SNMPv1/2c setup
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Callback function for receiving notifications
+def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
+ varBinds, cbCtx):
+ print('Notification from ContextEngineId "%s", ContextName "%s"' % (
+ contextEngineId.prettyPrint(),
+ contextName.prettyPrint()
+ )
+ )
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbFun)
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/manager/ntfrcv/v2c-observe-request-processing.py b/examples/v3arch/asyncore/manager/ntfrcv/v2c-observe-request-processing.py
new file mode 100644
index 0000000..ed44146
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/ntfrcv/v2c-observe-request-processing.py
@@ -0,0 +1,94 @@
+"""
+Observe SNMP engine internal operations
++++++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:162
+ over IPv6/UDP, listening at [::1]:162
+* registers its own execution observer to snmpEngine
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v1 -c public 127.0.0.1 1.3.6.1.4.1.20408.4.1.1.2 127.0.0.1 1 1 123 1.3.6.1.2.1.1.1.0 s test
+| $ snmptrap -v2c -c public udp6:[::1]:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+| $ snmpinform -v2c -c public 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp, udp6
+from pysnmp.entity.rfc3413 import ntfrcv
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Execution point observer setup
+
+# Register a callback to be invoked at specified execution point of
+# SNMP Engine and passed local variables at code point's local scope
+def requestObserver(snmpEngine, execpoint, variables, cbCtx):
+ print('Execution point: %s' % execpoint)
+ print('* transportDomain: %s' % '.'.join([str(x) for x in variables['transportDomain']]))
+ print('* transportAddress: %s' % '@'.join([str(x) for x in variables['transportAddress']]))
+ print('* securityModel: %s' % variables['securityModel'])
+ print('* securityName: %s' % variables['securityName'])
+ print('* securityLevel: %s' % variables['securityLevel'])
+ print('* contextEngineId: %s' % variables['contextEngineId'].prettyPrint())
+ print('* contextName: %s' % variables['contextName'].prettyPrint())
+ print('* PDU: %s' % variables['pdu'].prettyPrint())
+
+snmpEngine.observer.registerObserver(
+ requestObserver,
+ 'rfc3412.receiveMessage:request',
+ 'rfc3412.returnResponsePdu'
+)
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 162))
+)
+
+# UDP over IPv6
+config.addTransport(
+ snmpEngine,
+ udp6.domainName,
+ udp6.Udp6Transport().openServerMode(('::1', 162))
+ )
+
+# SNMPv1/2c setup
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Callback function for receiving notifications
+def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
+ varBinds, cbCtx):
+ print('Notification from ContextEngineId "%s", ContextName "%s"' % (
+ contextEngineId.prettyPrint(),
+ contextName.prettyPrint()
+ )
+ )
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbFun)
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.observer.unregisterObserver()
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/manager/ntfrcv/v2c-with-regexp-community-name.py b/examples/v3arch/asyncore/manager/ntfrcv/v2c-with-regexp-community-name.py
new file mode 100644
index 0000000..759bf98
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/ntfrcv/v2c-with-regexp-community-name.py
@@ -0,0 +1,88 @@
+"""
+Serve SNMP Community names defined by regexp
+++++++++++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with any SNMP community matching regexp '.*love.*'
+* over IPv4/UDP, listening at 127.0.0.1:162
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v1 -c rollover 127.0.0.1 1.3.6.1.4.1.20408.4.1.1.2 127.0.0.1 1 1 123 1.3.6.1.2.1.1.1.0 s test
+| $ snmpinform -v2c -c glove 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+
+The Notification Receiver below taps on v1/v2c SNMP security module
+to deliver certains values, normally internal to SNMP Engine, up to
+the context of user application.
+
+This script examines the value of CommunityName, as it came from peer SNMP
+Engine, and may modify it to match the only locally configured CommunityName
+'public'. This effectively makes NotificationReceiver accepting messages with
+CommunityName's, not explicitly configured to local SNMP Engine.
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntfrcv
+from pysnmp.proto.api import v2c
+import re
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Register a callback to be invoked at specified execution point of
+# SNMP Engine and passed local variables at execution point's local scope.
+# If at this execution point passed variables are modified, their new
+# values will be propagated back and used by SNMP Engine for securityName
+# selection.
+def requestObserver(snmpEngine, execpoint, variables, cbCtx):
+ if re.match('.*love.*', str(variables['communityName'])):
+ print('Rewriting communityName \'%s\' from %s into \'public\'' % (variables['communityName'], ':'.join([str(x) for x in variables['transportInformation'][1]])))
+ variables['communityName'] = variables['communityName'].clone('public')
+
+snmpEngine.observer.registerObserver(
+ requestObserver,
+ 'rfc2576.processIncomingMsg:writable'
+)
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 162))
+)
+
+# SNMPv1/2c setup
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Callback function for receiving notifications
+def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
+ varBinds, cbCtx):
+ print('Notification from ContextEngineId "%s", ContextName "%s"' % (
+ contextEngineId.prettyPrint(),
+ contextName.prettyPrint()
+ )
+ )
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbFun)
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/manager/ntfrcv/v2c-with-request-details.py b/examples/v3arch/asyncore/manager/ntfrcv/v2c-with-request-details.py
new file mode 100644
index 0000000..d8619de
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/ntfrcv/v2c-with-request-details.py
@@ -0,0 +1,69 @@
+"""
+Receive notifications noting peer address
++++++++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* over IPv4/UDP, listening at 127.0.0.1:162
+* use observer facility to pull lower-level request details from SNMP engine
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v2c -c public 127.0.0.1:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntfrcv
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4, first listening interface/port
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 162))
+)
+
+# SNMPv1/2c setup
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+# Callback function for receiving notifications
+def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
+ varBinds, cbCtx):
+ # Get an execution context...
+ execContext = snmpEngine.observer.getExecutionContext(
+ 'rfc3412.receiveMessage:request'
+ )
+
+ # ... and use inner SNMP engine data to figure out peer address
+ print('Notification from %s, ContextEngineId "%s", ContextName "%s"' % (
+ '@'.join([str(x) for x in execContext['transportAddress']]),
+ contextEngineId.prettyPrint(),
+ contextName.prettyPrint()
+ )
+ )
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbFun)
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/manager/ntfrcv/v3-multiple-users.py b/examples/v3arch/asyncore/manager/ntfrcv/v3-multiple-users.py
new file mode 100644
index 0000000..037062b
--- /dev/null
+++ b/examples/v3arch/asyncore/manager/ntfrcv/v3-multiple-users.py
@@ -0,0 +1,111 @@
+"""
+Multiple SNMP USM users
++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv3
+* with USM users:
+
+ * 'usr-md5-des', auth: MD5, priv DES, ContextEngineId: 8000000001020304
+ * 'usr-md5-none', auth: MD5, priv NONE, ContextEngineId: 8000000001020304
+ * 'usr-sha-aes128', auth: SHA, priv AES, ContextEngineId: 8000000001020304
+
+* over IPv4/UDP, listening at 127.0.0.1:162
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 -e 8000000001020304 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+| $ snmptrap -v3 -u usr-md5-none -l authNoPriv -A authkey1 -e 8000000001020304 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+| $ snmpinform -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+
+"""#
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntfrcv
+from pysnmp.proto.api import v2c
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openServerMode(('127.0.0.1', 162))
+)
+
+# SNMPv3/USM setup
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+
+# user: usr-md5-des, auth: MD5, priv DES, securityEngineId: 8000000001020304
+# this USM entry is used for TRAP receiving purposes
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1',
+ securityEngineId=v2c.OctetString(hexValue='8000000001020304')
+)
+
+# user: usr-md5-none, auth: MD5, priv NONE
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+
+# user: usr-md5-none, auth: MD5, priv NONE, securityEngineId: 8000000001020304
+# this USM entry is used for TRAP receiving purposes
+config.addV3User(
+ snmpEngine, 'usr-md5-none',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ securityEngineId=v2c.OctetString(hexValue='8000000001020304')
+)
+
+# user: usr-sha-aes128, auth: SHA, priv AES
+config.addV3User(
+ snmpEngine, 'usr-sha-aes128',
+ config.usmHMACSHAAuthProtocol, 'authkey1',
+ config.usmAesCfb128Protocol, 'privkey1'
+)
+# user: usr-sha-aes128, auth: SHA, priv AES, securityEngineId: 8000000001020304
+# this USM entry is used for TRAP receiving purposes
+config.addV3User(
+ snmpEngine, 'usr-sha-aes128',
+ config.usmHMACSHAAuthProtocol, 'authkey1',
+ config.usmAesCfb128Protocol, 'privkey1',
+ securityEngineId=v2c.OctetString(hexValue='8000000001020304')
+)
+
+# Callback function for receiving notifications
+def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
+ varBinds, cbCtx):
+ print('Notification from ContextEngineId "%s", ContextName "%s"' % (
+ contextEngineId.prettyPrint(),
+ contextName.prettyPrint()
+ )
+ )
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbFun)
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py
new file mode 100644
index 0000000..aa96c1e
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py
@@ -0,0 +1,88 @@
+"""
+Multiple SNMP Engines
++++++++++++++++++++++
+
+Send SNMP notifications in behalf of multiple independend SNMP engines
+using the following options:
+
+* with a single transport dispatcher and two independent SNMP engines
+* SNMPv2c and SNMPv3
+* with community name 'public' or USM username usr-md5-des
+* over IPv4/UDP
+* send IMFORM notification
+* to multiple Managers
+* with TRAP ID 'coldStart' specified as a MIB symbol
+* include managed object information specified as var-bind objects pair
+
+Within this script we have a single asynchronous TransportDispatcher
+and a single UDP-based transport serving two independent SNMP engines.
+We use a single instance of AsyncNotificationOriginator with each of
+SNMP Engines to communicate INFORM notification to remote systems.
+
+When we receive a [response] message from remote system we use
+a custom message router to choose what of the two SNMP engines
+data packet should be handed over. The selection criteria we
+employ here is based on peer's UDP port number. Other selection
+criterias are also possible.
+
+"""#
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
+
+# List of targets in the following format:
+# ( ( authData, transportTarget ), ... )
+targets = (
+ # 1-st target (SNMPv2c over IPv4/UDP)
+ ( CommunityData('public'),
+ UdpTransportTarget(('localhost', 1162)),
+ ContextData() ),
+ # 2-nd target (SNMPv3 over IPv4/UDP)
+ ( UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
+ UdpTransportTarget(('localhost', 162)),
+ ContextData() ),
+)
+
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbCtx):
+ snmpEngine = cbCtx
+ if errorIndication:
+ print('Notification %s for %s not sent: %s' % (sendRequestHandle, snmpEngine.snmpEngineID.prettyPrint(), errorIndication))
+ elif errorStatus:
+ print('Notification Receiver returned error for request %s, SNMP Engine %s: %s @%s' % (sendRequestHandle, snmpEngine.snmpEngineID.prettyPrint(), errorStatus, errorIndex))
+ else:
+ print('Notification %s for SNMP Engine %s delivered:' % (sendRequestHandle, snmpEngine.snmpEngineID.prettyPrint()))
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+# Instantiate the single transport dispatcher object
+transportDispatcher = AsyncoreDispatcher()
+
+# Setup a custom data routing function to select snmpEngine by transportDomain
+transportDispatcher.registerRoutingCbFun(
+ lambda td,ta,d: ta[1] % 3 and 'A' or 'B'
+)
+
+snmpEngineA = engine.SnmpEngine()
+snmpEngineA.registerTransportDispatcher(transportDispatcher, 'A')
+
+snmpEngineB = engine.SnmpEngine()
+snmpEngineB.registerTransportDispatcher(transportDispatcher, 'B')
+
+ntfOrg = AsyncNotificationOriginator()
+
+for authData, transportTarget, contextData in targets:
+ snmpEngine = transportTarget.getTransportInfo()[1][1] % 3 and \
+ snmpEngineA or snmpEngineB
+ sendPduHandle = ntfOrg.sendNotification(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ 'inform', # NotifyType
+ NotificationType(
+ ObjectIdentity('SNMPv2-MIB', 'coldStart')
+ ).addVarBinds( ( '1.3.6.1.2.1.1.1.0', 'my name' ) ),
+ cbInfo=(cbFun, snmpEngine)
+ )
+
+transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py
new file mode 100644
index 0000000..cfa2acd
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py
@@ -0,0 +1,60 @@
+"""
+Multiple concurrent notifications
++++++++++++++++++++++++++++++++++
+
+Send multiple SNMP notifications at once using the following options:
+
+* SNMPv2c and SNMPv3
+* with community name 'public' or USM username usr-md5-des
+* over IPv4/UDP
+* send INFORM notification
+* to multiple Managers
+* with TRAP ID 'coldStart' specified as a MIB symbol
+* include managed object information specified as var-bind objects pair
+
+"""#
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+
+# List of targets in the followin format:
+# ( ( authData, transportTarget ), ... )
+targets = (
+ # 1-st target (SNMPv2c over IPv4/UDP)
+ ( CommunityData('public'),
+ UdpTransportTarget(('localhost', 162)),
+ ContextData() ),
+ # 2-nd target (SNMPv3 over IPv4/UDP)
+ ( UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
+ UdpTransportTarget(('localhost', 162)),
+ ContextData() ),
+)
+
+def cbFun(snmpEngine, sendRequestHandle, errorIndication,
+ errorStatus, errorIndex, varBinds, cbctx):
+ if errorIndication:
+ print('Notification %s not sent: %s' % (sendRequestHandle, errorIndication))
+ elif errorStatus:
+ print('Notification Receiver returned error for %s: %s @%s' %
+ (sendRequestHandle, errorStatus, errorIndex))
+ else:
+ print('Notification %s delivered:' % sendRequestHandle)
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+
+snmpEngine = engine.SnmpEngine()
+
+ntfOrg = AsyncNotificationOriginator()
+
+for authData, transportTarget, contextData in targets:
+ sendPduHandle = ntfOrg.sendNotification(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ 'inform', # NotifyType
+ NotificationType(
+ ObjectIdentity('SNMPv2-MIB', 'coldStart')
+ ).addVarBinds( ( '1.3.6.1.2.1.1.1.0', 'my name' ) ),
+ cbInfo=(cbFun, None)
+ )
+
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py
index 6eebaa9..4d99a12 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py
@@ -1,42 +1,49 @@
-#
-# Notification Originator
-#
-# 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
-# * perform response OIDs and values resolution at MIB
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- sendNotification(SnmpEngine(),
- CommunityData('public'),
- UdpTransportTarget(('localhost', 162)),
- ContextData(),
- 'inform',
- NotificationType(
- ObjectIdentity('SNMPv2-MIB', 'coldStart')
- ).addVarBinds(
- ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 0), 'my system') )
- ),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
+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/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py
index 071c336..0c75c21 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py
@@ -1,46 +1,50 @@
-#
-# Notification Originator
-#
-# 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.
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-from pysnmp.proto import rfc1902
-
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- sendNotification(SnmpEngine(),
- UsmUserData('usr-md5-none', 'authkey1'),
- UdpTransportTarget(('localhost', 162)),
- ContextData(
- rfc1902.OctetString(hexValue='8000000004030201')
- ),
- 'inform',
- NotificationType(
- ObjectIdentity('1.3.6.1.6.3.1.1.5.2')
- ),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
+
+errorIndication, errorStatus, errorIndex, varBinds = next(
+ sendNotification(SnmpEngine(),
+ UsmUserData('usr-md5-none', 'authkey1'),
+ UdpTransportTarget(('localhost', 162)),
+ ContextData(
+ rfc1902.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/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py
index ed87fdc..1b3e1f8 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py
@@ -1,43 +1,48 @@
-#
-# Notification Originator
-#
-# 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.
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- 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')
- ),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
+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/v3arch/asyncore/oneliner/agent/ntforg/inform-v3.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3.py
index 2996eb5..161427a 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/inform-v3.py
@@ -1,44 +1,49 @@
-##
-# Notification Originator
-#
-# Send SNMP 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'
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-from pysnmp.proto import rfc1902
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- 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'),
- rfc1902.OctetString('system name')) )
- ),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
+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/v3arch/asyncore/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py
new file mode 100644
index 0000000..60c557a
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py
@@ -0,0 +1,51 @@
+"""
+Multiple concurrent queries
++++++++++++++++++++++++++++
+
+Send a bunch of different SNMP Notifications to different peers all at once,
+wait for responses asynchronously:
+
+* SNMPv1 and SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* send TRAP notification
+* to multiple Managers
+* with TRAP ID 'coldStart' specified as a MIB symbol
+* include managed object information specified as var-bind objects pair
+
+"""#
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+
+# List of targets in the followin format:
+# ( ( authData, transportTarget ), ... )
+targets = (
+ # 1-st target (SNMPv1 over IPv4/UDP)
+ ( CommunityData('public', mpModel=0),
+ UdpTransportTarget(('localhost', 162)),
+ ContextData() ),
+ # 2-nd target (SNMPv2c over IPv4/UDP)
+ ( CommunityData('public'),
+ UdpTransportTarget(('localhost', 162)),
+ ContextData() ),
+)
+
+snmpEngine = SnmpEngine()
+
+ntfOrg = AsyncNotificationOriginator()
+
+for authData, transportTarget, contextData in targets:
+ ntfOrg.sendNotification(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ 'trap', # NotifyType
+ NotificationType(
+ ObjectIdentity('SNMPv2-MIB', 'coldStart')
+ ).addVarBinds(
+ ( ObjectName('1.3.6.1.2.1.1.1.0'),
+ OctetString('my name') )
+ )
+ )
+
+snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-custom-values.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-custom-values.py
index 1d2b825..85e130b 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-custom-values.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-custom-values.py
@@ -1,36 +1,50 @@
-#
-# Notification Originator
-#
-# Send SNMP notification using the following options:
-#
-# * 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'
-#
+"""
+Custom SNMPv1 TRAP
+++++++++++++++++++
+
+Send SNMPv1 TRAP through unified SNMPv3 message processing framework.
+
+Original v1 TRAP fields are mapped into dedicated variable-bindings,
+(see `RFC2576 <https://www.ietf.org/rfc/rfc2576.txt>`_) 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.entity.rfc3413.oneliner.ntforg import *
-from pysnmp.proto import rfc1902
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- 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', rfc1902.OctetString('my system'))
- )):
- if errorIndication:
- print(errorIndication)
+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', rfc1902.OctetString('my system'))
+ )
+ )
+)
+if errorIndication:
+ print(errorIndication)
diff --git a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-default-values.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-default-values.py
index a704146..5ad5ef7 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-default-values.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v1-with-default-values.py
@@ -1,34 +1,46 @@
-#
-# Notification Originator
-#
-# Send SNMP notification 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'
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-from pysnmp.proto import rfc1902
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- 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', rfc1902.OctetString('my system'))
- )):
- if errorIndication:
- print(errorIndication)
+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', rfc1902.OctetString('my system'))
+ )
+ )
+)
+if errorIndication:
+ print(errorIndication)
diff --git a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py
index b243f43..a328a2c 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py
@@ -1,27 +1,37 @@
-#
-# Notification Originator
-#
-# Send SNMP notification using the following options:
-#
-# * 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
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- sendNotification(SnmpEngine(),
- CommunityData('public'),
- UdpTransportTarget(('localhost', 162)),
- ContextData(),
- 'trap',
- NotificationType(
- ObjectIdentity('SNMPv2-MIB', 'coldStart')
- )):
- if errorIndication:
- print(errorIndication)
+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/v3arch/asyncore/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py
index bbc9194..f03948f 100644
--- a/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py
+++ b/examples/v3arch/asyncore/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py
@@ -1,37 +1,45 @@
-#
-# Notification Originator
-#
-# 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.
-#
+"""
+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.entity.rfc3413.oneliner.ntforg import *
-from pysnmp.proto.rfc1902 import OctetString
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in \
- 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)
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py
index 85586ed..96ce80f 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py
@@ -1,52 +1,54 @@
-#
-# Asynchronous Command Generator
-#
-# Send SNMP GET requests using multiple independend SNMP engines
-# with the following options:
-#
-# * 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
-#
-# Within this script we have a single asynchronous TransportDispatcher
-# and a single UDP-based transport serving two independent SNMP engines.
-# We use a single instance of AsyncCommandGenerator with each of
-# SNMP Engines to comunicate GET command request to remote systems.
-#
-# When we receive a [response] message from remote system we use
-# a custom message router to choose what of the two SNMP engines
-# data packet should be handed over. The selection criteria we
-# employ here is based on peer's UDP port number. Other selection
-# criterias are also possible.
-#
-from pysnmp.entity.rfc3413.oneliner import cmdgen
-from pysnmp.entity import engine
+"""
+Multiple SNMP engines
++++++++++++++++++++++
+
+Send multiple SNMP GET requests to multiple peers using multiple
+independend SNMP engines. Deal with peers asynchronously. SNMP options
+are:
+
+* 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
+
+Within this script we have a single asynchronous TransportDispatcher
+and a single UDP-based transport serving two independent SNMP engines.
+We use a single instance of AsyncCommandGenerator with each of
+SNMP Engines to comunicate GET command request to remote systems.
+
+When we receive a [response] message from remote system we use
+a custom message router to choose what of the two SNMP engines
+data packet should be handed over. The selection criteria we
+employ here is based on peer's UDP port number. Other selection
+criterias are also possible.
+
+"""#
+from pysnmp.entity.rfc3413.oneliner.cmdgen import *
from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
-# List of targets in the followin format:
+# List of targets in the following format:
# ( ( authData, transportTarget, varNames ), ... )
targets = (
# 1-st target (SNMPv1 over IPv4/UDP)
- ( cmdgen.CommunityData('public', mpModel=0),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
+ ( 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)
- ( cmdgen.CommunityData('public'),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 1161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
+ ( CommunityData('public'),
+ UdpTransportTarget(('demo.snmplabs.com', 1161)),
+ ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
# 3-nd target (SNMPv3 over IPv4/UDP)
- ( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 2161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) )
+ ( UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
+ UdpTransportTarget(('demo.snmplabs.com', 2161)),
+ ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) )
# N-th target
# ...
)
@@ -61,20 +63,16 @@ def cbFun(snmpEngine, sendRequestHandle, errorIndication,
if errorIndication:
print(errorIndication)
return 1
- if errorStatus:
+ elif errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex)-1][0] or '?'
)
)
return 1
-
- for oid, val in varBinds:
- if val is None:
- print(oid.prettyPrint())
- else:
- print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
-
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
# Instantiate the single transport dispatcher object
transportDispatcher = AsyncoreDispatcher()
@@ -84,19 +82,19 @@ transportDispatcher.registerRoutingCbFun(
lambda td,ta,d: ta[1] % 3 and 'A' or 'B'
)
-snmpEngineA = engine.SnmpEngine()
+snmpEngineA = SnmpEngine()
snmpEngineA.registerTransportDispatcher(transportDispatcher, 'A')
-snmpEngineB = engine.SnmpEngine()
+snmpEngineB = SnmpEngine()
snmpEngineB.registerTransportDispatcher(transportDispatcher, 'B')
-cmdGen = cmdgen.AsyncCommandGenerator()
+cmdGen = AsyncCommandGenerator()
for authData, transportTarget, varBinds in targets:
snmpEngine = transportTarget.getTransportInfo()[1][1] % 3 and \
snmpEngineA or snmpEngineB
cmdGen.getCmd(
- snmpEngine, authData, transportTarget, cmdgen.ContextData(), varBinds,
+ snmpEngine, authData, transportTarget, ContextData(), varBinds,
(cbFun, (snmpEngine, authData, transportTarget))
)
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py
index e50a54b..f5c0569 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py
@@ -1,50 +1,52 @@
-#
-# Asynchronous Command Generator
-#
-# Send a bunch of SNMP GET requests all at once using the following options:
-#
-# * 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 pysnmp.entity import engine
-from pysnmp.entity.rfc3413.oneliner import cmdgen
+"""
+Multiple concurrent queries
++++++++++++++++++++++++++++
+
+Send a bunch of different SNMP GET requests to different peers all at once,
+wait for responses asynchronously:
+
+* 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 pysnmp.entity.rfc3413.oneliner.cmdgen import *
# List of targets in the followin format:
# ( ( authData, transportTarget, varNames ), ... )
targets = (
# 1-st target (SNMPv1 over IPv4/UDP)
- ( cmdgen.CommunityData('public', mpModel=0),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
+ ( 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)
- ( cmdgen.CommunityData('public'),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
+ ( 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.
- ( cmdgen.CommunityData('public'),
- cmdgen.UdpTransportTarget(('localhost', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysContact', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysName', 0))) ),
+ ( CommunityData('public'),
+ UdpTransportTarget(('localhost', 161)),
+ ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysContact', 0)),
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 0))) ),
# 4-nd target (SNMPv3 over IPv4/UDP)
- ( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
+ ( 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)
- ( cmdgen.UsmUserData('usr-md5-none', 'authkey1'),
- cmdgen.Udp6TransportTarget(('::1', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
+ ( UsmUserData('usr-md5-none', 'authkey1'),
+ Udp6TransportTarget(('::1', 161)),
+ ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) )) ),
# N-th target
# ...
)
@@ -52,36 +54,32 @@ targets = (
# Wait for responses or errors
def cbFun(snmpEngine, sendRequestHandle, errorIndication,
errorStatus, errorIndex, varBinds, cbCtx):
- (authData, transportTarget) = cbCtx
+ authData, transportTarget = cbCtx
print('%s via %s' % (authData, transportTarget))
if errorIndication:
print(errorIndication)
- return 1
- if errorStatus:
+ return True
+ elif errorStatus:
print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
+ errorStatus.prettyPrint(),
+ errorIndex and varBinds[int(errorIndex)-1][0] or '?'
)
)
- return 1
-
- for oid, val in varBinds:
- if val is None:
- print(oid.prettyPrint())
- else:
- print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ return True
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
-snmpEngine = engine.SnmpEngine()
+snmpEngine = SnmpEngine()
-cmdGen = cmdgen.AsyncCommandGenerator()
+cmdGen = AsyncCommandGenerator()
# Submit GET requests
for authData, transportTarget, varNames in targets:
cmdGen.getCmd(
- snmpEngine, authData, transportTarget, cmdgen.ContextData(), varNames,
+ snmpEngine, authData, transportTarget, ContextData(), varNames,
# User-space callback function and its context
- (cbFun, (authData, transportTarget)),
- lookupNames=True, lookupValues=True
+ (cbFun, (authData, transportTarget))
)
snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py
new file mode 100644
index 0000000..47630ea
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/get-v1.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v1.py
index aca4129..2e9c298 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v1.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v1.py
@@ -1,35 +1,37 @@
-#
-# Command Generator
-#
-# 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,
-# * one in label and another in MIB symbol form
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in getCmd(SnmpEngine(),
- CommunityData('public', mpModel=0),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-custom-timeout-and-retries.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-custom-timeout-and-retries.py
index d9fc491..1439aeb 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-custom-timeout-and-retries.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-custom-timeout-and-retries.py
@@ -1,49 +1,53 @@
-#
-# Command Generator
-#
-# 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.
-#
+"""
+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 demo.snmplabs.com 1.3.6.1.2.1.1.1.0
+
+"""#
from pysnmp.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in getCmd(SnmpEngine(),
- CommunityData('public'),
- UdpTransportTarget(
- ('demo.snmplabs.com', 161), timeout=1.5, retries=0
- ),
- ContextData(),
- ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+errorIndication, errorStatus, errorIndex, varBinds = next(
+ getCmd(SnmpEngine(),
+ CommunityData('public'),
+ UdpTransportTarget(
+ ('demo.snmplabs.com', 161), timeout=1.5, 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/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py
index fba316f..e994dba 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py
@@ -1,37 +1,39 @@
-#
-# Command Generator
-#
-# 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 attached MIB compiler non-default ASN.1 MIB source
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in 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@')
- ),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c.py
index 5fe5bfe..dcc4ccf 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v2c.py
@@ -1,34 +1,39 @@
-#
-# Command Generator
-#
-# 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in 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'))):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv-sha-aes128.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv-sha-aes128.py
new file mode 100644
index 0000000..85a0399
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv-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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv.py
new file mode 100644
index 0000000..2c53b29
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-auth-priv.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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-multiple-calls.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-multiple-calls.py
new file mode 100644
index 0000000..116d99f
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-multiple-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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-noauth-nopriv.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-noauth-nopriv.py
new file mode 100644
index 0000000..976e0f4
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-noauth-nopriv.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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py
index 716d1e9..9499a38 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py
@@ -1,36 +1,42 @@
-#
-# Command Generator
-#
-# 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: one passed as a ObjectIdentity object while others are
-# * in string form
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in 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'))):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-index.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-index.py
index e83e0d2..84b9105 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-index.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-index.py
@@ -1,35 +1,41 @@
-#
-# Command Generator
-#
-# 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 MIB object
-# * perform response OIDs and values resolution at MIB
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in getCmd(SnmpEngine(),
- UsmUserData('usr-none-none'),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1)),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py
index 7b78a35..ebc2b0c 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py
@@ -1,40 +1,46 @@
-#
-# Command Generator
-#
-# 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in 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)
- )):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-custom-security-name.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-custom-security-name.py
index 4770c5d..ae5e656 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-custom-security-name.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-custom-security-name.py
@@ -1,40 +1,38 @@
-#
-# Command Generator
-#
-# 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.
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in 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'))):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py
index c01a61d..6e0d1c5 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py
@@ -1,33 +1,38 @@
-#
-# Command Generator
-#
-# 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in getCmd(SnmpEngine(),
- UsmUserData('usr-md5-none', 'authkey1'),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 1))):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-specific-engine-id.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-specific-engine-id.py
index ca1d1fe..18b3a47 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-specific-engine-id.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/get-v3-with-specific-engine-id.py
@@ -1,18 +1,23 @@
-#
-# Command Generator
-#
-# 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
snmpEngine = SnmpEngine()
@@ -38,10 +43,10 @@ snmpEngine.observer.registerObserver(
authData = UsmUserData('non-existing-user')
-for errorIndication, errorStatus, errorIndex, \
- varBinds in getCmd(snmpEngine, authData,
- transportTarget, ContextData()):
- break
+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
@@ -60,22 +65,22 @@ print('Remote securityEngineId = %s' % securityEngineId.prettyPrint())
authData = UsmUserData('usr-md5-none', 'authkey1',
securityEngineId=securityEngineId)
-for errorIndication, errorStatus, errorIndex, \
- varBinds in getCmd(snmpEngine, authData, \
- transportTarget, ContextData(), \
- ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))):
- break
+errorIndication, errorStatus, errorIndex, varBinds = next(
+ getCmd(snmpEngine,
+ authData,
+ transportTarget,
+ ContextData(),
+ ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')))
+)
-# Check for errors and print out results
if errorIndication:
print(errorIndication)
-else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+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()))
+ )
+else:
+ for name, val in varBinds:
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c-limiting-number-of-rows.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c-limiting-number-of-rows.py
new file mode 100644
index 0000000..ac4887a
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c-limiting-number-of-rows.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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c.py
index 0bed0f0..bf167e4 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v2c.py
@@ -1,15 +1,23 @@
-#
-# Command Generator
-#
-# Send SNMP GETBULK request 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -20,19 +28,19 @@ for errorIndication, \
ContextData(),
0, 25,
ObjectType(ObjectIdentity('1.3.6.1.2.1.2.2')),
- ObjectType(ObjectIdentity('1.3.6.1.2.1.2.3'))):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('1.3.6.1.2.1.2.3')),
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-limiting-number-of-packets.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-limiting-number-of-packets.py
new file mode 100644
index 0000000..4cb303e
--- /dev/null
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-limiting-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.entity.rfc3413.oneliner.cmdgen 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/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py
index 9b255f3..6a09a13 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py
@@ -1,16 +1,25 @@
-#
-# Command Generator
-#
-# Send SNMP GETBULK 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
-# * 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 OR maxRows == 20
-# * perform response OIDs and values resolution at MIB
-#
+"""
+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-none -A authkey1 -X privkey1 \
+| -Cn1, -Cr25 \
+| demo.snmplabs.com \
+| IP-MIB::ipAdEntAddr \
+| IP-MIB::ipAddrEntry
+
+"""#
from pysnmp.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -22,19 +31,18 @@ for errorIndication, \
1, 25,
ObjectType(ObjectIdentity('IP-MIB', 'ipAdEntAddr')),
ObjectType(ObjectIdentity('IP-MIB', 'ipAddrEntry')),
- lookupNames=True, lookupValues=True, maxRows=20):
- # Check for errors and print out results
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py
index 5d1eb81..9c97465 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py
@@ -1,17 +1,23 @@
-#
-# Command Generator
-#
-# Send SNMP GETBULK 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 all OIDs past TCP-MIB::tcpConnTable
-# * TCP-MIB will be searched by a user-specified path
-# * run till end-of-mib condition is reported by Agent OR maxRows == 100 OR
-# maxCalls == 10 request-response interactions occur
-# * ignoring non-increasing OIDs whenever reported by Agent
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -21,22 +27,19 @@ for errorIndication, \
UdpTransportTarget(('demo.snmplabs.com', 161)),
ContextData(),
0, 50,
- ObjectType(ObjectIdentity('TCP-MIB', 'tcpConnTable').addMibSource('/tmp/mibs')),
- maxRows=100, maxCalls=10,
- lexicographicMode=True,
- ignoreNonIncreasingOid=True):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('TCP-MIB', 'tcpConnTable').addMibSource('/opt/mibs/pysnmp').addMibSource('python_packaged_mibs')),
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py
index b1304ae..a77dc49 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py
@@ -1,40 +1,42 @@
-##
-# Asynchronous Command Generator
-#
-# Send a bunch of SNMP GETNEXT requests all at once using the following options:
-#
-# * 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 multiple MIB subtrees and tables
-#
-from pysnmp.entity import engine
-from pysnmp.entity.rfc3413.oneliner import cmdgen
+"""
+Walk multiple Agents at once
+++++++++++++++++++++++++++++
+
+Iterate over MIBs of multiple SNMP Agents asynchronously using the
+following options:
+
+* 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 multiple MIB subtrees and tables
+
+"""#
+from pysnmp.entity.rfc3413.oneliner.cmdgen import *
# List of targets in the followin format:
# ( ( authData, transportTarget, varNames ), ... )
targets = (
# 1-st target (SNMPv1 over IPv4/UDP)
- ( cmdgen.CommunityData('public', mpModel=0),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('1.3.6.1.2.1')),
- cmdgen.ObjectType(cmdgen.ObjectIdentity('1.3.6.1.3.1')) ) ),
+ ( CommunityData('public', mpModel=0),
+ UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ( ObjectType(ObjectIdentity('1.3.6.1.2.1')),
+ ObjectType(ObjectIdentity('1.3.6.1.3.1')) ) ),
# 2-nd target (SNMPv2c over IPv4/UDP)
- ( cmdgen.CommunityData('public'),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('1.3.6.1.4.1')), ) ),
+ ( CommunityData('public'),
+ UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ( ObjectType(ObjectIdentity('1.3.6.1.4.1')), ) ),
# 3-nd target (SNMPv3 over IPv4/UDP)
- ( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
- cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('SNMPv2-MIB', 'system')), ) ),
+ ( UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
+ UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ( ObjectType(ObjectIdentity('SNMPv2-MIB', 'system')), ) ),
# 4-th target (SNMPv3 over IPv6/UDP)
- ( cmdgen.UsmUserData('usr-md5-none', 'authkey1'),
- cmdgen.Udp6TransportTarget(('::1', 161)),
- ( cmdgen.ObjectType(cmdgen.ObjectIdentity('IF-MIB', 'ifTable')), ) )
+ ( UsmUserData('usr-md5-none', 'authkey1'),
+ Udp6TransportTarget(('::1', 161)),
+ ( ObjectType(ObjectIdentity('IF-MIB', 'ifTable')), ) )
# N-th target
# ...
)
@@ -47,44 +49,38 @@ def cbFun(snmpEngine, sendRequestHandle, errorIndication,
if errorIndication:
print(errorIndication)
return
- if errorStatus:
+ elif errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1][0] or '?'
)
)
return
- varBindTableRow = varBindTable[-1]
- for idx in range(len(varBindTableRow)):
- name, val = varBindTableRow[idx]
- if val is not None and varBindHead[idx] <= name:
- # still in table
- break
else:
- print('went out of table at %s' % (name, ))
- return
+ for idx, varBind in enumerate(varBindTable[-1]):
+ if varBind[1] is not None and varBindHead[idx] <= varBind[0]:
+ break # still in table
+ else:
+ print('went out of table at %s' % (name, ))
+ return
- for varBindRow in varBindTable:
- for oid, val in varBindRow:
- if val is None:
- print(oid.prettyPrint())
- else:
- print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
+ for varBindRow in varBindTable:
+ for varBind in varBindRow:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
- return True # continue table retrieval
+ return True # continue table retrieval
-snmpEngine = engine.SnmpEngine()
+snmpEngine = SnmpEngine()
-cmdGen = cmdgen.AsyncCommandGenerator()
+cmdGen = AsyncCommandGenerator()
# Submit initial GETNEXT requests and wait for responses
for authData, transportTarget, varBinds in targets:
varBindHead = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds ) ]
cmdGen.nextCmd(
- snmpEngine, authData, transportTarget, cmdgen.ContextData(), varBinds,
+ snmpEngine, authData, transportTarget, ContextData(), varBinds,
# User-space callback function and its context
- (cbFun, (varBindHead, authData, transportTarget)),
- lookupNames=True, lookupValues=True
+ (cbFun, (varBindHead, authData, transportTarget))
)
snmpEngine.transportDispatcher.runDispatcher()
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py
index 0367eb3..1d459ef 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py
@@ -1,29 +1,33 @@
-#
-# GETNEXT Command Generator Application
-#
-# Perform SNMP GETNEXT operation with the following options:
-#
-# with SNMPv1, community 'public'
-# over IPv4/UDP
-# to an Agent at demo.snmplabs.com:161
-# two columns of the IF-MIB::ifEntry table
-# search for pysnmp MIBs at specific filesystem location
-# stop when response OIDs leave the scopes of initial OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v1 -c public -ObentU demo.snmplabs.com IF-MIB::ifDescr IF-MIB::ifType
-#
-# The pysnmp engine maintains its own MIB search path which is usued
-# for searching for MIB modules by name. By default pysnmp will search
-# its built-in MIB repository (pysnmp.smi.mibs.instances, pysnmp.smi.mibs)
-# and pysnmp-mibs package (pysnmp_mibs). Those two entries are normally
-# found relative to $PYTHONPATH. Besides searching MIBs as Python modules
-# (which could be egg-ed or not), pysnmp can also search for stand-alone
-# files in given directories. The latter could be specified by
-# ObjectIdentity.addMibSource() calls. New search path entries are added
-# in front of existing ones in search path.
-#
+"""
+Search PySNMP MIBs at custom location
++++++++++++++++++++++++++++++++++++++
+
+Perform SNMP GETNEXT operation and resolve received var-binds with
+PySNMP MIB(s) found at a custom location. Use the following SNMP options:
+
+* with SNMPv1, community 'public'
+* over IPv4/UDP
+* to an Agent at demo.snmplabs.com:161
+* two columns of the IF-MIB::ifEntry table
+* search for pysnmp MIBs at specific filesystem location
+* stop when response OIDs leave the scopes of initial OIDs
+
+The pysnmp engine maintains its own MIB search path which is used
+for searching for MIB modules by name. By default pysnmp will search
+its built-in MIB repository (pysnmp.smi.mibs.instances, pysnmp.smi.mibs)
+and pysnmp-mibs package (pysnmp_mibs). Those two entries are normally
+found relative to $PYTHONPATH. Besides searching MIBs as Python modules
+(which could be egg-ed or not), pysnmp can also search for stand-alone
+files in given directories. The latter could be specified by
+ObjectIdentity.addMibSource() calls. New search path entries are added
+in front of existing ones in search path.
+
+Functionally similar to:
+
+| $ snmpwalk -v1 -c public -ObentU demo.snmplabs.com \
+| IF-MIB::ifDescr IF-MIB::ifType
+
+"""#
from pysnmp.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -34,19 +38,18 @@ for errorIndication, \
ContextData(),
ObjectType(ObjectIdentity('IF-MIB', 'ifDescr').addMibSource('/tmp/mymibs')),
ObjectType(ObjectIdentity('IF-MIB', 'ifType')),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1.py
index 1c3a998..7530a39 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v1.py
@@ -1,18 +1,31 @@
-#
-# Command Generator
-#
-# Send SNMP GETNEXT request 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
- errorStatus, errorIndex, \
+ errorStatus, \
+ errorIndex, \
varBinds in nextCmd(SnmpEngine(),
CommunityData('public', mpModel=0),
UdpTransportTarget(('demo.snmplabs.com', 161)),
@@ -22,19 +35,19 @@ for errorIndication, \
ObjectType(ObjectIdentity('IF-MIB', 'ifMtu')),
ObjectType(ObjectIdentity('IF-MIB', 'ifSpeed')),
ObjectType(ObjectIdentity('IF-MIB', 'ifPhysAddress')),
- ObjectType(ObjectIdentity('IF-MIB', 'ifType'))):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('IF-MIB', 'ifType')),
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c-with-mib-resolution.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c-with-mib-resolution.py
index e59b07b..a79fefb 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c-with-mib-resolution.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c-with-mib-resolution.py
@@ -1,25 +1,24 @@
-#
-# GETNEXT Command Generator Application
-#
-# 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
-# * resolve response OIDs and values into human-freidly form
-# * stop when response OIDs leave the scopes of initial OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v2c -c public demo.snmplabs.com 1.3.6.1.2.1.1
-#
-# The lookupNames and lookupValues keyword arguments will make pysnmp
-# trying to resolve OIDs and values, in response variable-bindings,
-# into human-friendly form. If response OIDs do not belong to any of
-# currently loaded MIBs, unresolved OIDs and values will still be
-# returned.
-#
+"""
+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 lookupNames and lookupValues 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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -29,19 +28,18 @@ for errorIndication, \
UdpTransportTarget(('demo.snmplabs.com', 161)),
ContextData(),
ObjectType(ObjectIdentity('1.3.6.1.2.1.1')),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
+ lookupMib=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c.py
index 178cd09..514a6ce 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v2c.py
@@ -1,14 +1,21 @@
-#
-# Command Generator
-#
-# Send 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
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -18,19 +25,19 @@ for errorIndication, \
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'))):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('1.3.6.1.2.1.2.2.1.3')),
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py
index 01c74be..4a0877d 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py
@@ -1,17 +1,23 @@
-#
-# Command Generator
-#
-# Send 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 columns of the IF-MIB::ifEntry table
-# * stop when response OIDs leave the scopes of the table
-# * perform response OIDs and values resolution at MIB
-#
-# make sure IF-MIB.py is in search path
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -20,20 +26,18 @@ for errorIndication, \
UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
Udp6TransportTarget(('::1', 161)),
ContextData(),
- ObjectType(ObjectIdentity('IF-MIB', 'ifEntry')),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('1.3.6').loadMibs())):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py
index 658f6fc..4c0568a 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py
@@ -1,15 +1,21 @@
-#
-# Command Generator
-#
-# Send 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
-# * stop when response OIDs leave the scopes of the table
-# * perform response values resolution at MIB
-#
+"""
+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
+* stop when response OIDs leave the scopes of the table
+
+Functionally similar to:
+
+| $ snmpwalk -v3 -lauthPriv -u usr-md5-none -A authkey1 -X privkey1 \
+| demo.snmplabs.com IF-MIB::
+
+"""#
from pysnmp.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -18,20 +24,19 @@ for errorIndication, \
UsmUserData('usr-md5-none', 'authkey1'),
UdpTransportTarget(('demo.snmplabs.com', 161)),
ContextData(),
- ObjectType(ObjectIdentity('IF-MIB', '')),
- lookupValues=True):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('IF-MIB')),
+ lexicographicMode=False):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py
index 99eba51..19d7950 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py
@@ -1,17 +1,23 @@
-#
-# Command Generator
-#
-# Send SNMP GETNEXT requests using the following options:
-#
-# * with SNMPv3, user 'usr-sha-aes128', SHA auth, AES128 privacy
-# * over Local Domain Sockets
-# * to an Agent at demo.snmplabs.com:161
-# * for all OIDs past IF-MIB (load up all MIBs in search path)
-# * run till end-of-mib condition is reported by Agent OR maxRows == 100
-# * ignoring non-increasing OIDs whenever reported by Agent
-#
-# make sure IF-MIB.py is search path
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
for errorIndication, \
@@ -22,21 +28,19 @@ for errorIndication, \
privProtocol=usmAesCfb128Protocol),
UdpTransportTarget(('demo.snmplabs.com', 161)),
ContextData(),
- ObjectType(ObjectIdentity('IF-MIB', '').loadMibs()),
- lexicographicMode=True, maxRows=100,
- ignoreNonIncreasingOid=True):
- # Check for errors and print out results
+ ObjectType(ObjectIdentity('SNMPv2-MIB')),
+ maxRows=100, ignoreNonIncreasingOid=True):
+
if errorIndication:
print(errorIndication)
break
- else:
- if errorStatus:
- print('%s at %s' % (
- errorStatus.prettyPrint(),
- errorIndex and varBinds[int(errorIndex)-1][0] or '?'
- )
+ 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 ]))
+ )
+ break
+ else:
+ for varBind in varBinds:
+ print(' = '.join([ x.prettyPrint() for x in varBind ]))
diff --git a/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v1-multiple-values.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v1-multiple-values.py
index bba4a84..9b9fae7 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v1-multiple-values.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v1-multiple-values.py
@@ -1,36 +1,49 @@
-#
-# Command Generator
-#
-# Send SNMP SET request using the following options:
-#
-# * with SNMPv1, community 'public'
-# * over IPv4/UDP
-# * to an Agent at demo.snmplabs.com:161
-# * setting two OIDs to new values (types explicitly specified)
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-from pysnmp.proto import rfc1902
-
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in setCmd(SnmpEngine(),
- CommunityData('public', mpModel=0),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ('1.3.6.1.2.1.1.9.1.2.1', rfc1902.ObjectName('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', rfc1902.OctetString('new system name'))):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+
+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/v3arch/asyncore/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py
index 46d4c5e..62f7595 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py
@@ -1,36 +1,39 @@
-#
-# Command Generator
-#
-# 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)
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in setCmd(SnmpEngine(),
- CommunityData('public'),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ObjectType(
- ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1),
- 'new system name'
- )):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py
index 9c5b20f..f017882 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py
@@ -1,43 +1,45 @@
-#
-# Command Generator
-#
-# 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)
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-from pysnmp.proto import rfc1902
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in setCmd(SnmpEngine(),
- UsmUserData('usr-md5-none', 'authkey1'),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(
- contextEngineId=rfc1902.OctetString(hexValue='80004fb805636c6f75644dab22cc'),
- contextName='da761cfc8c94d3aceef4f60f049105ba'
- ),
- ObjectType(
- ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1),
- 'new system name'
- )):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py
index 22d165d..46ef275 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py
@@ -1,44 +1,43 @@
-#
-# Command Generator
-#
-# 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 taken from MIB)
-#
+"""
+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.entity.rfc3413.oneliner.cmdgen import *
-from pysnmp.proto import rfc1902
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in setCmd(SnmpEngine(),
- UsmUserData(
- 'usr-md5-des', 'authkey1', 'privkey1',
- securityEngineId=rfc1902.OctetString(
- hexValue='80004fb805636c6f75644dab22cc'
- )
- ),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ObjectType(
- ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1),
- 'new system name'
- )):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+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/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py
index 379a0dd..e72587d 100644
--- a/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py
+++ b/examples/v3arch/asyncore/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py
@@ -1,39 +1,41 @@
-#
-# Command Generator
-#
-# Send SNMP SET request using the following options:
-#
-# * with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
-# * over IPv4/UDP
-# * to an Agent at demo.snmplabs.com:161
-# * setting SNMPv2-MIB::sysName.0 to new value (type taken from MIB)
-# * perform response OIDs and values resolution at MIB
-#
+"""
+Coerce value to SET to MIB spec
++++++++++++++++++++++++++++++++
+
+
+Send SNMP SET request using the following options:
+
+* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
+* 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 -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 \
+| demo.snmplabs.com SNMPv2-MIB::sysORDescr.1 = "new system name"
+|
+
+"""#
from pysnmp.entity.rfc3413.oneliner.cmdgen import *
-from pysnmp.proto import rfc1902
-
-for errorIndication, \
- errorStatus, errorIndex, \
- varBinds in setCmd(SnmpEngine(),
- UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
- UdpTransportTarget(('demo.snmplabs.com', 161)),
- ContextData(),
- ObjectType(
- ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1),
- 'new system name'
- ),
- lookupNames=True, lookupValues=True):
- # Check for errors and print out results
- if errorIndication:
- print(errorIndication)
- else:
- if 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 ]))
- break
+
+errorIndication, errorStatus, errorIndex, varBinds = next(
+ setCmd(SnmpEngine(),
+ UsmUserData('usr-md5-des', 'authkey1', 'privkey1'),
+ 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/v3arch/asyncore/proxy/command/udp6-to-udp4-conversion.py b/examples/v3arch/asyncore/proxy/command/udp6-to-udp4-conversion.py
new file mode 100644
index 0000000..a13df6b
--- /dev/null
+++ b/examples/v3arch/asyncore/proxy/command/udp6-to-udp4-conversion.py
@@ -0,0 +1,142 @@
+"""
+IPv6-to-IPv4 conversion
++++++++++++++++++++++++
+
+Act as a local SNMPv1/v2c Agent listening on a UDP/IPv6 transport, relay
+messages to distant SNMPv1/2c Agent over UDP/IPv4 transport:
+
+* with local SNMPv2c community 'public'
+* local Agent listening at [::1]:161
+* remote SNMPv2c community 'public'
+* remote Agent listening at 195.218.195.228:161
+
+This script can be queried with the following Net-SNMP command:
+
+| $ snmpget -v2c -c public udp6:[::1]:161 sysDescr.0
+
+due to proxy, it is equivalent to
+
+| $ snmpget -v2c -c public 195.218.195.228:161 sysDescr.0
+
+Warning: for production operation you would need to modify this script
+so that it will re-map possible duplicate request-ID values, coming in
+initial request PDUs from different Managers, into unique values to
+avoid sending duplicate request-IDs to Agents.
+
+"""#
+from pysnmp.carrier.asyncore.dgram import udp, udp6
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, cmdgen, context
+from pysnmp.proto.api import v2c
+from pysnmp import error
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+#
+# Transport setup
+#
+
+# Agent section
+
+# UDP over IPv6
+config.addTransport(
+ snmpEngine,
+ udp6.domainName,
+ udp6.Udp6Transport().openServerMode(('::1', 161))
+)
+
+# Manager section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName,
+ udp.UdpTransport().openClientMode()
+)
+
+#
+# SNMPv1/2c setup (Agent role)
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, '1-my-area', 'public')
+
+#
+# SNMPv1/v2c setup (Manager role)
+#
+# Here we configure securityName lexicographically lesser than '1-my-area'
+# to let it match first in snmpCommunityTable on response processing.
+#
+
+config.addV1System(snmpEngine, '0-distant-area', 'public',
+ transportTag='remote')
+
+#
+# Transport target used by Manager
+#
+
+config.addTargetParams(
+ snmpEngine, 'distant-agent-auth', '0-distant-area', 'noAuthNoPriv', 1
+)
+config.addTargetAddr(
+ snmpEngine, 'distant-agent',
+ udp.domainName, ('195.218.195.228', 161),
+ 'distant-agent-auth', retryCount=0, tagList='remote'
+)
+
+# Default SNMP context
+config.addContext(snmpEngine, '')
+
+class CommandResponder(cmdrsp.CommandResponderBase):
+ cmdGenMap = {
+ v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(),
+ v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(),
+ v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
+ v2c.GetBulkRequestPDU.tagSet: cmdgen.BulkCommandGeneratorSingleRun()
+ }
+ pduTypes = cmdGenMap.keys() # This app will handle these PDUs
+
+ # SNMP request relay
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
+ PDU, acInfo):
+ cbCtx = stateReference, PDU
+ contextEngineId = None # address authoritative SNMP Engine
+ try:
+ self.cmdGenMap[PDU.tagSet].sendPdu(
+ snmpEngine, 'distant-agent',
+ contextEngineId, contextName,
+ PDU,
+ self.handleResponsePdu, cbCtx
+ )
+ except error.PySnmpError:
+ self.handleResponsePdu(
+ stateReference, 'error', None, cbCtx
+ )
+
+ # SNMP response relay
+ def handleResponsePdu(self, snmpEngine, sendRequestHandle,
+ errorIndication, PDU, cbCtx):
+ stateReference, reqPDU = cbCtx
+
+ if errorIndication:
+ PDU = v2c.apiPDU.getResponse(reqPDU)
+ PDU.setErrorStatus(PDU, 5)
+
+ self.sendPdu(
+ snmpEngine, stateReference, PDU
+ )
+
+ self.releaseStateInformation(stateReference)
+
+CommandResponder(snmpEngine, context.SnmpContext(snmpEngine))
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/proxy/command/v2c-to-v1-conversion.py b/examples/v3arch/asyncore/proxy/command/v2c-to-v1-conversion.py
new file mode 100644
index 0000000..4e78dfc
--- /dev/null
+++ b/examples/v3arch/asyncore/proxy/command/v2c-to-v1-conversion.py
@@ -0,0 +1,140 @@
+"""
+SNMPv2c-to-SNMPv1 conversion
+++++++++++++++++++++++++++++
+
+Act as a local SNMPv2c Agent, relay messages to distant SNMPv1 Agent:
+
+* over IPv4/UDP
+* with local SNMPv2c community public
+* local Agent listening at 127.0.0.1:161
+* remote SNMPv1, community public
+* remote Agent listening at 195.218.195.228:161
+
+This script can be queried with the following Net-SNMP command:
+
+| $ snmpbulkwalk -v2c -c public -ObentU 127.0.0.1:161 system
+
+due to proxy, it is equivalent to
+
+| $ snmpwalk -v1 -c public 195.218.195.228:161 system
+
+Warning: for production operation you would need to modify this script
+so that it will re-map possible duplicate request-ID values, coming in
+initial request PDUs from different Managers, into unique values to
+avoid sending duplicate request-IDs to Agents.
+
+"""#
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, cmdgen, context
+from pysnmp.proto.api import v2c
+from pysnmp import error
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+#
+# Transport setup
+#
+
+# Agent section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# Manager section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (2,),
+ udp.UdpTransport().openClientMode()
+)
+
+#
+# SNMPv2c setup (Agent role)
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+#
+# SNMPv1 setup (Manager role)
+#
+
+# SecurityName <-> CommunityName <-> Transport mapping
+config.addV1System(snmpEngine, 'distant-area', 'public', transportTag='distant')
+
+#
+# Transport target used by Manager
+#
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'distant-agent-auth', 'distant-area',
+ 'noAuthNoPriv', 0)
+
+config.addTargetAddr(
+ snmpEngine, 'distant-agent',
+ udp.domainName + (2,), ('195.218.195.228', 161),
+ 'distant-agent-auth', retryCount=0, tagList='distant'
+)
+
+# Default SNMP context
+config.addContext(snmpEngine, '')
+
+class CommandResponder(cmdrsp.CommandResponderBase):
+ cmdGenMap = {
+ v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(),
+ v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(),
+ v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
+ v2c.GetBulkRequestPDU.tagSet: cmdgen.BulkCommandGeneratorSingleRun()
+ }
+ pduTypes = cmdGenMap.keys() # This app will handle these PDUs
+
+ # SNMP request relay
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
+ PDU, acInfo):
+ cbCtx = stateReference, PDU
+ contextEngineId = None # address authoritative SNMP Engine
+ try:
+ self.cmdGenMap[PDU.tagSet].sendPdu(
+ snmpEngine, 'distant-agent',
+ contextEngineId, contextName,
+ PDU,
+ self.handleResponsePdu, cbCtx
+ )
+ except error.PySnmpError:
+ self.handleResponsePdu(
+ stateReference, 'error', None, cbCtx
+ )
+
+ # SNMP response relay
+ def handleResponsePdu(self, snmpEngine, sendRequestHandle,
+ errorIndication, PDU, cbCtx):
+ stateReference, reqPDU = cbCtx
+
+ if errorIndication:
+ PDU = v2c.apiPDU.getResponse(reqPDU)
+ PDU.setErrorStatus(PDU, 5)
+
+ self.sendPdu(
+ snmpEngine, stateReference, PDU
+ )
+
+ self.releaseStateInformation(stateReference)
+
+CommandResponder(snmpEngine, context.SnmpContext(snmpEngine))
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/proxy/command/v2c-to-v3-conversion.py b/examples/v3arch/asyncore/proxy/command/v2c-to-v3-conversion.py
new file mode 100644
index 0000000..ca269f7
--- /dev/null
+++ b/examples/v3arch/asyncore/proxy/command/v2c-to-v3-conversion.py
@@ -0,0 +1,140 @@
+"""
+SNMPv2c-to-SNMPv3 conversion
+++++++++++++++++++++++++++++
+
+Act as a local SNMPv1/v2c Agent, relay messages to distant SNMPv3 Agent:
+* over IPv4/UDP
+* with local SNMPv2c community 'public'
+* local Agent listening at 127.0.0.1:161
+* remote SNMPv3 user usr-md5-none, MD5 auth and no privacy protocols
+* remote Agent listening at 195.218.195.228:161
+
+This script can be queried with the following Net-SNMP command:
+
+| $ snmpget -v2c -c public 127.0.0.1:161 1.3.6.1.2.1.1.1.0
+
+due to proxy, it is equivalent to
+
+| $ snmpget -v3 -l authNoPriv -u usr-md5-none -A authkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+Warning: for production operation you would need to modify this script
+so that it will re-map possible duplicate request-ID values, coming in
+initial request PDUs from different Managers, into unique values to
+avoid sending duplicate request-IDs to Agents.
+
+"""#
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, cmdgen, context
+from pysnmp.proto.api import v2c
+from pysnmp import error
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+#
+# Transport setup
+#
+
+# Agent section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# Manager section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (2,),
+ udp.UdpTransport().openClientMode()
+)
+
+#
+# SNMPv1/2c setup (Agent role)
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+#
+# SNMPv3/USM setup (Manager role)
+#
+
+# user: usr-md5-none, auth: MD5, priv NONE
+config.addV3User(
+ snmpEngine, 'usr-md5-none', config.usmHMACMD5AuthProtocol, 'authkey1'
+)
+
+#
+# Transport target used by Manager
+#
+
+config.addTargetParams(
+ snmpEngine, 'distant-agent-auth', 'usr-md5-none', 'authNoPriv'
+)
+config.addTargetAddr(
+ snmpEngine, 'distant-agent',
+ udp.domainName + (2,), ('195.218.195.228', 161),
+ 'distant-agent-auth', retryCount=0
+)
+
+# Default SNMP context
+config.addContext(snmpEngine, '')
+
+class CommandResponder(cmdrsp.CommandResponderBase):
+ cmdGenMap = {
+ v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(),
+ v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(),
+ v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
+ v2c.GetBulkRequestPDU.tagSet: cmdgen.BulkCommandGeneratorSingleRun()
+ }
+ pduTypes = cmdGenMap.keys() # This app will handle these PDUs
+
+ # SNMP request relay
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
+ PDU, acInfo):
+ cbCtx = stateReference, PDU
+ contextEngineId = None # address authoritative SNMP Engine
+ try:
+ self.cmdGenMap[PDU.tagSet].sendPdu(
+ snmpEngine, 'distant-agent',
+ contextEngineId, contextName,
+ PDU,
+ self.handleResponsePdu, cbCtx
+ )
+ except error.PySnmpError:
+ self.handleResponsePdu(
+ stateReference, 'error', None, cbCtx
+ )
+
+ # SNMP response relay
+ def handleResponsePdu(self, snmpEngine, sendRequestHandle,
+ errorIndication, PDU, cbCtx):
+ stateReference, reqPDU = cbCtx
+
+ if errorIndication:
+ PDU = v2c.apiPDU.getResponse(reqPDU)
+ PDU.setErrorStatus(PDU, 5)
+
+ self.sendPdu(
+ snmpEngine, stateReference, PDU
+ )
+
+ self.releaseStateInformation(stateReference)
+
+CommandResponder(snmpEngine, context.SnmpContext(snmpEngine))
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py b/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py
new file mode 100644
index 0000000..da9aba3
--- /dev/null
+++ b/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py
@@ -0,0 +1,143 @@
+"""
+SNMPv3-to-SNMPv2c conversion
+++++++++++++++++++++++++++++
+
+Act as a local SNMPv3 Agent, relay messages to distant SNMPv1/v2c Agent:
+* over IPv4/UDP
+* with local SNMPv3 user usr-md5-des, MD5 auth and DES privacy protocols
+* local Agent listening at 127.0.0.1:161
+* remote SNMPv1, community public
+* remote Agent listening at 195.218.195.228:161
+
+This script can be queried with the following Net-SNMP command:
+
+| $ snmpget -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -ObentU 127.0.0.1:161 1.3.6.1.2.1.1.1.0
+
+due to proxy, it is equivalent to
+
+| $ snmpget -v2c -c public 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+Warning: for production operation you would need to modify this script
+so that it will re-map possible duplicate request-ID values, coming in
+initial request PDUs from different Managers, into unique values to
+avoid sending duplicate request-IDs to Agents.
+
+"""#
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, cmdgen, context
+from pysnmp.proto.api import v2c
+from pysnmp import error
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+#
+# Transport setup
+#
+
+# Agent section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# Manager section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (2,),
+ udp.UdpTransport().openClientMode()
+)
+
+#
+# SNMPv3/USM setup (Agent role)
+#
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+
+#
+# SNMPv1/2c setup (Manager role)
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+#
+# Transport target used by Manager
+#
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'distant-agent-auth', 'my-area',
+ 'noAuthNoPriv', 0)
+
+config.addTargetAddr(
+ snmpEngine, 'distant-agent',
+ udp.domainName + (2,), ('195.218.195.228', 161),
+ 'distant-agent-auth', retryCount=0
+)
+
+# Default SNMP context
+config.addContext(snmpEngine, '')
+
+class CommandResponder(cmdrsp.CommandResponderBase):
+ cmdGenMap = {
+ v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(),
+ v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(),
+ v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
+ v2c.GetBulkRequestPDU.tagSet: cmdgen.BulkCommandGeneratorSingleRun()
+ }
+ pduTypes = cmdGenMap.keys() # This app will handle these PDUs
+
+ # SNMP request relay
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
+ PDU, acInfo):
+ cbCtx = stateReference, PDU
+ contextEngineId = None # address authoritative SNMP Engine
+ try:
+ self.cmdGenMap[PDU.tagSet].sendPdu(
+ snmpEngine, 'distant-agent',
+ contextEngineId, contextName,
+ PDU,
+ self.handleResponsePdu, cbCtx
+ )
+ except error.PySnmpError:
+ self.handleResponsePdu(
+ stateReference, 'error', None, cbCtx
+ )
+
+ # SNMP response relay
+ def handleResponsePdu(self, snmpEngine, sendRequestHandle,
+ errorIndication, PDU, cbCtx):
+ stateReference, reqPDU = cbCtx
+
+ if errorIndication:
+ PDU = v2c.apiPDU.getResponse(reqPDU)
+ PDU.setErrorStatus(PDU, 5)
+
+ self.sendPdu(
+ snmpEngine, stateReference, PDU
+ )
+
+ self.releaseStateInformation(stateReference)
+
+CommandResponder(snmpEngine, context.SnmpContext(snmpEngine))
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/examples/v3arch/trollius/agent/ntforg/inform-v3.py b/examples/v3arch/trollius/agent/ntforg/inform-v3.py
index 93fe5df..e4e87c1 100644
--- a/examples/v3arch/trollius/agent/ntforg/inform-v3.py
+++ b/examples/v3arch/trollius/agent/ntforg/inform-v3.py
@@ -1,19 +1,25 @@
-#
-# Notification Originator
-#
-# Send SNMP INFORM notification using the following options:
-#
-# * SNMPv3
-# * with user 'usr-md5-none', auth: MD5, priv NONE
-# * over IPv4/UDP
-# * using Trollius framework for network transport
-# * to a Manager at 127.0.0.1:162
-# * send INFORM notification
-# * with TRAP ID 'warmStart' specified as an OID
-# * include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
-#
-# Requires Trollius framework!
-#
+"""
+SNMP INFORM notification
+++++++++++++++++++++++++
+
+Send SNMP INFORM notification using the following options:
+
+* SNMPv3
+* with user 'usr-md5-none', auth: MD5, priv NONE
+* over IPv4/UDP
+* using Trollius framework for network transport
+* to a Manager at 127.0.0.1:162
+* send INFORM notification
+* with TRAP ID 'warmStart' specified as an 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-md5-none -A authkey1 127.0.0.1 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s 'system name'
+
+Requires Trollius framework!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import context
from pysnmp.entity.rfc3413.asyncio import ntforg
diff --git a/examples/v3arch/trollius/agent/ntforg/trap-v1.py b/examples/v3arch/trollius/agent/ntforg/trap-v1.py
index b11b39f..50c26b8 100644
--- a/examples/v3arch/trollius/agent/ntforg/trap-v1.py
+++ b/examples/v3arch/trollius/agent/ntforg/trap-v1.py
@@ -1,23 +1,29 @@
-#
-# Notification Originator
-#
-# Send SNMP notification using the following options:
-#
-# * SNMPv1
-# * with community name 'public'
-# * over IPv4/UDP
-# * using Trollius framework for network transport
-# * to a Manager at 127.0.0.1:162
-# * send TRAP notification
-# * with TRAP ID 'coldStart' specified as an OID
-# * include managed objects information:
-# * 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'
-#
-# Requires Trollius framework!
-#
+"""
+SNMPv1 TRAP
++++++++++++
+
+Send SNMP notification using the following options:
+
+* SNMPv1
+* with community name 'public'
+* over IPv4/UDP
+* using Trollius framework for network transport
+* to a Manager at 127.0.0.1:162
+* send TRAP notification
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+* 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'
+
+Requires Trollius framework!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import context
from pysnmp.entity.rfc3413.asyncio import ntforg
diff --git a/examples/v3arch/trollius/manager/cmdgen/get-v1.py b/examples/v3arch/trollius/manager/cmdgen/get-v1.py
index 3d14a15..9ecda4e 100644
--- a/examples/v3arch/trollius/manager/cmdgen/get-v1.py
+++ b/examples/v3arch/trollius/manager/cmdgen/get-v1.py
@@ -1,20 +1,22 @@
-#
-# Command Generator
-#
-# Send SNMP GET request using the following options:
-#
-# * with SNMPv1, community 'public'
-# * using Trollius framework for network transport
-# * over IPv4/UDP
-# * to an Agent at 195.218.195.228:161
-# * for an OID in string form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpset -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0
-#
-# Requires Trollius framework!
-#
+"""
+SNMPv1 GET
+++++++++++
+
+Send SNMP GET request using the following options:
+
+* with SNMPv1, community 'public'
+* using Trollius framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in string form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+Requires Trollius framework!
+
+"""#
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity.rfc3413.asyncio import cmdgen
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/trollius/manager/cmdgen/get-v2c-custom-timeout.py b/examples/v3arch/trollius/manager/cmdgen/get-v2c-custom-timeout.py
index 4db7a8c..9da4301 100644
--- a/examples/v3arch/trollius/manager/cmdgen/get-v2c-custom-timeout.py
+++ b/examples/v3arch/trollius/manager/cmdgen/get-v2c-custom-timeout.py
@@ -1,20 +1,22 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv2c, community 'public'
-# using Trollius framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# wait 3 seconds for response, retry 5 times (plus one initial attempt)
-# for an OID in string form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
-#
-# Requires Trollius framework!
-#
+"""
+Fetch scalar value with timeout
++++++++++++++++++++++++++++++++
+
+Send a SNMP GET request
+* with SNMPv2c, community 'public'
+* using Trollius framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* wait 3 seconds for response, retry 5 times (plus one initial attempt)
+* for an OID in string form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+Requires Trollius framework!
+
+"""#
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity.rfc3413.asyncio import cmdgen
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/trollius/manager/cmdgen/getbulk-v3.py b/examples/v3arch/trollius/manager/cmdgen/getbulk-v3.py
index 50f4e69..94839b4 100644
--- a/examples/v3arch/trollius/manager/cmdgen/getbulk-v3.py
+++ b/examples/v3arch/trollius/manager/cmdgen/getbulk-v3.py
@@ -1,21 +1,23 @@
-#
-# GETBULK Command Generator
-#
-# Send a series of SNMP GETBULK requests
-# with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
-# using Trollius framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# with values non-repeaters = 0, max-repetitions = 25
-# for two OIDs in string form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
-# Requires Trollius framework!
-#
+"""
+BULK walk MIB
++++++++++++++
+
+Send a series of SNMP GETBULK requests
+* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
+* using Trollius framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* with values non-repeaters = 0, max-repetitions = 25
+* for two OIDs in string form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+Requires Trollius framework!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.proto import rfc1905
from pysnmp.entity.rfc3413.asyncio import cmdgen
diff --git a/examples/v3arch/trollius/manager/cmdgen/getnext-v3.py b/examples/v3arch/trollius/manager/cmdgen/getnext-v3.py
index 5b26bff..d5a852a 100644
--- a/examples/v3arch/trollius/manager/cmdgen/getnext-v3.py
+++ b/examples/v3arch/trollius/manager/cmdgen/getnext-v3.py
@@ -1,20 +1,22 @@
-#
-# GETNEXT Command Generator
-#
-# Send a series of SNMP GETNEXT requests
-# with SNMPv3 with user 'usr-none-none', no auth and no privacy protocols
-# using Trollius framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for an OID in string form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
-# Requires Trollius framework!
-#
+"""
+Walk MIB
+++++++++
+
+Send a series of SNMP GETNEXT requests
+* with SNMPv3 with user 'usr-none-none', no auth and no privacy protocols
+* using Trollius framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in string form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+Requires Trollius framework!
+
+"""#
from pysnmp.entity import engine, config
from pysnmp.proto import rfc1905
from pysnmp.entity.rfc3413.asyncio import cmdgen
diff --git a/examples/v3arch/trollius/manager/cmdgen/set-v2c.py b/examples/v3arch/trollius/manager/cmdgen/set-v2c.py
index 966e78a..4939635 100644
--- a/examples/v3arch/trollius/manager/cmdgen/set-v2c.py
+++ b/examples/v3arch/trollius/manager/cmdgen/set-v2c.py
@@ -1,20 +1,22 @@
-#
-# Command Generator
-#
-# Send SNMP SET request using the following options:
-#
-# * with SNMPv1, community 'public'
-# * using Trollius framework for network transport
-# * over IPv4/UDP
-# * to an Agent at 195.218.195.228:161
-# * for OIDs in tuple form and an integer and string-typed values
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
-#
-# Requires Trollius framework!
-#
+"""
+SET scalar value
+++++++++++++++++
+
+Send SNMP SET request using the following options:
+
+* with SNMPv1, community 'public'
+* using Trollius framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in tuple form and an integer and string-typed values
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
+
+Requires Trollius framework!
+
+"""#
from pysnmp.carrier.asyncio.dgram import udp
from pysnmp.entity.rfc3413.asyncio import cmdgen
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/twisted/agent/cmdrsp/v1-read-and-write-communities.py b/examples/v3arch/twisted/agent/cmdrsp/v1-read-and-write-communities.py
index d346244..da6cc5f 100644
--- a/examples/v3arch/twisted/agent/cmdrsp/v1-read-and-write-communities.py
+++ b/examples/v3arch/twisted/agent/cmdrsp/v1-read-and-write-communities.py
@@ -1,20 +1,22 @@
-#
-# Command Responder
-#
-# Listen and respond to SNMP GET/SET/GETNEXT queries with
-# the following options:
-#
-# * SNMPv1
-# * with SNMP community "public" (read access) or "private" (write access)
-# * allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
-# * over IPv4/UDP, listening at 127.0.0.1:161
-# * using Twisted fraework for network transport
-#
-# The following Net-SNMP's commands will GET/SET a value at this Agent:
-#
-# $ snmpget -v1 -c public 127.0.0.1 SNMPv2-MIB::sysLocation.0
-# $ snmpset -v1 -c private 127.0.0.1 SNMPv2-MIB::sysLocation.0 s "far away"
-#
+"""
+Multiple SNMP communities
++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT queries with
+the following options:
+
+* SNMPv1
+* with SNMP community "public" (read access) or "private" (write access)
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+* using Twisted fraework for network transport
+
+The following Net-SNMP commands will GET/SET a value at this Agent:
+
+| $ snmpget -v1 -c public 127.0.0.1 SNMPv2-MIB::sysLocation.0
+| $ snmpset -v1 -c private 127.0.0.1 SNMPv2-MIB::sysLocation.0 s "far away"
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
diff --git a/examples/v3arch/twisted/agent/cmdrsp/v2c-custom-scalar-mib-objects.py b/examples/v3arch/twisted/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
index 091bb75..565419d 100644
--- a/examples/v3arch/twisted/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
+++ b/examples/v3arch/twisted/agent/cmdrsp/v2c-custom-scalar-mib-objects.py
@@ -1,20 +1,22 @@
-#
-# Command Responder
-#
-# Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
-# the following options:
-#
-# * SNMPv2c
-# * with SNMP community "public"
-# * serving custom Managed Object Instance defined within this script
-# * allow read access only to the subtree where the custom MIB object resides
-# * over IPv4/UDP, listening at 127.0.0.1:161
-# * using Twisted fraework for network transport
-#
-# Either of the following Net-SNMP's commands will walk this Agent:
-#
-# $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
-#
+"""
+Implementing scalar MIB objects
++++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv2c
+* with SNMP community "public"
+* serving custom Managed Object Instance defined within this script
+* allow read access only to the subtree where the custom MIB object resides
+* over IPv4/UDP, listening at 127.0.0.1:161
+* using Twisted fraework for network transport
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
+
+"""#
import sys
from twisted.internet import reactor
from pysnmp.entity import engine, config
diff --git a/examples/v3arch/twisted/agent/cmdrsp/v2c-multiple-interfaces.py b/examples/v3arch/twisted/agent/cmdrsp/v2c-multiple-interfaces.py
index 4f8b29d..a9e3e00 100644
--- a/examples/v3arch/twisted/agent/cmdrsp/v2c-multiple-interfaces.py
+++ b/examples/v3arch/twisted/agent/cmdrsp/v2c-multiple-interfaces.py
@@ -1,20 +1,22 @@
-#
-# Command Responder
-#
-# Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
-# the following options:
-#
-# * SNMPv2c
-# * with SNMP community "public"
-# * allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
-# * over IPv4/UDP, listening at 127.0.0.1:161 and 127.0.0.2:161 interfaces
-# * using Twisted framework for network transport
-#
-# Either of the following Net-SNMP's commands will walk this Agent:
-#
-# $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
-# $ snmpwalk -v2c -c public 127.0.0.2 .1.3.6
-#
+"""
+Listen on multiple network interfaces
++++++++++++++++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv2c
+* with SNMP community "public"
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161 and 127.0.0.2:161 interfaces
+* using Twisted framework for network transport
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6
+| $ snmpwalk -v2c -c public 127.0.0.2 .1.3.6
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
diff --git a/examples/v3arch/twisted/agent/cmdrsp/v3-multiple-users.py b/examples/v3arch/twisted/agent/cmdrsp/v3-multiple-users.py
index 36d9d36..91fd955 100644
--- a/examples/v3arch/twisted/agent/cmdrsp/v3-multiple-users.py
+++ b/examples/v3arch/twisted/agent/cmdrsp/v3-multiple-users.py
@@ -1,23 +1,26 @@
-#
-# Command Responder
-#
-# Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
-# the following options:
-#
-# * SNMPv3
-# * with USM user 'usr-md5-des', auth: MD5, priv DES or
-# with USM user 'usr-sha-none', auth: SHA, no privacy
-# with USM user 'usr-sha-aes128', auth: SHA, priv AES
-# * allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
-# * over IPv4/UDP, listening at 127.0.0.1:161
-# * using Twisted framework for network transport
-#
-# Either of the following Net-SNMP's commands will walk this Agent:
-#
-# $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
-# $ snmpwalk -v3 -u usr-sha-none -l authNoPriv -a SHA -A authkey1 localhost .1.3.6
-# $ snmpwalk -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 localhost .1.3.6
-#
+"""
+Multiple SNMP USM users
++++++++++++++++++++++++
+
+Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
+the following options:
+
+* SNMPv3
+* with USM user:
+ * 'usr-md5-des', auth: MD5, priv DES or
+ * 'usr-sha-none', auth: SHA, no privacy
+ * 'usr-sha-aes128', auth: SHA, priv AES
+* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
+* over IPv4/UDP, listening at 127.0.0.1:161
+* using Twisted framework for network transport
+
+Either of the following Net-SNMP commands will walk this Agent:
+
+| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
+| $ snmpwalk -v3 -u usr-sha-none -l authNoPriv -a SHA -A authkey1 localhost .1.3.6
+| $ snmpwalk -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 localhost .1.3.6
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
diff --git a/examples/v3arch/twisted/agent/ntforg/inform-v2c.py b/examples/v3arch/twisted/agent/ntforg/inform-v2c.py
index 95ba561..77245fe 100644
--- a/examples/v3arch/twisted/agent/ntforg/inform-v2c.py
+++ b/examples/v3arch/twisted/agent/ntforg/inform-v2c.py
@@ -1,19 +1,25 @@
-#
-# Notification Originator
-#
-# Send SNMP INFORM notification using the following options:
-#
-# * SNMPv2c
-# * with community name 'public'
-# * over IPv4/UDP
-# * using Twisted framework for network transport
-# * send INFORM notification
-# * to a Manager at 127.0.0.1:162
-# * with TRAP ID 'coldStart' specified as an OID
-# * include managed objects information:
-# 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
-# 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
-#
+"""
+SNMPv2c INFORM
+++++++++++++++
+
+Send SNMP INFORM notification using the following options:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* using Twisted framework for network transport
+* send INFORM notification
+* to a Manager at 127.0.0.1:162
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ * 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+ * 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
+
+Functionally similar to:
+
+| $ snmpinform -v2c -c public 127.0.0.2 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/examples/v3arch/twisted/agent/ntforg/inform-v3.py b/examples/v3arch/twisted/agent/ntforg/inform-v3.py
index 376da6e..4473326 100644
--- a/examples/v3arch/twisted/agent/ntforg/inform-v3.py
+++ b/examples/v3arch/twisted/agent/ntforg/inform-v3.py
@@ -1,17 +1,23 @@
-#
-# Notification Originator
-#
-# Send SNMP INFORM notification using the following options:
-#
-# * SNMPv3
-# * with user 'usr-md5-none', auth: MD5, priv NONE
-# * over IPv4/UDP
-# * using Twisted framework for network transport
-# * to a Manager at 127.0.0.1:162
-# * send INFORM notification
-# * with TRAP ID 'warmStart' specified as an OID
-# * include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
-#
+"""
+SNMPv3 INFORM
++++++++++++++
+
+Send SNMP INFORM notification using the following options:
+
+* SNMPv3
+* with user 'usr-md5-none', auth: MD5, priv NONE
+* over IPv4/UDP
+* using Twisted framework for network transport
+* to a Manager at 127.0.0.1:162
+* send INFORM notification
+* with TRAP ID 'warmStart' specified as an 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-md5-none -A authkey1 127.0.0.1 0 1.3.6.1.6.3.1.1.5.2 1.3.6.1.2.1.1.5.0 s 'system name'
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/examples/v3arch/twisted/agent/ntforg/trap-v1.py b/examples/v3arch/twisted/agent/ntforg/trap-v1.py
index 6863e0d..587314a 100644
--- a/examples/v3arch/twisted/agent/ntforg/trap-v1.py
+++ b/examples/v3arch/twisted/agent/ntforg/trap-v1.py
@@ -1,21 +1,27 @@
-#
-# Notification Originator
-#
-# Send SNMP notification using the following options:
-#
-# * SNMPv1
-# * with community name 'public'
-# * over IPv4/UDP
-# * using Twisted framework for network transport
-# * to a Manager at 127.0.0.1:162
-# * send TRAP notification
-# * with TRAP ID 'coldStart' specified as an OID
-# * include managed objects information:
-# * 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'
-#
+"""
+SNMPv1 TRAP
++++++++++++
+
+Send SNMP notification using the following options:
+
+* SNMPv1
+* with community name 'public'
+* over IPv4/UDP
+* using Twisted framework for network transport
+* to a Manager at 127.0.0.1:162
+* send TRAP notification
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+* 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 127.0.0.1 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 twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/examples/v3arch/twisted/agent/ntforg/trap-v2c-multiple-targets.py b/examples/v3arch/twisted/agent/ntforg/trap-v2c-multiple-targets.py
index c63dc37..f1e95bf 100644
--- a/examples/v3arch/twisted/agent/ntforg/trap-v2c-multiple-targets.py
+++ b/examples/v3arch/twisted/agent/ntforg/trap-v2c-multiple-targets.py
@@ -1,20 +1,34 @@
-#
-# Notification Originator
-#
-# Send SNMP TRAP notifications to multiple Managers using the
-# following options:
-#
-# * SNMPv2c
-# * with community name 'public'
-# * over IPv4/UDP
-# * using Twisted framework for network transport
-# * send TRAP notification
-# * to multiple Managers at 127.0.0.1:162, 127.0.0.2:162
-# * with TRAP ID 'coldStart' specified as an OID
-# * include managed objects information:
-# 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
-# 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
-#
+"""
+Notification to multiple addresses
+++++++++++++++++++++++++++++++++++
+
+Send SNMP TRAP notifications to multiple Managers using the
+following options:
+
+* SNMPv2c
+* with community name 'public'
+* over IPv4/UDP
+* using Twisted framework for network transport
+* send TRAP notification
+* to multiple Managers at 127.0.0.1:162, 127.0.0.2:162 and 127.0.0.3:162
+* with TRAP ID 'coldStart' specified as an OID
+* include managed objects information:
+ * 1.3.6.1.2.1.1.1.0 = 'Example Notificator'
+ * 1.3.6.1.2.1.1.5.0 = 'Notificator Example'
+
+Functionally similar to:
+
+| $ snmptrap -v2c -c public 127.0.0.1 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+and
+
+| $ snmptrap -v2c -c public 127.0.0.2 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+and
+
+| $ snmptrap -v2c -c public 127.0.0.3 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.1.0 s 'Example notification' 1.3.6.1.2.1.1.5.0 s 'Notificator Example'
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/examples/v3arch/twisted/agent/ntforg/trap-v3.py b/examples/v3arch/twisted/agent/ntforg/trap-v3.py
index c38e474..133f723 100644
--- a/examples/v3arch/twisted/agent/ntforg/trap-v3.py
+++ b/examples/v3arch/twisted/agent/ntforg/trap-v3.py
@@ -1,17 +1,23 @@
-#
-# Notification Originator
-#
-# Send SNMP TRAP notification using the following options:
-#
-# * SNMPv3
-# * with user 'usr-md5-des', auth: MD5, priv DES
-# * over IPv4/UDP
-# * using Twisted framework for network transport
-# * send TRAP notification
-# * to a Manager at 127.0.0.1:162
-# * with TRAP ID 'warmStart' specified as an OID
-# * include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
-#
+"""
+SNMPv3 TRAP
++++++++++++
+
+Send SNMP TRAP notification using the following options:
+
+* SNMPv3
+* with user 'usr-md5-des', auth: MD5, priv DES
+* over IPv4/UDP
+* using Twisted framework for network transport
+* send TRAP notification
+* to a Manager at 127.0.0.1:162
+* with TRAP ID 'warmStart' specified as an OID
+* include managed object information 1.3.6.1.2.1.1.5.0 = 'system name'
+
+Functionally similar to:
+
+| $ snmptrap -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -e 8000000001020304 0 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s 'my system'
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/examples/v3arch/twisted/manager/cmdgen/get-v1.py b/examples/v3arch/twisted/manager/cmdgen/get-v1.py
index 38428c6..2939f41 100644
--- a/examples/v3arch/twisted/manager/cmdgen/get-v1.py
+++ b/examples/v3arch/twisted/manager/cmdgen/get-v1.py
@@ -1,17 +1,20 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv1, community 'public'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for an OID in tuple form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0
-#
+"""
+SNMPv1 GET
+++++++++++
+
+Send SNMP GET request with the following options:
+
+* with SNMPv1, community 'public'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/get-v2c-custom-timeout.py b/examples/v3arch/twisted/manager/cmdgen/get-v2c-custom-timeout.py
index 246a1b9..e83e5e8 100644
--- a/examples/v3arch/twisted/manager/cmdgen/get-v2c-custom-timeout.py
+++ b/examples/v3arch/twisted/manager/cmdgen/get-v2c-custom-timeout.py
@@ -1,18 +1,20 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv2c, community 'public'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# wait 3 seconds for response, retry 5 times (plus one initial attempt)
-# for an OID in tuple form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
-#
+"""
+Fetch scalar value with timeout
++++++++++++++++++++++++++++++++
+
+Send a SNMP GET request
+* with SNMPv2c, community 'public'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* wait 3 seconds for response, retry 5 times (plus one initial attempt)
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v2c -c public -ObentU -r 5 -t 1 195.218.195.228 1.3.6.1.2.1.1.1.0
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/get-v3-custom-context.py b/examples/v3arch/twisted/manager/cmdgen/get-v3-custom-context.py
index e85babe..527125f 100644
--- a/examples/v3arch/twisted/manager/cmdgen/get-v3-custom-context.py
+++ b/examples/v3arch/twisted/manager/cmdgen/get-v3-custom-context.py
@@ -1,20 +1,22 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv3 with user 'usr-md5-none', SHA auth and no privacy protocols
-# for MIB instance identified by
-# contextEngineId: 0x80004fb805636c6f75644dab22cc
-# contextName: da761cfc8c94d3aceef4f60f049105ba
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for an OID in tuple form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v3 -l authNoPriv -u usr-md5-none -A authkey1 -E 80004fb805636c6f75644dab22cc -n da761cfc8c94d3aceef4f60f049105ba -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
-#
+"""
+Custom ContextEngineId and ContextName
+++++++++++++++++++++++++++++++++++++++
+
+Send a SNMP GET request
+* with SNMPv3 with user 'usr-md5-none', SHA auth and no privacy protocols
+* for MIB instance identified by
+* contextEngineId: 0x80004fb805636c6f75644dab22cc
+* contextName: da761cfc8c94d3aceef4f60f049105ba
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v3 -l authNoPriv -u usr-md5-none -A authkey1 -E 80004fb805636c6f75644dab22cc -n da761cfc8c94d3aceef4f60f049105ba -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/get-v3.py b/examples/v3arch/twisted/manager/cmdgen/get-v3.py
index 0e3ab3e..d0a568d 100644
--- a/examples/v3arch/twisted/manager/cmdgen/get-v3.py
+++ b/examples/v3arch/twisted/manager/cmdgen/get-v3.py
@@ -1,17 +1,19 @@
-#
-# GET Command Generator
-#
-# Send a SNMP GET request
-# with SNMPv3 with user 'usr-sha-aes', SHA auth and AES128 privacy protocols
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for an OID in tuple form
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpget -v3 -l authPriv -u usr-sha-aes -a SHA -A authkey1 -x AES -X privkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
-#
+"""
+SNMPv3, auth: SHA, privacy: AES
++++++++++++++++++++++++++++++++
+
+Send a SNMP GET request
+* with SNMPv3 with user 'usr-sha-aes', SHA auth and AES128 privacy protocols
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpget -v3 -l authPriv -u usr-sha-aes -a SHA -A authkey1 -x AES -X privkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/getbulk-v2c.py b/examples/v3arch/twisted/manager/cmdgen/getbulk-v2c.py
index d5733aa..7adf6fe 100644
--- a/examples/v3arch/twisted/manager/cmdgen/getbulk-v2c.py
+++ b/examples/v3arch/twisted/manager/cmdgen/getbulk-v2c.py
@@ -1,19 +1,21 @@
-#
-# GETBULK Command Generator
-#
-# Send a series of SNMP GETBULK requests
-# with SNMPv2c, community 'public'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# with values non-repeaters = 0, max-repetitions = 25
-# for two OIDs in tuple form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
+"""
+Bulk walk MIB (SNMPv2c)
++++++++++++++++++++++++
+
+Send a series of SNMP GETBULK requests
+* with SNMPv2c, community 'public'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* with values non-repeaters = 0, max-repetitions = 25
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v2c -c public -C n0 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/getbulk-v3.py b/examples/v3arch/twisted/manager/cmdgen/getbulk-v3.py
index 2b734a1..04aa188 100644
--- a/examples/v3arch/twisted/manager/cmdgen/getbulk-v3.py
+++ b/examples/v3arch/twisted/manager/cmdgen/getbulk-v3.py
@@ -1,19 +1,21 @@
-#
-# GETBULK Command Generator
-#
-# Send a series of SNMP GETBULK requests
-# with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
-# over IPv4/UDP
-# using Twisted framework for network transport
-# to an Agent at 195.218.195.228:161
-# with values non-repeaters = 1, max-repetitions = 25
-# for two OIDs in tuple form (first OID is non-repeating)
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpbulkwalk -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -C n1 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
+"""
+Walk and Bulk walk OIDs
++++++++++++++++++++++++
+
+Send a series of SNMP GETBULK requests
+* with SNMPv3 with user 'usr-md5-des', MD5 auth and DES privacy protocols
+* over IPv4/UDP
+* using Twisted framework for network transport
+* to an Agent at 195.218.195.228:161
+* with values non-repeaters = 1, max-repetitions = 25
+* for two OIDs in tuple form (first OID is non-repeating)
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpbulkwalk -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -C n1 -C r25 -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/getnext-v1.py b/examples/v3arch/twisted/manager/cmdgen/getnext-v1.py
index dede0ab..b7f4bb8 100644
--- a/examples/v3arch/twisted/manager/cmdgen/getnext-v1.py
+++ b/examples/v3arch/twisted/manager/cmdgen/getnext-v1.py
@@ -1,18 +1,20 @@
-#
-# GETNEXT Command Generator
-#
-# Send a series of SNMP GETNEXT requests
-# with SNMPv1, community 'public'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for two OIDs in tuple form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
+"""
+Walk MIB (SNMPv1)
++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests
+* with SNMPv1, community 'public'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v1 -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/getnext-v2c-from-specific-address.py b/examples/v3arch/twisted/manager/cmdgen/getnext-v2c-from-specific-address.py
index c27b643..902bd29 100644
--- a/examples/v3arch/twisted/manager/cmdgen/getnext-v2c-from-specific-address.py
+++ b/examples/v3arch/twisted/manager/cmdgen/getnext-v2c-from-specific-address.py
@@ -1,19 +1,21 @@
-#
-# GETNEXT Command Generator
-#
-# Send a series of SNMP GETNEXT requests
-# with SNMPv2c, community 'public'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# sending packets from any local interface (0.0.0.0), local port 61024
-# for two OIDs in tuple form
-# stop on end-of-mib condition for both OIDs
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
-#
+"""
+Send packets from specific local interface
+++++++++++++++++++++++++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests
+* with SNMPv2c, community 'public'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* sending packets from any local interface (0.0.0.0), local port 61024
+* for two OIDs in tuple form
+* stop on end-of-mib condition for both OIDs
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v2c -c public -ObentU 195.218.195.228 1.3.6.1.2.1.1 1.3.6.1.4.1.1
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/getnext-v3-pull-subtree.py b/examples/v3arch/twisted/manager/cmdgen/getnext-v3-pull-subtree.py
index bff697e..d8e8612 100644
--- a/examples/v3arch/twisted/manager/cmdgen/getnext-v3-pull-subtree.py
+++ b/examples/v3arch/twisted/manager/cmdgen/getnext-v3-pull-subtree.py
@@ -1,18 +1,20 @@
-#
-# GETNEXT Command Generator
-#
-# Send a series of SNMP GETNEXT requests
-# with SNMPv3 with user 'usr-none-none', no auth and no privacy protocols
-# over IPv4/UDP
-# using Twisted framework for network transport
-# to an Agent at 195.218.195.228:161
-# for an OID in string form
-# stop whenever received OID goes out of initial prefix (it may be a table)
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpwalk -v3 -l noAuthNoPriv -u usr-none-none -ObentU 195.218.195.228:161 1.3.6.1.2.1.1
-#
+"""
+Pull MIB subtree (SNMPv3)
++++++++++++++++++++++++++
+
+Send a series of SNMP GETNEXT requests
+* with SNMPv3 with user 'usr-none-none', no auth and no privacy protocols
+* over IPv4/UDP
+* using Twisted framework for network transport
+* to an Agent at 195.218.195.228:161
+* for an OID in string form
+* stop whenever received OID goes out of initial prefix (it may be a table)
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpwalk -v3 -l noAuthNoPriv -u usr-none-none -ObentU 195.218.195.228:161 1.3.6.1.2.1.1
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/set-v1.py b/examples/v3arch/twisted/manager/cmdgen/set-v1.py
index c372104..fee0ed2 100644
--- a/examples/v3arch/twisted/manager/cmdgen/set-v1.py
+++ b/examples/v3arch/twisted/manager/cmdgen/set-v1.py
@@ -1,17 +1,19 @@
-#
-# SET Command Generator
-#
-# Send a SNMP SET request
-# with SNMPv1, community 'private'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for OIDs in tuple form and an integer and string-typed values
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
-#
+"""
+SET string and integer scalars (SNMPv1)
++++++++++++++++++++++++++++++++++++++++
+
+Send a SNMP SET request
+* with SNMPv1, community 'private'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in tuple form and an integer and string-typed values
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v1 -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my value' 1.3.6.1.2.1.1.9.1.4.1 t 123
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/set-v2c.py b/examples/v3arch/twisted/manager/cmdgen/set-v2c.py
index 5fd91f1..e27b6e6 100644
--- a/examples/v3arch/twisted/manager/cmdgen/set-v2c.py
+++ b/examples/v3arch/twisted/manager/cmdgen/set-v2c.py
@@ -1,17 +1,19 @@
-#
-# SET Command Generator
-#
-# Send a SNMP SET request
-# with SNMPv2c, community 'private'
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for OIDs in tuple form and an integer-typed value
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpset -v2c -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.4.1 t 123
-#
+"""
+SET integer scalar (SNMPv2c)
+++++++++++++++++++++++++++++
+
+Send a SNMP SET request
+* with SNMPv2c, community 'private'
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for OIDs in tuple form and an integer-typed value
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v2c -c private -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.4.1 t 123
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/cmdgen/set-v3.py b/examples/v3arch/twisted/manager/cmdgen/set-v3.py
index 1fb7ce8..e787927 100644
--- a/examples/v3arch/twisted/manager/cmdgen/set-v3.py
+++ b/examples/v3arch/twisted/manager/cmdgen/set-v3.py
@@ -1,17 +1,19 @@
-#
-# SET Command Generator
-#
-# Send a SNMP SET request
-# with SNMPv3 with user 'usr-sha-none', SHA auth and no privacy protocols
-# using Twisted framework for network transport
-# over IPv4/UDP
-# to an Agent at 195.218.195.228:161
-# for an OID in tuple form and a string-typed value
-#
-# This script performs similar to the following Net-SNMP command:
-#
-# $ snmpset -v3 -l authNoPriv -u usr-sha-none -a SHA -A authkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my new value'
-#
+"""
+SET string scalar (SNMPv3)
+++++++++++++++++++++++++++
+
+Send a SNMP SET request
+* with SNMPv3 with user 'usr-sha-none', SHA auth and no privacy protocols
+* using Twisted framework for network transport
+* over IPv4/UDP
+* to an Agent at 195.218.195.228:161
+* for an OID in tuple form and a string-typed value
+
+This script performs similar to the following Net-SNMP command:
+
+| $ snmpset -v3 -l authNoPriv -u usr-sha-none -a SHA -A authkey1 -ObentU 195.218.195.228:161 1.3.6.1.2.1.1.9.1.3.1 s 'my new value'
+
+"""#
from twisted.internet import reactor, defer
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413.twisted import cmdgen
diff --git a/examples/v3arch/twisted/manager/ntfrcv/v2c-multiple-interfaces.py b/examples/v3arch/twisted/manager/ntfrcv/v2c-multiple-interfaces.py
index 4f9b68f..b7edf7d 100644
--- a/examples/v3arch/twisted/manager/ntfrcv/v2c-multiple-interfaces.py
+++ b/examples/v3arch/twisted/manager/ntfrcv/v2c-multiple-interfaces.py
@@ -1,21 +1,24 @@
-#
-# Notification Receiver
-#
-# Receive SNMP TRAP/INFORM messages with the following options:
-#
-# * SNMPv1/SNMPv2c
-# * with SNMP community "public"
-# * over IPv4/UDP, listening at 127.0.0.1:162
-# over IPv4/UDP, listening at 127.0.0.1:2162
-# * using Twisted framework for network transport
-# * print received data on stdout
-#
-# Either of the following Net-SNMP's commands will send notifications to this
-# receiver:
-#
-# $ snmptrap -v2c -c public 127.0.0.1:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
-# $ snmpinform -v2c -c public 127.0.0.1:2162 123 1.3.6.1.6.3.1.1.5.1
-#
+"""
+Serving multiple network interfaces
++++++++++++++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv1/SNMPv2c
+* with SNMP community "public"
+* listen on two local network interfaces:
+ * IPv4/UDP, listening at 127.0.0.1:162
+ * IPv4/UDP, listening at 127.0.0.1:2162
+* using Twisted framework for network transport
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v2c -c public 127.0.0.1:162 123 1.3.6.1.6.3.1.1.5.1 1.3.6.1.2.1.1.5.0 s test
+| $ snmpinform -v2c -c public 127.0.0.1:2162 123 1.3.6.1.6.3.1.1.5.1
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/examples/v3arch/twisted/manager/ntfrcv/v3-multiple-users.py b/examples/v3arch/twisted/manager/ntfrcv/v3-multiple-users.py
index 1192427..a82bd3d 100644
--- a/examples/v3arch/twisted/manager/ntfrcv/v3-multiple-users.py
+++ b/examples/v3arch/twisted/manager/ntfrcv/v3-multiple-users.py
@@ -1,24 +1,26 @@
-#
-# Notification Receiver
-#
-# Receive SNMP TRAP/INFORM messages with the following options:
-#
-# * SNMPv3
-# * with USM users:
-# 'usr-md5-des', auth: MD5, priv DES, ContextEngineId: 8000000001020304
-# 'usr-md5-none', auth: MD5, priv NONE, ContextEngineId: 8000000001020304
-# 'usr-sha-aes128', auth: SHA, priv AES, ContextEngineId: 8000000001020304
-# * over IPv4/UDP, listening at 127.0.0.1:162
-# * using Twisted framework for network transport
-# * print received data on stdout
-#
-# Either of the following Net-SNMP's commands will send notifications to this
-# receiver:
-#
-# $ snmptrap -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 -e 8000000001020304 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
-# $ snmptrap -v3 -u usr-md5-none -l authNoPriv -A authkey1 -e 8000000001020304 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
-# $ snmpinform -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
-#
+"""
+Multiple SNMP USM users
++++++++++++++++++++++++
+
+Receive SNMP TRAP/INFORM messages with the following options:
+
+* SNMPv3
+* with USM users:
+ * 'usr-md5-des', auth: MD5, priv DES, ContextEngineId: 8000000001020304
+ * 'usr-md5-none', auth: MD5, priv NONE, ContextEngineId: 8000000001020304
+ * 'usr-sha-aes128', auth: SHA, priv AES, ContextEngineId: 8000000001020304
+* over IPv4/UDP, listening at 127.0.0.1:162
+* using Twisted framework for network transport
+* print received data on stdout
+
+Either of the following Net-SNMP commands will send notifications to this
+receiver:
+
+| $ snmptrap -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 -e 8000000001020304 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+| $ snmptrap -v3 -u usr-md5-none -l authNoPriv -A authkey1 -e 8000000001020304 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+| $ snmpinform -v3 -u usr-sha-aes128 -l authPriv -a SHA -A authkey1 -x AES -X privkey1 127.0.0.1 123 1.3.6.1.6.3.1.1.5.1
+
+"""#
from twisted.internet import reactor
from pysnmp.entity import engine, config
from pysnmp.carrier.twisted.dgram import udp
diff --git a/pysnmp/entity/rfc3413/oneliner/auth.py b/pysnmp/entity/rfc3413/oneliner/auth.py
index 8c7e5f6..df1eafe 100644
--- a/pysnmp/entity/rfc3413/oneliner/auth.py
+++ b/pysnmp/entity/rfc3413/oneliner/auth.py
@@ -3,6 +3,49 @@ from pysnmp import error
from pyasn1.compat.octets import null
class CommunityData:
+ """Creates SNMP v1/v2c configuration entry.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derivatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`2576#section-5.3` for more information on the
+ *SNMP-COMMUNITY-MIB::snmpCommunityTable*.
+
+ Parameters
+ ----------
+ communityIndex : str
+ Unique index value of a row in snmpCommunityTable. If it is the
+ only positional parameter, it is taken as *communityName*.
+ communityName : str
+ SNMP v1/v2c community string.
+ mpModel : int
+ SNMP version - 0 for SNMPv1 and 1 for SNMPv2c.
+ contextEngineId : str
+ Indicates the location of the context in which management
+ information is accessed when using the community string
+ specified by the above communityName.
+ contextName : str
+ The context in which management information is accessed when
+ using the above communityName.
+ tag : str
+ Arbitrary string that specifies a set of transport endpoints
+ to which a notification may be sent using communityName above
+ (see also :RFC:`3413#section-4.1.4`).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.auth import CommunityData
+ >>> CommunityData('public')
+ CommunityData(communityIndex='s1410706889', communityName=<COMMUNITY>, mpModel=1, contextEngineId=None, contextName='', tag='')
+ >>> CommunityData('public', 'public')
+ CommunityData(communityIndex='public', communityName=<COMMUNITY>, mpModel=1, contextEngineId=None, contextName='', tag='')
+ >>>
+
+ """
mpModel = 1 # Default is SMIv2
securityModel = mpModel + 1
securityLevel = 'noAuthNoPriv'
@@ -65,8 +108,89 @@ class CommunityData:
tag is None and self.tag or tag,
securityName is None and self.securityName or securityName
)
-
+
+#: No Authentication Protocol.
+usmNoAuthProtocol = config.usmNoAuthProtocol
+#: The HMAC-MD5-96 Digest Authentication Protocol (:RFC:`3414#section-6`)
+usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
+#: The HMAC-SHA-96 Digest Authentication Protocol (:RFC:`3414#section-7`)
+usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
+
+#: No Privacy Protocol.
+usmNoPrivProtocol = config.usmNoPrivProtocol
+#: The CBC-DES Symmetric Encryption Protocol (:RFC:`3414#section-8`)
+usmDESPrivProtocol = config.usmDESPrivProtocol
+#: The 3DES-EDE Symmetric Encryption Protocol (`draft-reeder-snmpv3-usm-3desede-00 <https://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00#section-5>`_)
+usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
+#: The CFB128-AES-128 Symmetric Encryption Protocol (:RFC:`3826#section-3`)
+usmAesCfb128Protocol = config.usmAesCfb128Protocol
+#: The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)
+usmAesCfb192Protocol = config.usmAesCfb192Protocol
+#: The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)
+usmAesCfb256Protocol = config.usmAesCfb256Protocol
+
class UsmUserData:
+ """Creates SNMP v3 User Security Model (USM) configuration entry.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derivatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`3414#section-5` for more information on the
+ *SNMP-USER-BASED-SM-MIB::usmUserTable*.
+
+ Parameters
+ ----------
+ userName : str
+ A human readable string representing the name of the SNMP USM user.
+ authKey : str
+ Initial value of the secret authentication key. If not set,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoAuthProtocol`
+ is implied. If set and no *authProtocol* is specified,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmHMACMD5AuthProtocol`
+ takes effect.
+ privKey : str
+ Initial value of the secret encryption key. If not set,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoPrivProtocol`
+ is implied. If set and no *privProtocol* is specified,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmDESPrivProtocol`
+ takes effect.
+ authProtocol : tuple
+ An indication of whether messages sent on behalf of this USM user
+ can be authenticated, and if so, the type of authentication protocol
+ which is used.
+
+ Supported authentication protocol identifiers are:
+
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoAuthProtocol` (default is *authKey* not given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmHMACMD5AuthProtocol` (default if *authKey* is given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmHMACSHAAuthProtocol`
+ privProtocol : tuple
+ An indication of whether messages sent on behalf of this USM user
+ be encrypted, and if so, the type of encryption protocol which is used.
+
+ Supported encryption protocol identifiers are:
+
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoPrivProtocol` (default is *authKey* not given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmDESPrivProtocol` (default if *authKey* is given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usm3DESEDEPrivProtocol`
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmAesCfb128Protocol`
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmAesCfb192Protocol`
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmAesCfb256Protocol`
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.auth import UsmUserData
+ >>> UsmUserData('testuser', authKey='authenticationkey')
+ UsmUserData(userName='testuser', authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=(1,3,6,1,6,3,10,1,1,2), privProtocol=(1,3,6,1,6,3,10,1,2,1))
+ >>> UsmUserData('testuser', authKey='authenticationkey', privKey='encryptionkey')
+ UsmUserData(userName='testuser', authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=(1,3,6,1,6,3,10,1,1,2), privProtocol=(1,3,6,1,6,3,10,1,2,2))
+ >>>
+
+ """
authKey = privKey = None
authProtocol = config.usmNoAuthProtocol
privProtocol = config.usmNoPrivProtocol
diff --git a/pysnmp/entity/rfc3413/oneliner/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/cmdgen.py
index d646cf6..4f38d51 100644
--- a/pysnmp/entity/rfc3413/oneliner/cmdgen.py
+++ b/pysnmp/entity/rfc3413/oneliner/cmdgen.py
@@ -1,31 +1,19 @@
+from sys import version_info
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdgen
-from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType
-from pysnmp.entity.rfc3413.oneliner.auth import CommunityData, UsmUserData
-from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget, \
- Udp6TransportTarget, UnixTransportTarget
-from pysnmp.entity.rfc3413.oneliner.ctx import ContextData
+from pysnmp.smi.rfc1902 import *
+from pysnmp.entity.rfc3413.oneliner.auth import *
+from pysnmp.entity.rfc3413.oneliner.target import *
+from pysnmp.entity.rfc3413.oneliner.ctx import *
from pysnmp.proto import rfc1905, errind
from pysnmp.smi import view
from pysnmp import nextid, error
from pyasn1.type import univ, base
from pyasn1.compat.octets import null
+
# obsolete, compatibility symbols
from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable
-# Auth protocol
-usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
-usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
-usmNoAuthProtocol = config.usmNoAuthProtocol
-
-# Privacy protocol
-usmDESPrivProtocol = config.usmDESPrivProtocol
-usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
-usmAesCfb128Protocol = config.usmAesCfb128Protocol
-usmAesCfb192Protocol = config.usmAesCfb192Protocol
-usmAesCfb256Protocol = config.usmAesCfb256Protocol
-usmNoPrivProtocol = config.usmNoPrivProtocol
-
# SNMP engine
SnmpEngine = engine.SnmpEngine
@@ -226,29 +214,21 @@ class AsyncCommandGenerator:
return __varBinds
- def unmakeVarBinds(self, snmpEngine, varBinds, lookupNames, lookupValues):
- if lookupNames or lookupValues:
+ def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=False):
+ if lookupMib:
mibViewController = self.getMibViewController(snmpEngine)
varBinds = [ ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds ]
return varBinds
- def makeVarBindsHead(self, snmpEngine, varNames):
- return [
- x[0] for x in self.makeVarBinds(
- snmpEngine,
- [ (x, univ.Null('')) for x in varNames ]
- )
- ]
-
# Async SNMP apps
def getCmd(self, snmpEngine, authData, transportTarget, contextData,
- varBinds, cbInfo, lookupNames=False, lookupValues=False):
+ varBinds, cbInfo, lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBinds, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
@@ -256,7 +236,7 @@ class AsyncCommandGenerator:
errorStatus,
errorIndex,
self.unmakeVarBinds(
- snmpEngine, varBinds, lookupNames, lookupValues
+ snmpEngine, varBinds, lookupMib
),
cbCtx
)
@@ -273,15 +253,15 @@ class AsyncCommandGenerator:
contextData.contextName,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
def setCmd(self, snmpEngine, authData, transportTarget, contextData,
- varBinds, cbInfo, lookupNames=False, lookupValues=False):
+ varBinds, cbInfo, lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBinds, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
@@ -289,7 +269,7 @@ class AsyncCommandGenerator:
errorStatus,
errorIndex,
self.unmakeVarBinds(
- snmpEngine, varBinds, lookupNames, lookupValues
+ snmpEngine, varBinds, lookupMib
),
cbCtx
)
@@ -306,22 +286,22 @@ class AsyncCommandGenerator:
contextData.contextName,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
def nextCmd(self, snmpEngine, authData, transportTarget, contextData,
- varBinds, cbInfo, lookupNames=False, lookupValues=False):
+ varBinds, cbInfo, lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBindTable, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
errorIndication,
errorStatus,
errorIndex,
- [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupNames, lookupValues) for varBindTableRow in varBindTable ],
+ [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupMib) for varBindTableRow in varBindTable ],
cbCtx
)
@@ -335,23 +315,23 @@ class AsyncCommandGenerator:
contextData.contextEngineId, contextData.contextName,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
def bulkCmd(self, snmpEngine, authData, transportTarget, contextData,
nonRepeaters, maxRepetitions, varBinds, cbInfo,
- lookupNames=False, lookupValues=False):
+ lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBindTable, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
errorIndication,
errorStatus,
errorIndex,
- [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupNames, lookupValues) for varBindTableRow in varBindTable ],
+ [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupMib) for varBindTableRow in varBindTable ],
cbCtx
)
@@ -367,239 +347,9 @@ class AsyncCommandGenerator:
nonRepeaters, maxRepetitions,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
-# Synchronous one-liner SNMP apps
-
-def getCmd(snmpEngine, authData, transportTarget, contextData,
- *varBinds, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBinds, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBinds'] = varBinds
-
- cbCtx = {}
-
- AsyncCommandGenerator().getCmd(
- snmpEngine,
- authData,
- transportTarget,
- contextData,
- varBinds,
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues')
- )
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- yield cbCtx['errorIndication'], \
- cbCtx['errorStatus'], cbCtx['errorIndex'], \
- cbCtx['varBinds']
-
-def setCmd(snmpEngine, authData, transportTarget, contextData,
- *varBinds, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBinds, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBinds'] = varBinds
-
- cbCtx = {}
-
- AsyncCommandGenerator().setCmd(
- snmpEngine,
- authData,
- transportTarget,
- contextData,
- varBinds,
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues')
- )
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- yield cbCtx['errorIndication'], \
- cbCtx['errorStatus'], cbCtx['errorIndex'], \
- cbCtx['varBinds']
-
-def nextCmd(snmpEngine, authData, transportTarget, contextData,
- *varBinds, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBindTable, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBindTable'] = varBindTable
-
- lookupNames = kwargs.get('lookupNames', False)
- lookupValues = kwargs.get('lookupValues', False)
- lexicographicMode = kwargs.get('lexicographicMode', False)
- ignoreNonIncreasingOid = kwargs.get('ignoreNonIncreasingOid', False)
- maxRows = kwargs.get('maxRows', 0)
- maxCalls = kwargs.get('maxCalls', 0)
-
- cbCtx = {}
-
- cmdGen = AsyncCommandGenerator()
-
- initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds) ]
-
- totalRows = totalCalls = 0
-
- while True:
- cmdGen.nextCmd(snmpEngine,
- authData,
- transportTarget,
- contextData,
- [ (x[0], univ.Null()) for x in varBinds ],
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues'))
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- errorIndication = cbCtx['errorIndication']
- errorStatus = cbCtx['errorStatus']
- errorIndex = cbCtx['errorIndex']
-
- if ignoreNonIncreasingOid and errorIndication and \
- isinstance(errorIndication, errind.OidNotIncreasing):
- errorIndication = None
- if errorStatus or errorIndication:
- 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
- continue
- else:
- varBinds = cbCtx['varBindTable'] and cbCtx['varBindTable'][0]
- for idx, varBind in enumerate(varBinds):
- name, val = varBind
- if not isinstance(val, univ.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, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBindTable, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBindTable'] = varBindTable
-
- lookupNames = kwargs.get('lookupNames', False)
- lookupValues = kwargs.get('lookupValues', False)
- lexicographicMode = kwargs.get('lexicographicMode', False)
- ignoreNonIncreasingOid = kwargs.get('ignoreNonIncreasingOid', False)
- maxRows = kwargs.get('maxRows', 0)
- maxCalls = kwargs.get('maxCalls', 0)
-
- cbCtx = {}
-
- cmdGen = AsyncCommandGenerator()
-
- initialVars = [ x[0] for x in cmdGen.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], univ.Null()) for x in varBinds ],
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues'))
-
- 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 errorStatus or errorIndication:
- 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 []
- continue
- 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, rfc1905.endOfMibView
- continue
- stopFlag = False
- if isinstance(val, univ.Null):
- nullVarBinds[j] = True
- elif not lexicographicMode and \
- not initialVars[j].isPrefixOf(name):
- varBindTable[i][j] = name, rfc1905.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
-
#
# The rest of code in this file belongs to obsolete, compatibility wrappers.
# Never use interfaces below for new applications!
@@ -641,7 +391,7 @@ class AsynCommandGenerator:
def unmakeVarBinds(self, varBinds, lookupNames, lookupValues):
return self.__asyncCmdGen.unmakeVarBinds(
- self.snmpEngine, varBinds, lookupNames, lookupValues
+ self.snmpEngine, varBinds, lookupNames or lookupValues
)
def getCmd(self, authData, transportTarget, varNames, cbInfo,
@@ -668,7 +418,7 @@ class AsynCommandGenerator:
ContextData(contextEngineId, contextName),
[(x, self._null) for x in varNames],
cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncGetCmd = getCmd
@@ -695,7 +445,7 @@ class AsynCommandGenerator:
self.snmpEngine,
authData, transportTarget,
ContextData(contextEngineId, contextName), varBinds, cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncSetCmd = setCmd
@@ -724,7 +474,7 @@ class AsynCommandGenerator:
ContextData(contextEngineId, contextName),
[(x, self._null) for x in varNames],
cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncNextCmd = nextCmd
@@ -755,7 +505,7 @@ class AsynCommandGenerator:
nonRepeaters, maxRepetitions,
[(x, self._null) for x in varNames],
cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncBulkCmd = bulkCmd
@@ -816,3 +566,8 @@ class CommandGenerator:
return errorIndication, errorStatus, errorIndex, varBindTable
+# circular module import dependency
+if version_info[:2] < (2, 6):
+ from pysnmp.entity.rfc3413.oneliner.sync.compat.cmdgen import *
+else:
+ from pysnmp.entity.rfc3413.oneliner.sync.cmdgen import *
diff --git a/pysnmp/entity/rfc3413/oneliner/ctx.py b/pysnmp/entity/rfc3413/oneliner/ctx.py
index 3449912..528a2b0 100644
--- a/pysnmp/entity/rfc3413/oneliner/ctx.py
+++ b/pysnmp/entity/rfc3413/oneliner/ctx.py
@@ -1,6 +1,41 @@
from pyasn1.compat.octets import null
class ContextData:
+ """Creates UDP/IPv6 configuration entry and initialize socket API if needed.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derevatives for forming SNMP PDU and also adding new entries to
+ Local Configuration Datastore (LCD) in order to support SNMPv1/v2c with
+ SNMPv3 interoperability.
+
+ See :RFC:`3411#section-4.1` for SNMP Context details.
+
+ Parameters
+ ----------
+ contextEngineId : str
+ Uniquely identifies an SNMP entity that may realize an instance of
+ a MIB with a particular contextName (:RFC:`3411#section-3.3.2`).
+ More frequently than not, ContextEngineID is the same as
+ authoritative SnmpEngineID, however if SNMP Engine serves multiple
+ SNMP Entities, their ContextEngineIDs would be distinct.
+ Default is authoritative SNMP Engine ID.
+ contextName : str
+ Used to name an instance of MIB (:RFC:`3411#section-3.3.3`).
+ Default is empty string.
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.ctx import ContextData
+ >>> ContextData()
+ ContextData(contextEngineId=None, contextName='')
+ >>> ContextData(OctetString(hexValue='01020ABBA0'))
+ ContextData(contextEngineId=OctetString(hexValue='01020abba0'), contextName='')
+ >>> ContextData(contextName='mycontext')
+ ContextData(contextEngineId=None, contextName='mycontext')
+
+ """
def __init__(self, contextEngineId=None, contextName=null):
self.contextEngineId = contextEngineId
self.contextName = contextName
diff --git a/pysnmp/entity/rfc3413/oneliner/ntforg.py b/pysnmp/entity/rfc3413/oneliner/ntforg.py
index 6ff9215..96a8456 100644
--- a/pysnmp/entity/rfc3413/oneliner/ntforg.py
+++ b/pysnmp/entity/rfc3413/oneliner/ntforg.py
@@ -1,30 +1,16 @@
from pyasn1.compat.octets import null
from pysnmp import nextid, error
from pysnmp.entity import engine, config
-from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType, NotificationType
+from pysnmp.smi.rfc1902 import *
from pysnmp.entity.rfc3413 import ntforg, context
-from pysnmp.entity.rfc3413.oneliner.auth import CommunityData, UsmUserData
-from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget, \
- Udp6TransportTarget, UnixTransportTarget
+from pysnmp.entity.rfc3413.oneliner.auth import *
+from pysnmp.entity.rfc3413.oneliner.target import *
+from pysnmp.entity.rfc3413.oneliner.ctx import *
from pysnmp.entity.rfc3413.oneliner import cmdgen
# obsolete, compatibility symbols
from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable
-# Auth protocol
-usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
-usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
-usmNoAuthProtocol = config.usmNoAuthProtocol
-
-# Privacy protocol
-usmDESPrivProtocol = config.usmDESPrivProtocol
-usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
-usmAesCfb128Protocol = config.usmAesCfb128Protocol
-usmAesCfb192Protocol = config.usmAesCfb192Protocol
-usmAesCfb256Protocol = config.usmAesCfb256Protocol
-usmNoPrivProtocol = config.usmNoPrivProtocol
-
SnmpEngine = engine.SnmpEngine
-ContextData = cmdgen.ContextData
nextID = nextid.Integer(0xffffffff)
@@ -135,8 +121,8 @@ class AsyncNotificationOriginator:
__varBinds.append(varBind.resolveWithMib(mibViewController))
return __varBinds
- def unmakeVarBinds(self, snmpEngine, varBinds, lookupNames, lookupValues):
- if lookupNames or lookupValues:
+ def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=False):
+ if lookupMib:
mibViewController = self.getMibViewController(snmpEngine)
varBinds = [ ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds ]
return varBinds
@@ -144,20 +130,20 @@ class AsyncNotificationOriginator:
def sendNotification(self, snmpEngine,
authData, transportTarget, contextData,
notifyType,
- varBinds=(),
+ varBinds,
cbInfo=(None, None),
- lookupNames=False, lookupValues=False):
+ lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle, errorIndication,
errorStatus, errorIndex, varBinds, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun and cbFun(
snmpEngine,
sendRequestHandle,
errorIndication,
errorStatus, errorIndex,
self.unmakeVarBinds(
- snmpEngine, varBinds, lookupNames, lookupValues
+ snmpEngine, varBinds, lookupMib
),
cbCtx
)
@@ -176,43 +162,7 @@ class AsyncNotificationOriginator:
snmpEngine, authData, transportTarget, notifyType
)
- return ntforg.NotificationOriginator().sendVarBinds(snmpEngine, notifyName, contextData.contextEngineId, contextData.contextName, self.makeVarBinds(snmpEngine, varBinds), __cbFun, (lookupNames, lookupValues, cbFun, cbCtx))
-
-#
-# Synchronous one-liner Notification Originator application
-#
-
-def sendNotification(snmpEngine, authData, transportTarget, contextData,
- notifyType, notificationType, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBinds, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBinds'] = varBinds
-
- cbCtx = {}
-
- AsyncNotificationOriginator().sendNotification(
- snmpEngine,
- authData,
- transportTarget,
- contextData,
- notifyType,
- notificationType,
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues')
- )
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- if cbCtx:
- yield cbCtx['errorIndication'], \
- cbCtx['errorStatus'], cbCtx['errorIndex'], \
- cbCtx['varBinds']
+ return ntforg.NotificationOriginator().sendVarBinds(snmpEngine, notifyName, contextData.contextEngineId, contextData.contextName, self.makeVarBinds(snmpEngine, varBinds), __cbFun, (lookupMib, cbFun, cbCtx))
#
# The rest of code in this file belongs to obsolete, compatibility wrappers.
@@ -256,6 +206,16 @@ class AsynNotificationOriginator:
def uncfgNtfOrg(self, authData=None):
return self.__asyncNtfOrg.uncfgNtfOrg(self.snmpEngine, authData)
+ def makeVarBinds(self, varBinds):
+ return self.__asyncNtfOrg.makeVarBinds(
+ self.snmpEngine, varBinds
+ )
+
+ def unmakeVarBinds(self, varBinds, lookupNames, lookupValues):
+ return self.__asyncNtfOrg.unmakeVarBinds(
+ self.snmpEngine, varBinds, lookupNames or lookupValues
+ )
+
def sendNotification(self, authData, transportTarget,
notifyType, notificationType,
varBinds=(), # legacy, use NotificationType instead
@@ -306,7 +266,7 @@ class AsynNotificationOriginator:
contextName),
notifyType, notificationType.addVarBinds(*varBinds),
(__cbFun, cbInfo),
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncSendNotification = sendNotification
@@ -328,3 +288,10 @@ class NotificationOriginator:
notificationType.addVarBinds(*varBinds),
**kwargs):
return x
+
+# circular module import dependency
+from sys import version_info
+if version_info[:2] < (2, 6):
+ from pysnmp.entity.rfc3413.oneliner.sync.compat.ntforg import *
+else:
+ from pysnmp.entity.rfc3413.oneliner.sync.ntforg import *
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/__init__.py b/pysnmp/entity/rfc3413/oneliner/sync/__init__.py
new file mode 100644
index 0000000..8c3066b
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/__init__.py
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py
new file mode 100644
index 0000000..b3a42d7
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py
@@ -0,0 +1,602 @@
+from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+
+if version_info[:2] < (2, 6):
+ def next(iter):
+ return iter.next()
+
+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.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.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
+ Non-zero 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.entity.rfc3413.oneliner.cmdgen 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ 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.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.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
+ Non-zero 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.entity.rfc3413.oneliner.cmdgen 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ 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.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.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
+ Non-zero 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.entity.rfc3413.oneliner.cmdgen 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds) ]
+
+ totalRows = totalCalls = 0
+
+ while True:
+ if varBinds:
+ cmdGen.nextCmd(snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ [ (x[0], univ.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, univ.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 cmdGen.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.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.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
+ Non-zero 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.entity.rfc3413.oneliner.cmdgen 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.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], univ.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, rfc1905.endOfMibView
+ continue
+ stopFlag = False
+ if isinstance(val, univ.Null):
+ nullVarBinds[j] = True
+ elif not lexicographicMode and \
+ not initialVars[j].isPrefixOf(name):
+ varBindTable[i][j] = name, rfc1905.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/entity/rfc3413/oneliner/sync/compat/__init__.py b/pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py
new file mode 100644
index 0000000..8c3066b
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py
new file mode 100644
index 0000000..ebe3296
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py
@@ -0,0 +1,256 @@
+from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+
+# Synchronous one-liner SNMP Command Generator apps
+
+if version_info[:2] < (2, 6):
+ 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ 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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds) ]
+
+ totalRows = totalCalls = 0
+
+ while True:
+ cmdGen.nextCmd(snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ [ (x[0], univ.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, univ.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 = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.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], univ.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, rfc1905.endOfMibView
+ continue
+ stopFlag = False
+ if isinstance(val, univ.Null):
+ nullVarBinds[j] = True
+ elif not lexicographicMode and \
+ not initialVars[j].isPrefixOf(name):
+ varBindTable[i][j] = name, rfc1905.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/entity/rfc3413/oneliner/sync/compat/ntforg.py b/pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py
new file mode 100644
index 0000000..7a9291c
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py
@@ -0,0 +1,48 @@
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+
+if version_info[:2] < (2, 6):
+ 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 = {}
+
+ ntfOrg = AsyncNotificationOriginator()
+
+ 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/entity/rfc3413/oneliner/sync/ntforg.py b/pysnmp/entity/rfc3413/oneliner/sync/ntforg.py
new file mode 100644
index 0000000..16f3930
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/ntforg.py
@@ -0,0 +1,126 @@
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+
+if version_info[:2] < (2, 6):
+ def next(iter):
+ return iter.next()
+
+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:`3413#section-3.3`). The iterator blocks waiting for
+ INFORM acknowlegement to arrive or error to occur.
+
+ Parameters
+ ----------
+ snmpEngine : :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.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
+ Non-zero 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.entity.rfc3413.oneliner.ntforg 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 = {}
+
+ ntfOrg = AsyncNotificationOriginator()
+
+ while True:
+ if varBinds:
+ ntfOrg.sendNotification(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ notifyType,
+ varBinds,
+ cbInfo=(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
diff --git a/pysnmp/entity/rfc3413/oneliner/target.py b/pysnmp/entity/rfc3413/oneliner/target.py
index 04ecb5f..ecb7882 100644
--- a/pysnmp/entity/rfc3413/oneliner/target.py
+++ b/pysnmp/entity/rfc3413/oneliner/target.py
@@ -37,6 +37,42 @@ class _AbstractTransportTarget:
def _resolveAddr(self, transportAddr): raise NotImplementedError()
class UdpTransportTarget(_AbstractTransportTarget):
+ """Creates UDP/IPv4 configuration entry and initialize socket API if needed.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derevatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`1906#section-3` for more information on the UDP transport mapping.
+
+ Parameters
+ ----------
+ transportAddr : tuple
+ Indicates remote address in Python :py:mod:`socket` module format
+ which is a tuple of FQDN, port where FQDN is a string representing
+ either hostname or IPv4 address in quad-dotted form, port is an
+ integer.
+ timeout : int
+ Response timeout in seconds.
+ retries : int
+ Maximum number of request retries, 0 retries means just a single
+ request.
+ tagList : str
+ Arbitrary string that contains a list of tag values which are used
+ to select target addresses for a particular operation
+ (:RFC:`3413#section-4.1.4`).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget
+ >>> UdpTransportTarget(('demo.snmplabs.com', 161))
+ UdpTransportTarget(('195.218.195.228', 161), timeout=1, retries=5, tagList='')
+ >>>
+
+ """
transportDomain = udp.domainName
protoTransport = udp.UdpSocketTransport
def _resolveAddr(self, transportAddr):
@@ -50,6 +86,51 @@ class UdpTransportTarget(_AbstractTransportTarget):
raise error.PySnmpError('Bad IPv4/UDP transport address %s: %s' % ('@'.join([ str(x) for x in transportAddr ]), sys.exc_info()[1]))
class Udp6TransportTarget(_AbstractTransportTarget):
+ """Creates UDP/IPv6 configuration entry and initialize socket API if needed.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derevatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`1906#section-3`, :RFC:`2851#section-4` for more information
+ on the UDP and IPv6 transport mapping.
+
+ Parameters
+ ----------
+ transportAddr : tuple
+ Indicates remote address in Python :py:mod:`socket` module format
+ which is a tuple of FQDN, port where FQDN is a string representing
+ either hostname or IPv6 address in one of three conventional forms
+ (:RFC:`1924#section-3`), port is an integer.
+ timeout : int
+ Response timeout in seconds.
+ retries : int
+ Maximum number of request retries, 0 retries means just a single
+ request.
+ tagList : str
+ Arbitrary string that contains a list of tag values which are used
+ to select target addresses for a particular operation
+ (:RFC:`3413#section-4.1.4`).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.target import Udp6TransportTarget
+ >>> Udp6TransportTarget(('google.com', 161))
+ Udp6TransportTarget(('2a00:1450:4014:80a::100e', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', 161))
+ Udp6TransportTarget(('fedc:ba98:7654:3210:fedc:ba98:7654:3210', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('1080:0:0:0:8:800:200C:417A', 161))
+ Udp6TransportTarget(('1080::8:800:200c:417a', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('::0', 161))
+ Udp6TransportTarget(('::', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('::', 161))
+ Udp6TransportTarget(('::', 161), timeout=1, retries=5, tagList='')
+ >>>
+
+ """
transportDomain = udp6.domainName
protoTransport = udp6.Udp6SocketTransport
def _resolveAddr(self, transportAddr):
diff --git a/pysnmp/smi/rfc1902.py b/pysnmp/smi/rfc1902.py
index 8d66f25..b61f5a0 100644
--- a/pysnmp/smi/rfc1902.py
+++ b/pysnmp/smi/rfc1902.py
@@ -8,17 +8,83 @@ from pyasn1.type.base import AbstractSimpleAsn1Item
from pyasn1.error import PyAsn1Error
from pysnmp import debug
-#
-# An OID-like object that embeds MIB resolution.
-#
-# Valid initializers include:
-# ObjectIdentity('1.3.6.1.2.1.1.1.0')
-# ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0')
-# ObjectIdentity('SNMPv2-MIB', 'system')
-# ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
-# ObjectIdentity('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123)
-#
+# expose SNMP types in this namespace for convenience
+Integer = rfc1902.Integer
+Integer32 = rfc1902.Integer32
+OctetString = rfc1902.OctetString
+ObjectIdentifier = rfc1902.ObjectIdentifier
+IpAddress = rfc1902.IpAddress
+Counter32 = rfc1902.Counter32
+Gauge32 = rfc1902.Gauge32
+Unsigned32 = rfc1902.Unsigned32
+TimeTicks = rfc1902.TimeTicks
+Opaque = rfc1902.Opaque
+Counter64 = rfc1902.Counter64
+Bits = rfc1902.Bits
+ObjectName = rfc1902.ObjectName
+
class ObjectIdentity:
+ """Create an object representing MIB variable ID.
+
+ At the protocol level, MIB variable is only identified by an OID.
+ However, when interacting with humans, MIB variable can also be referred
+ to by its MIB name. The *ObjectIdentity* class supports various forms
+ of MIB variable identification, providing automatic conversion from
+ one to others. At the same time *ObjectIdentity* objects behave like
+ :py:obj:`tuples` of py:obj:`int` sub-OIDs.
+
+ See :RFC:`1902#section-2` for more information on OBJECT-IDENTITY
+ SMI definitions.
+
+ Parameters
+ ----------
+ args
+ initial MIB variable identity. Recognized variants:
+
+ * single :py:obj:`tuple` or integers representing OID
+ * single :py:obj:`str` representing OID in dot-separated
+ integers form
+ * single :py:obj:`str` representing MIB variable in
+ dot-separated labels form
+ * single :py:obj:`str` representing MIB name. First variable
+ defined in MIB is assumed.
+ * pair of :py:obj:`str` representing MIB name and variable name
+ * pair of :py:obj:`str` representing MIB name and variable name
+ followed by an arbitrary number of :py:obj:`str` and/or
+ :py:obj:`int` values representing MIB variable instance
+ identification.
+
+ Other parameters
+ ----------------
+ kwargs
+ MIB resolution options:
+
+ * whenever only MIB name is given, resolve into last variable defined
+ in MIB if last=True. Otherwise resolves to first variable (default).
+
+ Notes
+ -----
+ Actual conversion between MIB variable representation formats occurs
+ upon :py:meth:`~pysnmp.smi.rfc1902.ObjectIdentity.resolveWithMib`
+ invocation.
+
+ Examples
+ --------
+ >>> from pysnmp.smi.rfc1902 import ObjectIdentity
+ >>> ObjectIdentity((1, 3, 6, 1, 2, 1, 1, 1, 0))
+ ObjectIdentity((1, 3, 6, 1, 2, 1, 1, 1, 0))
+ >>> ObjectIdentity('1.3.6.1.2.1.1.1.0')
+ ObjectIdentity('1.3.6.1.2.1.1.1.0')
+ >>> ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0')
+ ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0')
+ >>> ObjectIdentity('SNMPv2-MIB', 'system')
+ ObjectIdentity('SNMPv2-MIB', 'system')
+ >>> ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ >>> ObjectIdentity('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123)
+ ObjectIdentity('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123)
+
+ """
stDirty, stClean = 1, 2
def __init__(self, *args, **kwargs):
@@ -28,22 +94,95 @@ class ObjectIdentity:
self.__asn1SourcesToAdd = self.__asn1SourcesOptions = None
self.__state = self.stDirty
- #
- # public API
- #
def getMibSymbol(self):
+ """Returns MIB variable symbolic identification.
+
+ Returns
+ -------
+ str
+ MIB module name
+ str
+ MIB variable symbolic name
+ : :py:class:`~pysnmp.proto.rfc1902.ObjectName`
+ class instance representing MIB variable instance index.
+
+ Raises
+ ------
+ SmiError
+ If MIB variable conversion has not been performed.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('1.3.6.1.2.1.1.1.0')
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ >>> objectIdentity.getMibSymbol()
+ ('SNMPv2-MIB', 'sysDescr', (0,))
+ >>>
+
+ """
if self.__state & self.stClean:
return self.__modName, self.__symName, self.__indices
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
def getOid(self):
+ """Returns OID identifying MIB variable.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.proto.rfc1902.ObjectName`
+ full OID identifying MIB variable including possible index part.
+
+ Raises
+ ------
+ SmiError
+ If MIB variable conversion has not been performed.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ >>> objectIdentity.getOid()
+ ObjectName('1.3.6.1.2.1.1.1.0')
+ >>>
+
+ """
if self.__state & self.stClean:
return self.__oid
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
def getLabel(self):
+ """Returns symbolic path to this MIB variable.
+
+ Meaning a sequence of symbolic identifications for each of parent
+ MIB objects in MIB tree.
+
+ Returns
+ -------
+ tuple
+ sequence of names of nodes in a MIB tree from the top of the tree
+ towards this MIB variable.
+
+ Raises
+ ------
+ SmiError
+ If MIB variable conversion has not been performed.
+
+ Notes
+ -----
+ Returned sequence may not contain full path to this MIB variable
+ if some symbols are now known at the moment of MIB look up.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ >>> objectIdentity.getOid()
+ ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'system', 'sysDescr')
+ >>>
+
+ """
if self.__state & self.stClean:
return self.__label
else:
@@ -63,6 +202,35 @@ class ObjectIdentity:
#
def addAsn1MibSource(self, *asn1Sources, **kwargs):
+ """Adds path to a repository to search ASN.1 MIB files.
+
+ Parameters
+ ----------
+ *asn1Sources :
+ one or more URL in form of :py:obj:`str` identifying local or
+ remote ASN.1 MIB repositories. Path must include the *@mib@*
+ component which will be replaced with MIB module name at the
+ time of search.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ reference to itself
+
+ Notes
+ -----
+ Please refer to :py:class:`~pysmi.reader.localfile.FileReader`,
+ :py:class:`~pysmi.reader.httpclient.HttpReader` and
+ :py:class:`~pysmi.reader.ftpclient.FtpReader` classes for
+ in-depth information on ASN.1 MIB lookup.
+
+ Examples
+ --------
+ >>> ObjectIdentity('SNMPv2-MIB', 'sysDescr').addAsn1Source('http://mibs.snmplabs.com/asn1/@mib@')
+ ObjectIdentity('SNMPv2-MIB', 'sysDescr')
+ >>>
+
+ """
if self.__asn1SourcesToAdd is None:
self.__asn1SourcesToAdd = asn1Sources
else:
@@ -91,6 +259,47 @@ class ObjectIdentity:
# this would eventually be called by an entity which posses a
# reference to MibViewController
def resolveWithMib(self, mibViewController):
+ """Perform MIB variable ID conversion.
+
+ Parameters
+ ----------
+ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController`
+ class instance representing MIB browsing functionality.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ reference to itself
+
+ Raises
+ ------
+ SmiError
+ In case of fatal MIB hanling errora
+
+ Notes
+ -----
+ Calling this method might cause the following sequence of
+ events (exact details depends on many factors):
+
+ * ASN.1 MIB file downloaded and handed over to
+ :py:class:`~pysmi.compiler.MibCompiler` for conversion into
+ Python MIB module (based on pysnmp classes)
+ * Python MIB module is imported by SNMP engine, internal indices
+ created
+ * :py:class:`~pysnmp.smi.view.MibViewController` looks up the
+ rest of MIB identification information based on whatever information
+ is already available, :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ class instance
+ gets updated and ready for further use.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('SNMPv2-MIB', 'sysDescr')
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ ObjectIdentity('SNMPv2-MIB', 'sysDescr')
+ >>>
+
+ """
if self.__mibSourcesToAdd is not None:
debug.logger & debug.flagMIB and debug.logger('adding MIB sources %s' % ', '.join(self.__mibSourcesToAdd))
mibViewController.mibBuilder.addMibSources(
@@ -374,6 +583,63 @@ class ObjectIdentity:
# A two-element sequence of ObjectIdentity and SNMP data type object
class ObjectType:
+ """Create an object representing MIB variable.
+
+ Instances of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class are
+ containters incorporating :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ class instance (identifying MIB variable) and optional value belonging
+ to one of SNMP types (:RFC:`1902`).
+
+ Typical MIB variable is defined like this (from *SNMPv2-MIB.txt*):
+
+ .. code-block:: bash
+
+ sysDescr OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A textual description of the entity. This value should..."
+ ::= { system 1 }
+
+ Corresponding ObjectType instantiation would look like this:
+
+ .. code-block:: python
+
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'), 'Linux i386 box')
+
+ In order to behave like SNMP variable-binding (:RFC:`1157#section-4.1.1`),
+ :py:class:`~pysnmp.smi.rfc1902.ObjectType` objects also support
+ sequence protocol addressing `objectIdentity` as its 0-th element
+ and `objectSyntax` as 1-st.
+
+ See :RFC:`1902#section-2` for more information on OBJECT-TYPE SMI
+ definitions.
+
+ Parameters
+ ----------
+ objectIdentity : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ Class instance representing MIB variable identification.
+ objectSyntax :
+ Represents a value associated with this MIB variable. Values of
+ built-in Python types will be automatically converted into SNMP
+ object as specified in OBJECT-TYPE->SYNTAX field.
+
+ Notes
+ -----
+ Actual conversion between MIB variable representation formats occurs
+ upon :py:meth:`~pysnmp.smi.rfc1902.ObjectType.resolveWithMib`
+ invocation.
+
+ Examples
+ --------
+ >>> from pysnmp.smi.rfc1902 import *
+ >>> ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))
+ ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'), Null())
+ >>> ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), 'Linux i386')
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), 'Linux i386')
+
+ """
stDirty, stClean = 1, 2
def __init__(self, objectIdentity, objectSyntax=rfc1905.unSpecified):
if not isinstance(objectIdentity, ObjectIdentity):
@@ -387,6 +653,9 @@ class ObjectType:
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
+ def __str__(self):
+ return self.prettyPrint()
+
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, ', '.join([ repr(x) for x in self.__args]))
@@ -394,6 +663,39 @@ class ObjectType:
return self.__state & self.stClean
def resolveWithMib(self, mibViewController):
+ """Perform MIB variable ID and associated value conversion.
+
+ Parameters
+ ----------
+ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController`
+ class instance representing MIB browsing functionality.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ reference to itself
+
+ Raises
+ ------
+ SmiError
+ In case of fatal MIB hanling errora
+
+ Notes
+ -----
+ Calling this method involves
+ :py:meth:`~pysnmp.smi.rfc1902.ObjectIdentity.resolveWithMib`
+ method invocation.
+
+ Examples
+ --------
+ >>> objectType = ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'), 'Linux i386')
+ >>> objectType.resolveWithMib(mibViewController)
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'), DisplayString('Linux i386'))
+ >>> str(objectType)
+ 'SNMPv2-MIB::sysDescr."0" = Linux i386'
+ >>>
+
+ """
if self.__state & self.stClean:
return self
@@ -433,8 +735,71 @@ class ObjectType:
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
-# A sequence of ObjectType's
class NotificationType:
+ """Create an object representing SNMP Notification.
+
+ Instances of :py:class:`~pysnmp.smi.rfc1902.NotificationType` class are
+ containters incorporating :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ class instance (identifying particular notification) and a collection
+ of MIB variables IDs that
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.NotificationOriginator`
+ should gather and put into notification message.
+
+ Typical notification is defined like this (from *IF-MIB.txt*):
+
+ .. code-block:: bash
+
+ linkDown NOTIFICATION-TYPE
+ OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
+ STATUS current
+ DESCRIPTION
+ "A linkDown trap signifies that the SNMP entity..."
+ ::= { snmpTraps 3 }
+
+ Corresponding NotificationType instantiation would look like this:
+
+ .. code-block:: python
+
+ NotificationType(ObjectIdentity('IF-MIB', 'linkDown'))
+
+ To retain similarity with SNMP variable-bindings,
+ :py:class:`~pysnmp.smi.rfc1902.NotificationType` objects behave like
+ a sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances.
+
+ See :RFC:`1902#section-2` for more information on NOTIFICATION-TYPE SMI
+ definitions.
+
+ Parameters
+ ----------
+ objectIdentity : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ Class instance representing MIB notification type identification.
+ instanceIndex : :py:class:`~pysnmp.proto.rfc1902.ObjectName`
+ Trailing part of MIB variables OID identification that represents
+ concrete instance of a MIB variable. When notification is prepared,
+ `instanceIndex` is appended to each MIB variable identification
+ listed in NOTIFICATION-TYPE->OBJECTS clause.
+ objects : dict
+ Dictionary-like object that may return values by OID key. The
+ `objects` dictionary is consulted when notification is being
+ prepared. OIDs are taken from MIB variables listed in
+ NOTIFICATION-TYPE->OBJECTS with `instanceIndex` part appended.
+
+ Notes
+ -----
+ Actual notification type and MIB variables look up occurs
+ upon :py:meth:`~pysnmp.smi.rfc1902.NotificationType.resolveWithMib`
+ invocation.
+
+ Examples
+ --------
+ >>> from pysnmp.smi.rfc1902 import *
+ >>> NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.3'))
+ NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.3'), (), {})
+ >>> NotificationType(ObjectIdentity('IP-MIB', 'linkDown'), ObjectName('3.5))
+ NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.3'), ObjectName('3.5'), {})
+
+ """
stDirty, stClean = 1, 2
def __init__(self, objectIdentity, instanceIndex=(), objects={}):
if not isinstance(objectIdentity, ObjectIdentity):
@@ -456,6 +821,33 @@ class NotificationType:
return '%s(%r, %r, %r)' % (self.__class__.__name__, self.__objectIdentity, self.__instanceIndex, self.__objects)
def addVarBinds(self, *varBinds):
+ """Appends variable-binding to notification.
+
+ Parameters
+ ----------
+ *varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ One or more :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.NotificationType`
+ reference to itself
+
+ Notes
+ -----
+ This method can be used to add custom variable-bindings to
+ notification message in addition to MIB variables specified
+ in NOTIFICATION-TYPE->OBJECTS clause.
+
+ Examples
+ --------
+ >>> nt = NotificationType(ObjectIdentity('IP-MIB', 'linkDown'))
+ >>> nt.addVarBinds(ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
+ NotificationType(ObjectIdentity('IP-MIB', 'linkDown'), (), {})
+ >>>
+
+ """
debug.logger & debug.flagMIB and debug.logger('additional var-binds: %r' % (varBinds,))
if self.__state & self.stClean:
self.__varBinds.extend(varBinds)
@@ -467,6 +859,43 @@ class NotificationType:
return self.__state & self.stClean
def resolveWithMib(self, mibViewController):
+ """Perform MIB variable ID conversion and notification objects expansion.
+
+ Parameters
+ ----------
+ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController`
+ class instance representing MIB browsing functionality.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.NotificationType`
+ reference to itself
+
+ Raises
+ ------
+ SmiError
+ In case of fatal MIB hanling errora
+
+ Notes
+ -----
+ Calling this method might cause the following sequence of
+ events (exact details depends on many factors):
+
+ * :py:meth:`pysnmp.smi.rfc1902.ObjectIdentity.resolveWithMib` is called
+ * MIB variables names are read from NOTIFICATION-TYPE->OBJECTS clause,
+ :py:class:`~pysnmp.smi.rfc1902.ObjectType` instances are created
+ from MIB variable OID and `indexInstance` suffix.
+ * `objects` dictionary is queried for each MIB variable OID,
+ acquired values are added to corresponding MIB variable
+
+ Examples
+ --------
+ >>> notificationType = NotificationType(ObjectIdentity('IF-MIB', 'linkDown'))
+ >>> notificationType.resolveWithMib(mibViewController)
+ NotificationType(ObjectIdentity('IF-MIB', 'linkDown'), (), {})
+ >>>
+
+ """
if self.__state & self.stClean:
return self
diff --git a/setup.py b/setup.py
index fccda85..7941703 100644
--- a/setup.py
+++ b/setup.py
@@ -105,6 +105,8 @@ params.update( {
'pysnmp.entity',
'pysnmp.entity.rfc3413',
'pysnmp.entity.rfc3413.oneliner',
+ 'pysnmp.entity.rfc3413.oneliner.sync',
+ 'pysnmp.entity.rfc3413.oneliner.sync.compat',
'pysnmp.entity.rfc3413.twisted',
'pysnmp.entity.rfc3413.asyncio',
'pysnmp.proto',