From bea11dfe16e6714737b6f5016697206a038f051b Mon Sep 17 00:00:00 2001 From: elie Date: Sun, 31 May 2015 19:35:10 +0000 Subject: Major overhaul related to PySMI integration and Standard SNMP Applications API redesign: * MibVariable becomes ObjectIdentity and moves to pysnmp.smi.rfc1902 * ObjectType and NotificationType classes resempling corresponding MIB MACROs implemented * SNMP Standard Applications and examples modified to support ObjectType and NotificationType parameters --- CHANGES | 25 +- .../agent/ntforg/inform-multiple-protocols.py | 26 +- examples/v3arch/agent/ntforg/inform-v2c.py | 28 +- examples/v3arch/agent/ntforg/inform-v3.py | 24 +- .../agent/ntforg/trap-v1-from-specific-address.py | 22 +- examples/v3arch/agent/ntforg/trap-v1.py | 25 +- .../agent/ntforg/trap-v2c-multiple-addresses.py | 27 +- .../agent/ntforg/trap-v2c-multiple-targets.py | 25 +- .../agent/ntforg/trap-v2c-multiple-transports.py | 27 +- .../v3arch/agent/ntforg/trap-v2c-with-objects.py | 83 ++-- examples/v3arch/agent/ntforg/trap-v2c.py | 27 +- examples/v3arch/agent/ntforg/trap-v3.py | 25 +- .../getnext-v2c-with-mib-compilation-and-lookup.py | 88 ++++ .../ntforg/inform-async-multiple-snmp-engines.py | 21 +- ...form-async-multiple-transports-and-protocols.py | 21 +- .../agent/ntforg/inform-v2c-with-mib-lookup.py | 7 +- .../inform-v3-with-custom-contextengineid.py | 8 +- .../ntforg/inform-v3-with-custom-contextname.py | 9 +- examples/v3arch/oneliner/agent/ntforg/inform-v3.py | 7 +- ...trap-async-multiple-transports-and-protocols.py | 23 +- .../agent/ntforg/trap-v1-with-custom-values.py | 16 +- .../agent/ntforg/trap-v1-with-default-values.py | 9 +- .../agent/ntforg/trap-v2c-with-mib-lookup.py | 3 +- .../agent/ntforg/trap-v3-with-custom-engineid.py | 4 +- .../cmdgen/get-async-multiple-snmp-engines.py | 12 +- .../get-async-multiple-transports-and-protocols.py | 20 +- ...t-threaded-multiple-transports-and-protocols.py | 20 +- examples/v3arch/oneliner/manager/cmdgen/get-v1.py | 4 +- .../manager/cmdgen/get-v2c-with-asn1-mib-lookup.py | 37 -- .../get-v2c-with-mib-compilation-and-lookup.py | 34 ++ .../cmdgen/get-v3-over-ipv6-with-mib-lookup.py | 4 +- .../manager/cmdgen/get-v3-table-object-by-index.py | 2 +- .../get-v3-table-object-by-multiple-indices.py | 2 +- .../manager/cmdgen/get-v3-with-mib-lookup.py | 2 +- .../cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py | 4 +- .../getbulk-v3-with-custom-mib-path-and-options.py | 2 +- ...next-async-multiple-transports-and-protocols.py | 4 +- .../cmdgen/getnext-v1-with-custom-mibs-location.py | 6 +- .../v3arch/oneliner/manager/cmdgen/getnext-v1.py | 10 +- .../cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py | 2 +- .../getnext-v3-pull-whole-mib-with-mib-lookup.py | 2 +- .../getnext-v3-pull-whole-mib-with-options.py | 2 +- .../cmdgen/set-v2c-with-value-type-mib-lookup.py | 5 +- ...-with-custom-contextengineid-and-contextname.py | 5 +- .../cmdgen/set-v3-with-custom-contextengineid.py | 5 +- .../cmdgen/set-v3-with-value-type-mib-lookup.py | 5 +- pysnmp/entity/config.py | 25 +- pysnmp/entity/engine.py | 19 + pysnmp/entity/rfc3413/config.py | 32 +- pysnmp/entity/rfc3413/ntforg.py | 129 +++--- pysnmp/entity/rfc3413/oneliner/cmdgen.py | 87 ++-- pysnmp/entity/rfc3413/oneliner/mibvar.py | 315 +------------- pysnmp/entity/rfc3413/oneliner/ntforg.py | 86 ++-- pysnmp/smi/compiler.py | 2 +- pysnmp/smi/rfc1902.py | 463 +++++++++++++++++++++ 55 files changed, 1083 insertions(+), 844 deletions(-) create mode 100644 examples/v3arch/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py delete mode 100644 examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-asn1-mib-lookup.py create mode 100644 examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py create mode 100644 pysnmp/smi/rfc1902.py diff --git a/CHANGES b/CHANGES index cecd2d2..07dbdd8 100644 --- a/CHANGES +++ b/CHANGES @@ -4,17 +4,21 @@ Revision 4.2.6rc2 - Critical error fixed in key localization procedure for AES192/AES256/3DES cyphers. Previous versions might never worked properly in this respect. - Initial PySMI integration. Original ASN.1 MIBs could now be parsed, stored - at a local pysnmp MIBs repository and loaded into SNMP Engine. + at a local pysnmp MIBs repository and loaded into SNMP Engine. Relevant + example scripts added. - Major rewrite of native SNMPv3 CommandGenerator and NotificationOriginator applications towards the following goals: - * avoid bonding with particular SNMP engine instance to promote single - app instance using many SNMP engine instances + * 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 whole PDU object while the other on PDU contents * keep callback context data in stack rather than in stateful application cache * newly introduced sendVarBinds() method offers a more functional and logical signatures. + * Promote the use of dedicated classes for dealing with OID-value pairs. + Instances of those classes resemble OBJECT-IDENTITY, OBJECT-TYPE and + NOTIFICATION-TYPE MIB structures. * 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 @@ -36,9 +40,9 @@ Revision 4.2.6rc2 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 object. That would allow - for better cache reuse and allow for a single app working with - many snmpEngine instances. + apps objects to [a singular] snmpEngine "user context" object. + That would allow for better cache reuse and allow for a single app + working with many snmpEngine instances. - Legacy interfaces and APIs dropped in new oneliner AsyncCommandGenerator and AsyncNotificationOriginator classes (notice 'c' in Async). Original AsynCommandGenerator and AsynNotificationOriginator implementations @@ -86,6 +90,15 @@ Revision 4.2.6rc2 - The smi.MibBuilder() will now raise more specific exceptions (MibLoadError, MibNotFoundError) on MIB loading problems rather than more generic SmiError. +- The oneliner's MibVariable MIB lookup subsystem redesigned for more + generality to mimic OBJECT-TYPE macro capabilities related to SNMP + PDU handling. The two new classed are ObjectIdentity and ObjectType. + This new subsystem is moved from a scope of oneliner to more common + pysnmp.smi.rfc1903 scope to more naturally invoke it from whatever + part of pysnmp requires MIB services. +- MibBuilder now prepends the contents of environment variables it + recognizes (PYSNMP_MIB_DIR, PYSNMP_MIB_DIRS, PYSNMP_MIB_PKGS) rather + than using them instead of its default core MIBs. - Fix to authoritative engine side snmpEngineID discovery procedure: respond with notInTimeWindows rather then with unsupportedSecurityLevel at time synchronization phase. diff --git a/examples/v3arch/agent/ntforg/inform-multiple-protocols.py b/examples/v3arch/agent/ntforg/inform-multiple-protocols.py index a3fbb8d..8f70ef9 100644 --- a/examples/v3arch/agent/ntforg/inform-multiple-protocols.py +++ b/examples/v3arch/agent/ntforg/inform-multiple-protocols.py @@ -18,7 +18,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -80,9 +80,6 @@ config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() -# Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Error/confirmation receiver def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): @@ -94,18 +91,15 @@ def cbFun(snmpEngine, sendRequestHandle, errorIndication, # Build and submit notification message to dispatcher sendRequestHandle = ntfOrg.sendVarBinds( snmpEngine, - # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # additional var-binds: ( (oid, value), ... ) - [ ((1,3,6,1,2,1,1,1,0), v2c.OctetString('Example Notificator')) ], + '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 ) diff --git a/examples/v3arch/agent/ntforg/inform-v2c.py b/examples/v3arch/agent/ntforg/inform-v2c.py index 08993b0..9c52655 100644 --- a/examples/v3arch/agent/ntforg/inform-v2c.py +++ b/examples/v3arch/agent/ntforg/inform-v2c.py @@ -15,7 +15,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -59,9 +59,6 @@ config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() -# Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Error/confirmation receiver def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): @@ -73,19 +70,16 @@ def cbFun(snmpEngine, sendRequestHandle, errorIndication, # Build and submit notification message to dispatcher sendRequestHandle = ntfOrg.sendVarBinds( snmpEngine, - # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # 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')) ], + '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 ) diff --git a/examples/v3arch/agent/ntforg/inform-v3.py b/examples/v3arch/agent/ntforg/inform-v3.py index facebe3..ef5355a 100644 --- a/examples/v3arch/agent/ntforg/inform-v3.py +++ b/examples/v3arch/agent/ntforg/inform-v3.py @@ -13,7 +13,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -54,11 +54,8 @@ config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv', (), (), (1,3,6)) # *** SNMP engine configuration is complete by this line *** -# Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Create Notification Originator App instance. -ntfOrg = ntforg.NotificationOriginator(snmpContext) +ntfOrg = ntforg.NotificationOriginator() # Error/confirmation receiver def cbFun(snmpEngine, sendRequestHandle, errorIndication, @@ -71,18 +68,11 @@ def cbFun(snmpEngine, sendRequestHandle, errorIndication, # Build and submit notification message to dispatcher sendRequestHandle = ntfOrg.sendVarBinds( snmpEngine, - # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # additional var-binds: ( (oid, value), ... ) - [ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('system name')) ], + '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 ) diff --git a/examples/v3arch/agent/ntforg/trap-v1-from-specific-address.py b/examples/v3arch/agent/ntforg/trap-v1-from-specific-address.py index 2bfa05d..04dcd56 100644 --- a/examples/v3arch/agent/ntforg/trap-v1-from-specific-address.py +++ b/examples/v3arch/agent/ntforg/trap-v1-from-specific-address.py @@ -13,7 +13,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -57,22 +57,16 @@ config.addVacmUser(snmpEngine, 1, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() - # Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, - # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None + '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') diff --git a/examples/v3arch/agent/ntforg/trap-v1.py b/examples/v3arch/agent/ntforg/trap-v1.py index f21bde5..2ac5071 100644 --- a/examples/v3arch/agent/ntforg/trap-v1.py +++ b/examples/v3arch/agent/ntforg/trap-v1.py @@ -17,7 +17,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c #from pysnmp import debug @@ -64,28 +64,21 @@ config.addVacmUser(snmpEngine, 1, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() - # Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name: Generic Trap #6 (enterpriseSpecific) - # and Specific Trap 432 - '1.3.6.1.4.1.20408.4.1.1.2.0.432', - # instance Index - None, - # additional var-binds - [ + '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')), diff --git a/examples/v3arch/agent/ntforg/trap-v2c-multiple-addresses.py b/examples/v3arch/agent/ntforg/trap-v2c-multiple-addresses.py index 329268f..709e972 100644 --- a/examples/v3arch/agent/ntforg/trap-v2c-multiple-addresses.py +++ b/examples/v3arch/agent/ntforg/trap-v2c-multiple-addresses.py @@ -16,7 +16,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -74,25 +74,20 @@ config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() -# Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # 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')) ] + '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') diff --git a/examples/v3arch/agent/ntforg/trap-v2c-multiple-targets.py b/examples/v3arch/agent/ntforg/trap-v2c-multiple-targets.py index 0ca3d70..cd6432b 100644 --- a/examples/v3arch/agent/ntforg/trap-v2c-multiple-targets.py +++ b/examples/v3arch/agent/ntforg/trap-v2c-multiple-targets.py @@ -16,7 +16,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -70,22 +70,23 @@ config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # *** SNMP engine configuration is complete by this line *** -# Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Create Notification Originator App instance. -ntfOrg = ntforg.NotificationOriginator(snmpContext) +ntfOrg = ntforg.NotificationOriginator() # Build and submit notification message to dispatcher -ntfOrg.sendNotification( +ntfOrg.sendVarBinds( snmpEngine, # Notification targets - 'my-notification', - # Trap OID (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # ( (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')) ) + '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') diff --git a/examples/v3arch/agent/ntforg/trap-v2c-multiple-transports.py b/examples/v3arch/agent/ntforg/trap-v2c-multiple-transports.py index ea204f2..e2589da 100644 --- a/examples/v3arch/agent/ntforg/trap-v2c-multiple-transports.py +++ b/examples/v3arch/agent/ntforg/trap-v2c-multiple-transports.py @@ -15,7 +15,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp, udp6 -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -73,25 +73,20 @@ config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() - # Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # 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')) ] + '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') diff --git a/examples/v3arch/agent/ntforg/trap-v2c-with-objects.py b/examples/v3arch/agent/ntforg/trap-v2c-with-objects.py index e4ac2e0..ad17348 100644 --- a/examples/v3arch/agent/ntforg/trap-v2c-with-objects.py +++ b/examples/v3arch/agent/ntforg/trap-v2c-with-objects.py @@ -8,28 +8,24 @@ # * over IPv4/UDP # * send TRAP notification # * to a Manager at 127.0.0.1:162 -# * with TRAP ID ACCOUNTING-CONTROL-MIB::acctngFileFull as MIB symbol +# * with TRAP ID IF-MIB::ifLink as MIB symbol # -# The ACCOUNTING-CONTROL-MIB::acctngFileFull NOTIFICATION-TYPE implies -# including three other var-binds into the TRAP describing the incident -# occurred. These var-binds are: -# ACCOUNTING-CONTROL-MIB::acctngFileMaximumSize.0 -# ACCOUNTING-CONTROL-MIB::acctngFileNameSuffix.0 -# ACCOUNTING-CONTROL-MIB::acctngFileName.0 +# 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" # -# To run this example make sure to have ACCOUNTING-CONTROL-MIB.py in -# search path. +# Where "x" is MIB table index (instance index). +# +# To run this example make sure to have IF-MIB.py in search path. # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context -from pysnmp.proto.api import v2c - -# Create SNMP engine instance -snmpEngine = engine.SnmpEngine() - -# Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) +from pysnmp.entity.rfc3413 import ntforg +from pysnmp.smi import rfc1902, view # # Here we fill in some values for Managed Objects Instances (invoked @@ -37,33 +33,19 @@ snmpContext = context.SnmpContext(snmpEngine) # 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' +} -mibInstrumCtl = snmpContext.getMibInstrum('') -( MibScalarInstance, ) = mibInstrumCtl.mibBuilder.importSymbols( - 'SNMPv2-SMI', - 'MibScalarInstance' - ) -( acctngFileFull, - acctngFileMaximumSize, - acctngFileNameSuffix, - acctngFileName ) = mibInstrumCtl.mibBuilder.importSymbols( - 'ACCOUNTING-CONTROL-MIB', - 'acctngFileFull', - 'acctngFileMaximumSize', - 'acctngFileNameSuffix', - 'acctngFileName' - ) - -mibInstrumCtl.mibBuilder.exportSymbols( - '__ACCOUNTING-CONTROL-MIB', - MibScalarInstance(acctngFileMaximumSize.name, (0,), acctngFileMaximumSize.syntax.clone(123)), - MibScalarInstance(acctngFileNameSuffix.name, (0,), acctngFileNameSuffix.syntax.clone('.log')), - MibScalarInstance(acctngFileName.name, (0,), acctngFileName.syntax.clone('mylogfile')), -) +# Create SNMP engine instance +snmpEngine = engine.SnmpEngine() -# -# End of Agent's Managed Object Instances initialization -# +# 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') @@ -107,16 +89,13 @@ ntfOrg = ntforg.NotificationOriginator() # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, - # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name - ('ACCOUNTING-CONTROL-MIB', 'acctngFileFull'), - # MIB scalar/table instances of NOTIFICATION-TYPE objects - (0,) + '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') diff --git a/examples/v3arch/agent/ntforg/trap-v2c.py b/examples/v3arch/agent/ntforg/trap-v2c.py index 4e3465b..d63a371 100644 --- a/examples/v3arch/agent/ntforg/trap-v2c.py +++ b/examples/v3arch/agent/ntforg/trap-v2c.py @@ -15,7 +15,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance @@ -58,9 +58,6 @@ config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() - # Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Error/confirmation receiver def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): @@ -73,18 +70,16 @@ def cbFun(snmpEngine, sendRequestHandle, errorIndication, sendRequestHandle = ntfOrg.sendVarBinds( snmpEngine, # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # 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')) ], + '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 ) diff --git a/examples/v3arch/agent/ntforg/trap-v3.py b/examples/v3arch/agent/ntforg/trap-v3.py index bff341a..266d91e 100644 --- a/examples/v3arch/agent/ntforg/trap-v3.py +++ b/examples/v3arch/agent/ntforg/trap-v3.py @@ -13,7 +13,7 @@ # from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp -from pysnmp.entity.rfc3413 import ntforg, context +from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance with specific (and locally unique) @@ -62,24 +62,19 @@ config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (), (), (1,3,6)) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator() - # Create default SNMP context where contextEngineId == SnmpEngineId -snmpContext = context.SnmpContext(snmpEngine) - # Build and submit notification message to dispatcher ntfOrg.sendVarBinds( snmpEngine, # Notification targets - 'my-notification', - # SNMP Context - snmpContext, - # contextName - '', - # notification name (SNMPv2-MIB::coldStart) - (1,3,6,1,6,3,1,1,5,1), - # instance Index - None, - # additional var-binds: ( (oid, value), ... ) - [ ((1,3,6,1,2,1,1,5,0), v2c.OctetString('system name')) ] + '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') diff --git a/examples/v3arch/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py b/examples/v3arch/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py new file mode 100644 index 0000000..a8c5b35 --- /dev/null +++ b/examples/v3arch/manager/cmdgen/getnext-v2c-with-mib-compilation-and-lookup.py @@ -0,0 +1,88 @@ +# +# GETNEXT Command Generator +# +# Send a series of SNMP GETNEXT requests +# 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.asynsock.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) +compiler.addMibCompiler(snmpEngine.getMibBuilder()) + +# 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/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py b/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py index 088b72b..2dfbc55 100644 --- a/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py +++ b/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-snmp-engines.py @@ -26,19 +26,19 @@ # from pysnmp.entity.rfc3413.oneliner import ntforg from pysnmp.entity import engine -from pysnmp.entity.rfc3413 import context from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher -from pysnmp.proto import rfc1902 # List of targets in the following format: # ( ( authData, transportTarget ), ... ) targets = ( # 1-st target (SNMPv2c over IPv4/UDP) ( ntforg.CommunityData('public'), - ntforg.UdpTransportTarget(('localhost', 1162)) ), + ntforg.UdpTransportTarget(('localhost', 1162)), + ntforg.ContextData() ), # 2-nd target (SNMPv3 over IPv4/UDP) ( ntforg.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), - ntforg.UdpTransportTarget(('localhost', 162)) ) + ntforg.UdpTransportTarget(('localhost', 162)), + ntforg.ContextData() ), ) def cbFun(snmpEngine, sendRequestHandle, errorIndication, @@ -69,19 +69,18 @@ snmpEngineB.registerTransportDispatcher(transportDispatcher, 'B') ntfOrg = ntforg.AsyncNotificationOriginator() -for authData, transportTarget in targets: +for authData, transportTarget, contextData in targets: snmpEngine = transportTarget.getTransportInfo()[1][1] % 3 and \ snmpEngineA or snmpEngineB sendPduHandle = ntfOrg.sendNotification( snmpEngine, authData, transportTarget, - context.SnmpContext(snmpEngine), - ntforg.null, - 'inform', - ntforg.MibVariable('SNMPv2-MIB', 'coldStart'), - ( ( rfc1902.ObjectName('1.3.6.1.2.1.1.1.0'), - rfc1902.OctetString('my name') ), ), + contextData, + 'inform', # NotifyType + ntforg.NotificationType( + ntforg.ObjectIdentity('SNMPv2-MIB', 'coldStart') + ).addVarBinds( ( '1.3.6.1.2.1.1.1.0', 'my name' ) ), cbInfo=(cbFun, snmpEngine) ) diff --git a/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py b/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py index a19bc11..fc4a358 100644 --- a/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py +++ b/examples/v3arch/oneliner/agent/ntforg/inform-async-multiple-transports-and-protocols.py @@ -12,19 +12,19 @@ # * include managed object information specified as var-bind objects pair # from pysnmp.entity.rfc3413.oneliner import ntforg -from pysnmp.entity.rfc3413 import context from pysnmp.entity import engine -from pysnmp.proto import rfc1902 # List of targets in the followin format: # ( ( authData, transportTarget ), ... ) targets = ( # 1-st target (SNMPv2c over IPv4/UDP) ( ntforg.CommunityData('public'), - ntforg.UdpTransportTarget(('localhost', 162)) ), + ntforg.UdpTransportTarget(('localhost', 162)), + ntforg.ContextData() ), # 2-nd target (SNMPv3 over IPv4/UDP) ( ntforg.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), - ntforg.UdpTransportTarget(('localhost', 162)) ) + ntforg.UdpTransportTarget(('localhost', 162)), + ntforg.ContextData() ), ) def cbFun(snmpEngine, sendRequestHandle, errorIndication, @@ -43,17 +43,16 @@ snmpEngine = engine.SnmpEngine() ntfOrg = ntforg.AsyncNotificationOriginator() -for authData, transportTarget in targets: +for authData, transportTarget, contextData in targets: sendPduHandle = ntfOrg.sendNotification( snmpEngine, authData, transportTarget, - context.SnmpContext(snmpEngine), - ntforg.null, - 'inform', - ntforg.MibVariable('SNMPv2-MIB', 'coldStart'), - ( ( rfc1902.ObjectName('1.3.6.1.2.1.1.1.0'), - rfc1902.OctetString('my name') ), ), + contextData, + 'inform', # NotifyType + ntforg.NotificationType( + ntforg.ObjectIdentity('SNMPv2-MIB', 'coldStart') + ).addVarBinds( ( '1.3.6.1.2.1.1.1.0', 'my name' ) ), cbInfo=(cbFun, None) ) diff --git a/examples/v3arch/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py b/examples/v3arch/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py index ca51d28..330b6b2 100644 --- a/examples/v3arch/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py +++ b/examples/v3arch/oneliner/agent/ntforg/inform-v2c-with-mib-lookup.py @@ -19,8 +19,11 @@ errorIndication, errorStatus, errorIndex, varBinds = ntfOrg.sendNotification( ntforg.CommunityData('public'), ntforg.UdpTransportTarget(('localhost', 162)), 'inform', - ntforg.MibVariable('SNMPv2-MIB', 'coldStart'), - ( ntforg.MibVariable('SNMPv2-MIB', 'sysName', 0), 'my system' ), + ntforg.NotificationType( + ntforg.ObjectIdentity('SNMPv2-MIB', 'coldStart') + ).addVarBinds( + ( ntforg.ObjectIdentity('SNMPv2-MIB', 'sysName', 0), 'my system' ) + ), lookupNames=True, lookupValues=True ) diff --git a/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py b/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py index 60ab7b2..5e8c053 100644 --- a/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py +++ b/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextengineid.py @@ -20,17 +20,15 @@ from pysnmp.entity.rfc3413.oneliner import ntforg from pysnmp.proto import rfc1902 snmpEngine = engine.SnmpEngine() -snmpContext = context.SnmpContext( - snmpEngine,contextEngineId=rfc1902.OctetString(hexValue='8000000004030201') -) -ntfOrg = ntforg.NotificationOriginator(snmpEngine, snmpContext) +ntfOrg = ntforg.NotificationOriginator(snmpEngine) errorIndication, errorStatus, errorIndex, varBinds = ntfOrg.sendNotification( ntforg.UsmUserData('usr-md5-none', 'authkey1'), ntforg.UdpTransportTarget(('localhost', 162)), 'inform', - '1.3.6.1.6.3.1.1.5.2' + ntforg.NotificationType(ntforg.ObjectIdentity('1.3.6.1.6.3.1.1.5.2')), + contextEngineId=rfc1902.OctetString(hexValue='8000000004030201') ) if errorIndication: diff --git a/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py b/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py index 1d1085e..dfe0ad0 100644 --- a/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py +++ b/examples/v3arch/oneliner/agent/ntforg/inform-v3-with-custom-contextname.py @@ -15,22 +15,17 @@ # the ContextName being used. # from pysnmp.entity import engine -from pysnmp.entity.rfc3413 import context from pysnmp.entity.rfc3413.oneliner import ntforg snmpEngine = engine.SnmpEngine() -snmpContext = context.SnmpContext(snmpEngine) -# register default collection of Managed Objects under new contextName -snmpContext.registerContextName('my-context', snmpContext.getMibInstrum()) - -ntfOrg = ntforg.NotificationOriginator(snmpEngine, snmpContext) +ntfOrg = ntforg.NotificationOriginator(snmpEngine) errorIndication, errorStatus, errorIndex, varBinds = ntfOrg.sendNotification( ntforg.UsmUserData('usr-md5-none', 'authkey1'), ntforg.UdpTransportTarget(('localhost', 162)), 'inform', - '1.3.6.1.6.3.1.1.5.2', + ntforg.NotificationType(ntforg.ObjectIdentity('1.3.6.1.6.3.1.1.5.2')), contextName='my-context' ) diff --git a/examples/v3arch/oneliner/agent/ntforg/inform-v3.py b/examples/v3arch/oneliner/agent/ntforg/inform-v3.py index 41d996e..f9abe91 100644 --- a/examples/v3arch/oneliner/agent/ntforg/inform-v3.py +++ b/examples/v3arch/oneliner/agent/ntforg/inform-v3.py @@ -19,8 +19,11 @@ errorIndication, errorStatus, errorIndex, varBinds = ntfOrg.sendNotification( ntforg.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), ntforg.UdpTransportTarget(('localhost', 162)), 'inform', - '1.3.6.1.6.3.1.1.5.2', - ('1.3.6.1.2.1.1.5.0', rfc1902.OctetString('system name')) + ntforg.NotificationType( + ntforg.ObjectIdentity('1.3.6.1.6.3.1.1.5.2') + ).addVarBinds( + ('1.3.6.1.2.1.1.5.0', rfc1902.OctetString('system name')) + ) ) if errorIndication: diff --git a/examples/v3arch/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py b/examples/v3arch/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py index a075fda..c9e955e 100644 --- a/examples/v3arch/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py +++ b/examples/v3arch/oneliner/agent/ntforg/trap-async-multiple-transports-and-protocols.py @@ -12,7 +12,6 @@ # * include managed object information specified as var-bind objects pair # from pysnmp.entity.rfc3413.oneliner import ntforg -from pysnmp.entity.rfc3413 import context from pysnmp.entity import engine from pysnmp.proto import rfc1902 @@ -21,27 +20,31 @@ from pysnmp.proto import rfc1902 targets = ( # 1-st target (SNMPv1 over IPv4/UDP) ( ntforg.CommunityData('public', mpModel=0), - ntforg.UdpTransportTarget(('localhost', 162)) ), + ntforg.UdpTransportTarget(('localhost', 162)), + ntforg.ContextData() ), # 2-nd target (SNMPv2c over IPv4/UDP) ( ntforg.CommunityData('public'), - ntforg.UdpTransportTarget(('localhost', 162)) ) + ntforg.UdpTransportTarget(('localhost', 162)), + ntforg.ContextData() ), ) snmpEngine = engine.SnmpEngine() ntfOrg = ntforg.AsyncNotificationOriginator() -for authData, transportTarget in targets: +for authData, transportTarget, contextData in targets: ntfOrg.sendNotification( snmpEngine, authData, transportTarget, - context.SnmpContext(snmpEngine), - ntforg.null, - 'trap', - ntforg.MibVariable('SNMPv2-MIB', 'coldStart'), - ( ( rfc1902.ObjectName('1.3.6.1.2.1.1.1.0'), - rfc1902.OctetString('my name') ), ) + contextData, + 'trap', # NotifyType + ntforg.NotificationType( + ntforg.ObjectIdentity('SNMPv2-MIB', 'coldStart') + ).addVarBinds( + ( rfc1902.ObjectName('1.3.6.1.2.1.1.1.0'), + rfc1902.OctetString('my name') ) + ) ) snmpEngine.transportDispatcher.runDispatcher() diff --git a/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-custom-values.py b/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-custom-values.py index e2ba44a..7db778e 100644 --- a/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-custom-values.py +++ b/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-custom-values.py @@ -15,6 +15,9 @@ # from pysnmp.entity.rfc3413.oneliner import ntforg from pysnmp.proto import rfc1902 +#from pysnmp import debug + +#debug.setLogger(debug.Debug('mibview')) ntfOrg = ntforg.NotificationOriginator() @@ -22,11 +25,14 @@ errorIndication = ntfOrg.sendNotification( ntforg.CommunityData('public', mpModel=0), ntforg.UdpTransportTarget(('localhost', 162)), 'trap', - '1.3.6.1.4.1.20408.4.1.1.2.0.432', - ('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')) + ntforg.NotificationType( + ntforg.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: diff --git a/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-default-values.py b/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-default-values.py index 4a845f4..beab6e7 100644 --- a/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-default-values.py +++ b/examples/v3arch/oneliner/agent/ntforg/trap-v1-with-default-values.py @@ -22,9 +22,12 @@ errorIndication = ntfOrg.sendNotification( ntforg.CommunityData('public', mpModel=0), ntforg.UdpTransportTarget(('localhost', 162)), 'trap', - '1.3.6.1.6.3.1.1.5.2', - ('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')) + ntforg.NotificationType( + ntforg.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: diff --git a/examples/v3arch/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py b/examples/v3arch/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py index 7d01883..502b3a0 100644 --- a/examples/v3arch/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py +++ b/examples/v3arch/oneliner/agent/ntforg/trap-v2c-with-mib-lookup.py @@ -18,8 +18,7 @@ errorIndication = ntfOrg.sendNotification( ntforg.CommunityData('public'), ntforg.UdpTransportTarget(('localhost', 162)), 'trap', - ntforg.MibVariable('SNMPv2-MIB', 'coldStart'), - ( ntforg.MibVariable('SNMPv2-MIB', 'sysName', 0), 'new name' ) + ntforg.NotificationType(ntforg.ObjectIdentity('SNMPv2-MIB', 'coldStart')) ) if errorIndication: diff --git a/examples/v3arch/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py b/examples/v3arch/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py index 7aa72f4..60cb0a6 100644 --- a/examples/v3arch/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py +++ b/examples/v3arch/oneliner/agent/ntforg/trap-v3-with-custom-engineid.py @@ -30,7 +30,9 @@ errorIndication = ntfOrg.sendNotification( privProtocol=ntforg.usmAesCfb128Protocol), ntforg.UdpTransportTarget(('127.0.0.1', 162)), 'trap', - ntforg.MibVariable('SNMPv2-MIB', 'authenticationFailure') + ntforg.NotificationType( + ntforg.ObjectIdentity('SNMPv2-MIB', 'authenticationFailure') + ) ) if errorIndication: diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py b/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py index 1b7d156..94c1f54 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-snmp-engines.py @@ -35,18 +35,18 @@ targets = ( # 1-st target (SNMPv1 over IPv4/UDP) ( cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # 2-nd target (SNMPv2c over IPv4/UDP) ( cmdgen.CommunityData('public'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 1161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.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.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ) + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ) # N-th target # ... ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py b/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py index d70617d..d169377 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-async-multiple-transports-and-protocols.py @@ -22,29 +22,29 @@ targets = ( # 1-st target (SNMPv1 over IPv4/UDP) ( cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # 2-nd target (SNMPv2c over IPv4/UDP) ( cmdgen.CommunityData('public'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.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.MibVariable('SNMPv2-MIB', 'sysContact', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysName', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysContact', 0), + cmdgen.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.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # 5-th target (SNMPv3 over IPv6/UDP) ( cmdgen.UsmUserData('usr-md5-none', 'authkey1'), cmdgen.Udp6TransportTarget(('::1', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # N-th target # ... ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py b/examples/v3arch/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py index df22afb..5d589f9 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-threaded-multiple-transports-and-protocols.py @@ -28,29 +28,29 @@ targets = ( # 1-st target (SNMPv1 over IPv4/UDP) ( cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # 2-nd target (SNMPv2c over IPv4/UDP) ( cmdgen.CommunityData('public'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.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.MibVariable('SNMPv2-MIB', 'sysContact', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysName', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysContact', 0), + cmdgen.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.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # 5-th target (SNMPv3 over IPv6/UDP) ( cmdgen.UsmUserData('usr-md5-none', 'authkey1'), cmdgen.Udp6TransportTarget(('::1', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), - cmdgen.MibVariable('SNMPv2-MIB', 'sysLocation', 0) ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysLocation', 0) ) ), # N-th target # ... ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v1.py b/examples/v3arch/oneliner/manager/cmdgen/get-v1.py index f05c5f8..664df9d 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-v1.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-v1.py @@ -16,8 +16,8 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0'), - cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0) + cmdgen.ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0'), + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0) ) # Check for errors and print out results diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-asn1-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-asn1-mib-lookup.py deleted file mode 100644 index a8f1e73..0000000 --- a/examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-asn1-mib-lookup.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# 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 -# -from pysnmp.entity.rfc3413.oneliner import cmdgen -from pysnmp import debug - -#debug.setLogger(debug.Debug('mibbuild')) - -cmdGen = cmdgen.CommandGenerator() - -errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( - cmdgen.CommunityData('public'), - cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', 'ifInOctets', '1').addAsn1Sources('file:///usr/share/snmp', 'http://mibs.snmplabs.com/asn1/'), - 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 name, val in varBinds: - print('%s = %s' % (name.prettyPrint(), val.prettyPrint())) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py new file mode 100644 index 0000000..2c69699 --- /dev/null +++ b/examples/v3arch/oneliner/manager/cmdgen/get-v2c-with-mib-compilation-and-lookup.py @@ -0,0 +1,34 @@ +# +# 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 +# +from pysnmp.entity.rfc3413.oneliner import cmdgen + +cmdGen = cmdgen.CommandGenerator() + +errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( + cmdgen.CommunityData('public'), + cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), + cmdgen.ObjectIdentity('IF-MIB', 'ifInOctets', 1).addMibCompiler('file:///usr/share/snmp', 'http://mibs.snmplabs.com/asn1/'), + 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 oid, val in varBinds: + print('%s = %s' % (oid.prettyPrint(), val.prettyPrint())) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py index 452c811..b766fad 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-v3-over-ipv6-with-mib-lookup.py @@ -6,7 +6,7 @@ # * 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 MibVariable object while others are +# * for three OIDs: one passed as a ObjectIdentity object while others are # * in string form # from pysnmp.entity.rfc3413.oneliner import cmdgen @@ -16,7 +16,7 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), cmdgen.Udp6TransportTarget(('::1', 161)), - cmdgen.MibVariable('1.3.6.1.2.1.1.1.0'), + cmdgen.ObjectIdentity('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' ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-index.py b/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-index.py index 35fe0df..c641993 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-index.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-index.py @@ -16,7 +16,7 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.UsmUserData('usr-none-none'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', 'ifInOctets', '1'), + cmdgen.ObjectIdentity('IF-MIB', 'ifInOctets', 1), lookupNames=True, lookupValues=True ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py b/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py index 74f31b0..8bc4562 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-v3-table-object-by-multiple-indices.py @@ -17,7 +17,7 @@ errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( authProtocol=cmdgen.usmHMACSHAAuthProtocol, privProtocol=cmdgen.usmAesCfb128Protocol ), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('TCP-MIB', 'tcpConnLocalAddress', '0.0.0.0', 22, '0.0.0.0', 0) + cmdgen.ObjectIdentity('TCP-MIB', 'tcpConnLocalAddress', '0.0.0.0', 22, '0.0.0.0', 0) ) # Check for errors and print out results diff --git a/examples/v3arch/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py index 5392c0c..47f025f 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/get-v3-with-mib-lookup.py @@ -15,7 +15,7 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.UsmUserData('usr-md5-none', 'authkey1'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', 'ifInOctets', '1') + cmdgen.ObjectIdentity('IF-MIB', 'ifInOctets', 1) ) # Check for errors and print out results diff --git a/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py index 7291ee8..99df3c1 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-over-ipv6-with-mib-lookup.py @@ -22,8 +22,8 @@ errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), cmdgen.Udp6TransportTarget(('::1', 161)), 1, 25, - cmdgen.MibVariable('IP-MIB', 'ipAdEntAddr'), - cmdgen.MibVariable('IF-MIB', 'ifEntry'), + cmdgen.ObjectIdentity('IP-MIB', 'ipAdEntAddr'), + cmdgen.ObjectIdentity('IF-MIB', 'ifEntry'), lookupNames=True, lookupValues=True, maxRows=20 ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py b/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py index a0f0f29..4ca6b6e 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getbulk-v3-with-custom-mib-path-and-options.py @@ -22,7 +22,7 @@ errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd( cmdgen.UsmUserData('usr-none-none'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), 0, 50, - cmdgen.MibVariable('TCP-MIB', 'tcpConnTable').addMibSource('/tmp/mymibs'), + cmdgen.ObjectIdentity('TCP-MIB', 'tcpConnTable').addMibSource('/tmp/mibs'), lexicographicMode=True, maxRows=100, maxCalls=10,ignoreNonIncreasingOid=True ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py b/examples/v3arch/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py index af3a40f..80ff0fe 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getnext-async-multiple-transports-and-protocols.py @@ -29,11 +29,11 @@ targets = ( # 3-nd target (SNMPv3 over IPv4/UDP) ( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - ( cmdgen.MibVariable('SNMPv2-MIB', 'system'), ) ), + ( cmdgen.ObjectIdentity('SNMPv2-MIB', 'system'), ) ), # 4-th target (SNMPv3 over IPv6/UDP) ( cmdgen.UsmUserData('usr-md5-none', 'authkey1'), cmdgen.Udp6TransportTarget(('::1', 161)), - ( cmdgen.MibVariable('IF-MIB', 'ifTable'), ) ) + ( cmdgen.ObjectIdentity('IF-MIB', 'ifTable'), ) ) # N-th target # ... ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py b/examples/v3arch/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py index 42e8f46..e693562 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getnext-v1-with-custom-mibs-location.py @@ -21,7 +21,7 @@ # 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 -# MibVariable.addMibSource() calls. New search path entries are added +# ObjectIdentity.addMibSource() calls. New search path entries are added # in front of existing ones in search path. # from pysnmp.entity.rfc3413.oneliner import cmdgen @@ -31,8 +31,8 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd( cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', 'ifDescr').addMibSource('/tmp/mymibs'), - cmdgen.MibVariable('IF-MIB', 'ifType') + cmdgen.ObjectIdentity('IF-MIB', 'ifDescr').addMibSource('/tmp/mymibs'), + cmdgen.ObjectIdentity('IF-MIB', 'ifType') ) if errorIndication: diff --git a/examples/v3arch/oneliner/manager/cmdgen/getnext-v1.py b/examples/v3arch/oneliner/manager/cmdgen/getnext-v1.py index 2a69895..7be99e2 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getnext-v1.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getnext-v1.py @@ -18,11 +18,11 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd( cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', 'ifDescr'), - cmdgen.MibVariable('IF-MIB', 'ifType'), - cmdgen.MibVariable('IF-MIB', 'ifMtu'), - cmdgen.MibVariable('IF-MIB', 'ifSpeed'), - cmdgen.MibVariable('IF-MIB', 'ifPhysAddress') + cmdgen.ObjectIdentity('IF-MIB', 'ifDescr'), + cmdgen.ObjectIdentity('IF-MIB', 'ifType'), + cmdgen.ObjectIdentity('IF-MIB', 'ifMtu'), + cmdgen.ObjectIdentity('IF-MIB', 'ifSpeed'), + cmdgen.ObjectIdentity('IF-MIB', 'ifPhysAddress') ) if errorIndication: diff --git a/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py index 6354572..847ba25 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-over-ipv6-with-mib-lookup.py @@ -19,7 +19,7 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), cmdgen.Udp6TransportTarget(('::1', 161)), - cmdgen.MibVariable('IF-MIB', 'ifEntry'), + cmdgen.ObjectIdentity('IF-MIB', 'ifEntry'), lookupNames=True, lookupValues=True ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py index 25352de..2d62e85 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-mib-lookup.py @@ -19,7 +19,7 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd( cmdgen.UsmUserData('usr-md5-none', 'authkey1'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', ''), + cmdgen.ObjectIdentity('IF-MIB', ''), lookupValues=True ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py b/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py index 2e9c9f4..bdeda85 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py +++ b/examples/v3arch/oneliner/manager/cmdgen/getnext-v3-pull-whole-mib-with-options.py @@ -21,7 +21,7 @@ errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd( authProtocol=cmdgen.usmHMACSHAAuthProtocol, privProtocol=cmdgen.usmAesCfb128Protocol), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - cmdgen.MibVariable('IF-MIB', '').loadMibs(), + cmdgen.ObjectIdentity('IF-MIB', '').loadMibs(), lexicographicMode=True, maxRows=100, ignoreNonIncreasingOid=True ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py index d58ad9c..6732ec2 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/set-v2c-with-value-type-mib-lookup.py @@ -15,7 +15,10 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.setCmd( cmdgen.CommunityData('public'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - (cmdgen.MibVariable('SNMPv2-MIB', 'sysORDescr', 1), 'new system name') + cmdgen.ObjectType( + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1), + 'new system name' + ) ) # Check for errors and print out results diff --git a/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py b/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py index e273bba..f28063b 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py +++ b/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid-and-contextname.py @@ -19,7 +19,10 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.setCmd( cmdgen.UsmUserData('usr-md5-none', 'authkey1'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - (cmdgen.MibVariable('SNMPv2-MIB', 'sysORDescr', 1), 'new system name'), + cmdgen.ObjectType( + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1), + 'new system name' + ), contextEngineId=rfc1902.OctetString(hexValue='80004fb805636c6f75644dab22cc'), contextName='da761cfc8c94d3aceef4f60f049105ba' ) diff --git a/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py b/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py index 04ee0bf..124a26f 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py +++ b/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-custom-contextengineid.py @@ -23,7 +23,10 @@ errorIndication, errorStatus, errorIndex, varBinds = cmdGen.setCmd( ) ), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - (cmdgen.MibVariable('SNMPv2-MIB', 'sysORDescr', 1), 'new system name'), + cmdgen.ObjectType( + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1), + 'new system name' + ) ) # Check for errors and print out results diff --git a/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py b/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py index 9734400..c5ce06d 100644 --- a/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py +++ b/examples/v3arch/oneliner/manager/cmdgen/set-v3-with-value-type-mib-lookup.py @@ -16,7 +16,10 @@ cmdGen = cmdgen.CommandGenerator() errorIndication, errorStatus, errorIndex, varBinds = cmdGen.setCmd( cmdgen.UsmUserData('usr-md5-des', 'authkey1', 'privkey1'), cmdgen.UdpTransportTarget(('demo.snmplabs.com', 161)), - (cmdgen.MibVariable('SNMPv2-MIB', 'sysORDescr', 1), 'new system name'), + cmdgen.ObjectType( + cmdgen.ObjectIdentity('SNMPv2-MIB', 'sysORDescr', 1), + 'new system name' + ), lookupNames=True, lookupValues=True ) diff --git a/pysnmp/entity/config.py b/pysnmp/entity/config.py index f9018e9..085eea5 100644 --- a/pysnmp/entity/config.py +++ b/pysnmp/entity/config.py @@ -325,12 +325,17 @@ def addTransport(snmpEngine, transportDomain, transport): transport.protoTransportDispatcher() ) # here we note that we have created transportDispatcher automatically - snmpEngine.cache['automaticTransportDispatcher'] = 0 + snmpEngine.setUserContext(automaticTransportDispatcher=0) snmpEngine.transportDispatcher.registerTransport( transportDomain, transport ) - if 'automaticTransportDispatcher' in snmpEngine.cache: - snmpEngine.cache['automaticTransportDispatcher'] += 1 + automaticTransportDispatcher = snmpEngine.getUserContext( + 'automaticTransportDispatcher' + ) + if automaticTransportDispatcher is not None: + snmpEngine.setUserContext( + automaticTransportDispatcher=automaticTransportDispatcher+1 + ) def getTransport(snmpEngine, transportDomain): if not snmpEngine.transportDispatcher: @@ -346,12 +351,18 @@ def delTransport(snmpEngine, transportDomain): transport = getTransport(snmpEngine, transportDomain) snmpEngine.transportDispatcher.unregisterTransport(transportDomain) # automatically shutdown automatically created transportDispatcher - if 'automaticTransportDispatcher' in snmpEngine.cache: - snmpEngine.cache['automaticTransportDispatcher'] -= 1 - if not snmpEngine.cache['automaticTransportDispatcher']: + automaticTransportDispatcher = snmpEngine.getUserContext( + 'automaticTransportDispatcher' + ) + if automaticTransportDispatcher is not None: + automaticTransportDispatcher -= 1 + snmpEngine.setUserContext( + automaticTransportDispatcher=automaticTransportDispatcher + ) + if not automaticTransportDispatcher: snmpEngine.transportDispatcher.closeDispatcher() snmpEngine.unregisterTransportDispatcher() - del snmpEngine.cache['automaticTransportDispatcher'] + snmpEngine.delUserContext(automaticTransportDispatcher) return transport addSocketTransport = addTransport diff --git a/pysnmp/entity/engine.py b/pysnmp/entity/engine.py index ecc0aa5..d663d91 100644 --- a/pysnmp/entity/engine.py +++ b/pysnmp/entity/engine.py @@ -140,3 +140,22 @@ class SnmpEngine: self.transportDispatcher.unregisterRecvCbFun(recvId) self.transportDispatcher.unregisterTimerCbFun() self.transportDispatcher = None + + def getMibBuilder(self): + return self.msgAndPduDsp.mibInstrumController.mibBuilder + + # User app may attach opaque objects to SNMP Engine + def setUserContext(self, **kwargs): + self.cache.update( + dict([('__%s' % k, kwargs[k]) for k in kwargs]) + ) + + def getUserContext(self, arg): + return self.cache.get('__%s' % arg) + + def delUserContext(self, arg): + try: + del self.cache['__%s' % arg] + except KeyError: + pass + diff --git a/pysnmp/entity/rfc3413/config.py b/pysnmp/entity/rfc3413/config.py index 1124600..68218eb 100644 --- a/pysnmp/entity/rfc3413/config.py +++ b/pysnmp/entity/rfc3413/config.py @@ -9,10 +9,10 @@ def getTargetAddr(snmpEngine, snmpTargetAddrName): 'SNMP-TARGET-MIB', 'snmpTargetAddrEntry' ) - if 'getTargetAddr' not in snmpEngine.cache: - snmpEngine.cache['getTargetAddr'] = { 'id': -1 } - - cache = snmpEngine.cache['getTargetAddr'] + cache = snmpEngine.getUserContext('getTargetAddr') + if cache is None: + cache = { 'id': -1 } + snmpEngine.setUserContext(getTargetAddr=cache) if cache['id'] != snmpTargetAddrEntry.branchVersionId: cache['nameToTargetMap'] = {} @@ -98,10 +98,10 @@ def getTargetParams(snmpEngine, paramsName): 'SNMP-TARGET-MIB', 'snmpTargetParamsEntry' ) - if 'getTargetParams' not in snmpEngine.cache: - snmpEngine.cache['getTargetParams'] = { 'id': -1 } - - cache = snmpEngine.cache['getTargetParams'] + cache = snmpEngine.getUserContext('getTargetParams') + if cache is None: + cache = { 'id': -1 } + snmpEngine.setUserContext(getTargetParams=cache) if cache['id'] != snmpTargetParamsEntry.branchVersionId: cache['nameToParamsMap'] = {} @@ -178,10 +178,10 @@ def getNotificationInfo(snmpEngine, notificationTarget): 'SNMP-NOTIFICATION-MIB', 'snmpNotifyEntry' ) - if 'getNotificationInfo' not in snmpEngine.cache: - snmpEngine.cache['getNotificationInfo'] = { 'id': -1 } - - cache = snmpEngine.cache['getNotificationInfo'] + cache = snmpEngine.getUserContext('getNotificationInfo') + if cache is None: + cache = { 'id': -1 } + snmpEngine.setUserContext(getNotificationInfo=cache) if cache['id'] != snmpNotifyEntry.branchVersionId: cache['targetToNotifyMap'] = {} @@ -225,10 +225,10 @@ def getTargetNames(snmpEngine, tag): 'SNMP-TARGET-MIB', 'snmpTargetAddrEntry' ) - if 'getTargetNames' not in snmpEngine.cache: - snmpEngine.cache['getTargetNames'] = { 'id': -1 } - - cache = snmpEngine.cache['getTargetNames'] + cache = snmpEngine.getUserContext('getTargetNames') + if cache is None: + cache = { 'id': -1 } + snmpEngine.setUserContext(getTargetNames=cache) if cache['id'] == snmpTargetAddrEntry.branchVersionId: tagToTargetsMap = cache['tagToTargetsMap'] diff --git a/pysnmp/entity/rfc3413/ntforg.py b/pysnmp/entity/rfc3413/ntforg.py index 5018049..a3d7934 100644 --- a/pysnmp/entity/rfc3413/ntforg.py +++ b/pysnmp/entity/rfc3413/ntforg.py @@ -5,6 +5,7 @@ from pysnmp.proto.proxy import rfc2576 from pysnmp.proto import rfc3411 from pysnmp.proto.api import v2c from pysnmp.proto import error +from pysnmp.smi import view, rfc1902 from pysnmp import nextid from pysnmp import debug @@ -254,14 +255,12 @@ class NotificationOriginator: def sendVarBinds(self, snmpEngine, notificationTarget, - snmpContext, + contextEngineId, contextName, - notificationName, - instanceIndex, - additionalVarBinds=(), + varBinds=(), cbFun=None, cbCtx=None): - debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationTarget %s, notificationName %s, additionalVarBinds %s, contextName "%s", instanceIndex %s' % (notificationTarget, notificationName, additionalVarBinds, contextName, instanceIndex)) + debug.logger & debug.flagApp and debug.logger('sendVarBinds: notificationTarget %s, contextEngineId %s, contextName "%s", varBinds %s' % (notificationTarget, contextEngineId or '', contextName, varBinds)) if contextName: __SnmpAdminString, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('SNMP-FRAMEWORK-MIB', 'SnmpAdminString') @@ -277,10 +276,32 @@ class NotificationOriginator: debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s, notifyTag %s, notifyType %s' % (sendRequestHandle, notifyTag, notifyType)) - contextMibInstrumCtl = snmpContext.getMibInstrum(contextName) - - additionalVarBinds = [ (v2c.ObjectIdentifier(x),y) for x,y in additionalVarBinds ] + varBinds = [ (v2c.ObjectIdentifier(x),y) for x,y in varBinds ] + # 3.3.2 & 3.3.3 + snmpTrapOID, sysUpTime = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpTrapOID', 'sysUpTime') + + for idx in range(len(varBinds)): + if idx and varBinds[idx][0] == sysUpTime.getName(): + if varBinds[0][0] == sysUpTime.getName(): + varBinds[0] = varBinds[idx] + else: + varBinds.insert(0, varBinds[idx]) + del varBinds[idx] + + if varBinds[0][0] != sysUpTime.getName(): + varBinds.insert(0, (v2c.ObjectIdentifier(sysUpTime.getName()), + sysUpTime.getSyntax().clone())) + + if len(varBinds) < 2 or varBinds[1][0] != snmpTrapOID.getName(): + varBinds.insert(1, (v2c.ObjectIdentifier(snmpTrapOID.getName()), + snmpTrapOID.getSyntax())) + + debug.logger & debug.flagApp and debug.logger('sendVarBinds: final varBinds %s' % (varBinds,)) + + cbCtx = cbFun, cbCtx + cbFun = self.processResponseVarBinds + for targetAddrName in config.getTargetNames(snmpEngine, notifyTag): ( transportDomain, transportAddress, @@ -292,8 +313,6 @@ class NotificationOriginator: securityName, securityLevel ) = config.getTargetParams(snmpEngine, params) - debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (sendRequestHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) - # 3.3.1 XXX # XXX filtering's yet to be implemented # filterProfileName = config.getNotifyFilterProfile(params) @@ -302,57 +321,22 @@ class NotificationOriginator: # filterMask, # filterType ) = config.getNotifyFilter(filterProfileName) - varBinds = [] - - # 3.3.2 & 3.3.3 - sysUpTime, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'sysUpTime') - - for varName, varVal in additionalVarBinds: - if varName == sysUpTime.name: - varBinds.append((varName, varVal)) - break - if not varBinds: - varBinds.append((sysUpTime.name, - sysUpTime.syntax.clone())) # for actual value - - snmpTrapOid, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpTrapOID') - if len(notificationName) == 2: # ('MIB', 'symbol') - notificationTypeObject, = contextMibInstrumCtl.mibBuilder.importSymbols(*notificationName) - varBinds.append((snmpTrapOid.name, v2c.ObjectIdentifier(notificationTypeObject.name))) - debug.logger & debug.flagApp and debug.logger('sendVarBinds: notification type object is %s' % notificationTypeObject) - for notificationObject in notificationTypeObject.getObjects(): - mibNode, = contextMibInstrumCtl.mibBuilder.importSymbols(*notificationObject) - if instanceIndex: - mibNode = mibNode.getNode(mibNode.name + instanceIndex) - else: - mibNode = mibNode.getNextNode(mibNode.name) - varBinds.extend( - contextMibInstrumCtl.readVars( - [ (mibNode.name, None) ] # XXX AC is missing - ) - ) - debug.logger & debug.flagApp and debug.logger('sendVarBinds: processed notification object %s, instance index %s, var-bind %s' % (notificationObject, instanceIndex is None and "" or instanceIndex, mibNode)) - elif notificationName: # numeric OID - varBinds.append( - (snmpTrapOid.name, - snmpTrapOid.syntax.clone(notificationName)) - ) - else: - varBinds.append((snmpTrapOid.name, snmpTrapOid.syntax)) + debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s, notifyTag %s yields: transportDomain %s, transportAddress %r, securityModel %s, securityName %s, securityLevel %s' % (sendRequestHandle, notifyTag, transportDomain, transportAddress, securityModel, securityName, securityLevel)) - for varName, varVal in additionalVarBinds: - if varName in (sysUpTime.name, snmpTrapOid.name): + for varName, varVal in varBinds: + if varName in (sysUpTime.name, snmpTrapOID.name): continue try: snmpEngine.accessControlModel[self.acmID].isAccessAllowed( snmpEngine, securityModel, securityName, securityLevel, 'notify', contextName, varName ) + + debug.logger & debug.flagApp and debug.logger('sendVarBinds: ACL succeeded for OID %s securityName %s' % (varName, securityName)) + except error.StatusInformation: - debug.logger & debug.flagApp and debug.logger('sendVarBinds: OID %s not allowed for %s, droppping notification' % (varName, securityName)) + debug.logger & debug.flagApp and debug.logger('sendVarBinds: ACL denied access for OID %s securityName %s, droppping notification' % (varName, securityName)) return - else: - varBinds.append((varName, varVal)) # 3.3.4 if notifyType == 1: @@ -365,14 +349,11 @@ class NotificationOriginator: v2c.apiPDU.setDefaults(pdu) v2c.apiPDU.setVarBinds(pdu, varBinds) - cbCtx = cbFun, cbCtx - cbFun = self.processResponseVarBinds - # 3.3.5 try: sendPduHandle = self.sendPdu(snmpEngine, targetAddrName, - snmpContext.contextEngineId, + contextEngineId, contextName, pdu, cbFun, @@ -380,7 +361,7 @@ class NotificationOriginator: except error.StatusInformation: statusInformation = sys.exc_info()[1] - debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s: sendVarBindsPdu() failed with %r' % (sendRequestHandle, statusInformation)) + debug.logger & debug.flagApp and debug.logger('sendVarBinds: sendRequestHandle %s: sendPdu() failed with %r' % (sendRequestHandle, statusInformation)) if sendRequestHandle not in self.__pendingNotifications or \ not self.__pendingNotifications[sendRequestHandle]: if sendRequestHandle in self.__pendingNotifications: @@ -440,13 +421,39 @@ def _sendNotification(self, cbCtx = cbFun, cbCtx cbFun = _sendNotificationCbFun + # + # Here we first expand trap OID into associated OBJECTS + # and then look them up at context-specific MIB + # + + mibViewController = snmpEngine.getUserContext('mibViewController') + if not mibViewController: + mibViewController = view.MibViewController(snmpEngine.getMibBuilder()) + snmpEngine.setUserContext(mibViewController=mibViewController) + + # Support the following syntax: + # '1.2.3.4' + # (1,2,3,4) + # ('MIB', 'symbol') + if isinstance(notificationName, (tuple, list)) and \ + notificationName and isinstance(notificationName[0], str): + notificationName = rfc1902.ObjectIdentity(*notificationName) + else: + notificationName = rfc1902.ObjectIdentity(notificationName) + + varBinds = rfc1902.NotificationType( + notificationName, instanceIndex=instanceIndex + ).resolveWithMib(mibViewController) + + mibInstrumController = self.snmpContext.getMibInstrum(contextName) + + varBinds = varBinds[:1] + mibInstrumController.readVars(varBinds[1:]) + return self.sendVarBinds(snmpEngine, notificationTarget, - self.snmpContext, + self.snmpContext.contextEngineId, contextName, - notificationName, - instanceIndex, - additionalVarBinds, + varBinds + list(additionalVarBinds), cbFun, cbCtx) diff --git a/pysnmp/entity/rfc3413/oneliner/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/cmdgen.py index 00d8aa0..2e2a88c 100644 --- a/pysnmp/entity/rfc3413/oneliner/cmdgen.py +++ b/pysnmp/entity/rfc3413/oneliner/cmdgen.py @@ -1,6 +1,6 @@ from pysnmp.entity import engine, config from pysnmp.entity.rfc3413 import cmdgen -from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable +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 @@ -10,6 +10,8 @@ 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 @@ -30,21 +32,22 @@ class AsyncCommandGenerator: _null = univ.Null('') def _getCache(self, snmpEngine): - if 'cmdgen' not in snmpEngine.cache: - snmpEngine.cache['cmdgen'] = { - 'auth': {}, - 'parm': {}, - 'tran': {}, - 'addr': {}, - } - return snmpEngine.cache['cmdgen'] + cache = snmpEngine.getUserContext('cmdgen_cache') + if cache is None: + cache = { + 'auth': {}, 'parm': {}, 'tran': {}, 'addr': {} + } + snmpEngine.setUserContext(cmdgen_cache=cache) + return cache def getMibViewController(self, snmpEngine): - if 'mibViewController' not in snmpEngine.cache: - snmpEngine.cache['mibViewController'] = view.MibViewController( - snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder + mibViewController = snmpEngine.getUserContext('mibViewController') + if not mibViewController: + mibViewController = view.MibViewController( + snmpEngine.getMibBuilder() ) - return snmpEngine.cache['mibViewController'] + snmpEngine.setUserContext(mibViewController=mibViewController) + return mibViewController def cfgCmdGen(self, snmpEngine, authData, transportTarget): cache = self._getCache(snmpEngine) @@ -203,59 +206,35 @@ class AsyncCommandGenerator: return addrNames, paramsNames - def makeVarBinds(self, snmpEngine, varBinds, oidOnly=False): + def makeVarBinds(self, snmpEngine, varBinds): mibViewController = self.getMibViewController(snmpEngine) __varBinds = [] - for varName, varVal in varBinds: - if isinstance(varName, MibVariable): - if oidOnly or isinstance(varVal, base.AbstractSimpleAsn1Item): - varName.resolveWithMib(mibViewController, oidOnly=True) - else: - varName.resolveWithMib(mibViewController) - varVal = varName.getMibNode().getSyntax().clone(varVal) - elif isinstance(varName[0], tuple): # legacy - varName = MibVariable(varName[0][0], varName[0][1], *varName[1:]).resolveWithMib(mibViewController) - if not oidOnly and \ - not isinstance(varVal, base.AbstractSimpleAsn1Item): - varVal = varName.getMibNode().getSyntax().clone(varVal) + for varBind in varBinds: + if isinstance(varBind, ObjectType): + pass + elif isinstance(varBind[0], ObjectIdentity): + varBind = ObjectType(*varBind) + elif isinstance(varBind[0][0], tuple): # legacy + varBind = ObjectType(ObjectIdentity(varBind[0][0][0], varBind[0][0][1], *varBind[0][1:]), varBind[1]) else: - if oidOnly or isinstance(varVal, base.AbstractSimpleAsn1Item): - varName = MibVariable(varName).resolveWithMib(mibViewController, oidOnly=True) - else: - varName = MibVariable(varName).resolveWithMib(mibViewController) - try: - varVal = varName.getMibNode().getSyntax().clone(varVal) - except: - raise error.PySnmpError('Unresolved SNMP value type for OID %s (MIB not loaded?)' % (varName,)) + varBind = ObjectType(ObjectIdentity(varBind[0]), varBind[1]) - __varBinds.append((varName, varVal)) + __varBinds.append(varBind.resolveWithMib(mibViewController)) return __varBinds def unmakeVarBinds(self, snmpEngine, varBinds, lookupNames, lookupValues): if lookupNames or lookupValues: mibViewController = self.getMibViewController(snmpEngine) - _varBinds = [] - for name, value in varBinds: - varName = MibVariable(name).resolveWithMib(mibViewController) - if lookupNames: - name = varName - if lookupValues: - if value.tagSet not in (rfc1905.NoSuchObject.tagSet, - rfc1905.NoSuchInstance.tagSet, - rfc1905.EndOfMibView.tagSet): - if varName.isFullyResolved(): - value = varName.getMibNode().getSyntax().clone(value) - _varBinds.append((name, value)) - return _varBinds - else: - return varBinds + 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 ], oidOnly=True + [ (x, univ.Null('')) for x in varNames ] ) ] @@ -415,12 +394,12 @@ class AsynCommandGenerator: # compatibility stub def makeReadVarBinds(self, varNames): return self.makeVarBinds( - [ (x, univ.Null('')) for x in varNames ], oidOnly=True + [ (x, univ.Null('')) for x in varNames ] ) - def makeVarBinds(self, varBinds, oidOnly=False): + def makeVarBinds(self, varBinds): return self.__asyncCmdGen.makeVarBinds( - self.snmpEngine, varBinds, oidOnly + self.snmpEngine, varBinds ) def unmakeVarBinds(self, varBinds, lookupNames, lookupValues): diff --git a/pysnmp/entity/rfc3413/oneliner/mibvar.py b/pysnmp/entity/rfc3413/oneliner/mibvar.py index cb7b163..5e069ab 100644 --- a/pysnmp/entity/rfc3413/oneliner/mibvar.py +++ b/pysnmp/entity/rfc3413/oneliner/mibvar.py @@ -1,313 +1,6 @@ -from pysnmp.proto import rfc1902 -from pysnmp.smi.builder import ZipMibSource -from pysnmp.smi.compiler import addMibCompiler -from pysnmp.error import PySnmpError -from pyasn1.error import PyAsn1Error +# Obsolete interfaces, use pysnmp.smi.rfc1902 instead. +from pysnmp.smi import rfc1902 -# -# An OID-like object that embeds MIB resolution. -# -# Valid initializers include: -# MibVariable('1.3.6.1.2.1.1.1.0'), -# MibVariable('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0') -# MibVariable('SNMPv2-MIB', 'system'), -# MibVariable('SNMPv2-MIB', 'sysDescr', 0), -# MibVariable('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123), -# - -class MibVariable: - stDirty, stOidOnly, stClean, stUnresolved = 1, 2, 4, 8 - - def __init__(self, *args): - self.__args = args - self.__mibSourcesToAdd = self.__modNamesToLoad = None - self.__asn1SourcesToAdd = None - self.__state = self.stDirty - - # - # public API - # - def getMibSymbol(self): - if self.__state & self.stClean: - return self.__modName, self.__symName, self.__indices - else: - raise PySnmpError('%s object not fully initialized' % self.__class__.__name__) - - def getOid(self): - if self.__state & (self.stOidOnly | self.stClean): - return self.__oid - else: - raise PySnmpError('%s object not fully initialized' % self.__class__.__name__) - - def getLabel(self): - if self.__state & self.stClean: - return self.__label - else: - raise PySnmpError('%s object not fully initialized' % self.__class__.__name__) - - def getMibNode(self): # XXX - if self.__state & self.stClean: - return self.__mibNode - else: - raise PySnmpError('%s object not fully initialized' % self.__class__.__name__) - - def isFullyResolved(self): - return not (self.__state & self.stUnresolved) - - # - # A gateway to MIBs manipulation routines - # - - def addAsn1Sources(self, *asn1Sources): - self.__asn1SourcesToAdd = asn1Sources - return self - - def addMibSource(self, *mibSources): - self.__mibSourcesToAdd = mibSources - return self - - # provides deferred MIBs load - def loadMibs(self, *modNames): - self.__modNamesToLoad = modNames - return self - - # this would eventually be called by an entity which posses a - # reference to MibViewController - def resolveWithMib(self, mibViewController, oidOnly=False): - if self.__mibSourcesToAdd is not None: - mibSources = tuple( - [ ZipMibSource(x) for x in self.__mibSourcesToAdd ] - ) + mibViewController.mibBuilder.getMibSources() - mibViewController.mibBuilder.setMibSources(*mibSources) - self.__mibSourcesToAdd = None - - if self.__asn1SourcesToAdd is not None: - addMibCompiler( - mibViewController.mibBuilder, - sources=self.__asn1SourcesToAdd - ) - self.__asn1SourcesToAdd = None - - if self.__modNamesToLoad is not None: - mibViewController.mibBuilder.loadModules(*self.__modNamesToLoad) - self.__modNamesToLoad = None - - if self.__state & (self.stOidOnly | self.stClean): - return self - - MibScalar, MibTableColumn, = mibViewController.mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalar', 'MibTableColumn') - - if len(self.__args) == 1: # OID or label - try: - self.__oid = rfc1902.ObjectName(self.__args[0]) - except PyAsn1Error: - try: - label = tuple(self.__args[0].split('.')) - except ValueError: - raise PySnmpError('Bad OID format %s' % (self.__args[0],)) - prefix, label, suffix = mibViewController.getNodeNameByOid( - label - ) - - if suffix: - try: - suffix = tuple([ int(x) for x in suffix ]) - except ValueError: - raise PySnmpError('Unknown object name component %s' % (suffix,)) - - self.__oid = rfc1902.ObjectName(prefix + suffix) - - self.__state |= self.stOidOnly - - if oidOnly: - return self - else: - self.__state |= self.stOidOnly - - if oidOnly: - return self - - prefix, label, suffix = mibViewController.getNodeNameByOid( - self.__oid - ) - - modName, symName, _ = mibViewController.getNodeLocation(prefix) - - self.__modName = modName - self.__symName = symName - - self.__label = label - - mibNode, = mibViewController.mibBuilder.importSymbols( - modName, symName - ) - - self.__mibNode = mibNode - - if isinstance(mibNode, MibTableColumn): # table column - rowModName, rowSymName, _ = mibViewController.getNodeLocation( - mibNode.name[:-1] - ) - rowNode, = mibViewController.mibBuilder.importSymbols( - rowModName, rowSymName - ) - self.__indices = rowNode.getIndicesFromInstId(suffix) - elif isinstance(mibNode, MibScalar): # scalar - self.__indices = ( rfc1902.ObjectName(suffix), ) - else: - self.__indices = ( rfc1902.ObjectName(suffix), ) - self.__state |= self.stUnresolved - self.__state |= self.stClean - return self - elif len(self.__args) > 1: # MIB, symbol[, index, index ...] - self.__modName = self.__args[0] - if self.__args[1]: - self.__symName = self.__args[1] - else: - mibViewController.mibBuilder.loadModules(self.__modName) - oid, _, _ = mibViewController.getFirstNodeName(self.__modName) - _, self.__symName, _ = mibViewController.getNodeLocation(oid) - - mibNode, = mibViewController.mibBuilder.importSymbols( - self.__modName, self.__symName - ) - - self.__mibNode = mibNode - - self.__indices = () - self.__oid = rfc1902.ObjectName(mibNode.getName()) - - prefix, label, suffix = mibViewController.getNodeNameByOid( - self.__oid - ) - self.__label = label - - if isinstance(mibNode, MibTableColumn): # table - rowModName, rowSymName, _ = mibViewController.getNodeLocation( - mibNode.name[:-1] - ) - rowNode, = mibViewController.mibBuilder.importSymbols( - rowModName, rowSymName - ) - if self.__args[2:]: - instIds = rowNode.getInstIdFromIndices(*self.__args[2:]) - self.__oid += instIds - self.__indices = rowNode.getIndicesFromInstId(instIds) - elif self.__args[2:]: # any other kind of MIB node with indices - instId = rfc1902.ObjectName( - '.'.join([ str(x) for x in self.__args[2:] ]) - ) - self.__oid += instId - self.__indices = ( instId, ) - self.__state |= (self.stClean | self.stOidOnly) - return self - else: - raise PySnmpError('Non-OID, label or MIB symbol') - - def prettyPrint(self): - if self.__state & self.stClean: - return '%s::%s.%s' % ( - self.__modName, self.__symName, - '.'.join(['"%s"' % x.prettyPrint() for x in self.__indices ]) - ) - else: - raise PySnmpError('%s object not fully initialized' % self.__class__.__name__) - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join([ repr(x) for x in self.__args])) - - # Redirect some attrs access to the OID object to behave alike - - def __str__(self): - if self.__state & self.stOidOnly: - return str(self.__oid) - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __eq__(self, other): - if self.__state & self.stOidOnly: - return self.__oid == other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __ne__(self, other): - if self.__state & self.stOidOnly: - return self.__oid != other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __lt__(self, other): - if self.__state & self.stOidOnly: - return self.__oid < other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __le__(self, other): - if self.__state & self.stOidOnly: - return self.__oid <= other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __gt__(self, other): - if self.__state & self.stOidOnly: - return self.__oid > other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __ge__(self, other): - if self.__state & self.stOidOnly: - return self.__oid > other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __nonzero__(self): - if self.__state & self.stOidOnly: - return self.__oid != 0 - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __bool__(self): - if self.__state & self.stOidOnly: - return bool(self.__oid) - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __getitem__(self, i): - if self.__state & self.stOidOnly: - return self.__oid[i] - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __len__(self): - if self.__state & self.stOidOnly: - return len(self.__oid) - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __add__(self, other): - if self.__state & self.stOidOnly: - return self.__oid + other - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __radd__(self, other): - if self.__state & self.stOidOnly: - return other + self.__oid - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __hash__(self): - if self.__state & self.stOidOnly: - return hash(self.__oid) - else: - raise PySnmpError('%s object not properly initialized' % self.__class__.__name__) - - def __getattr__(self, attr): - if self.__state & self.stOidOnly: - if attr in ( 'asTuple', 'clone', 'subtype', 'isPrefixOf', - 'isSameTypeWith', 'isSuperTypeOf'): - return getattr(self.__oid, attr) - raise AttributeError - else: - raise PySnmpError('%s object not properly initialized for %s access' % (self.__class__.__name__, attr)) +class MibVariable(rfc1902.ObjectIdentity): pass +class MibVariableBinding(rfc1902.ObjectType): pass diff --git a/pysnmp/entity/rfc3413/oneliner/ntforg.py b/pysnmp/entity/rfc3413/oneliner/ntforg.py index c81667d..8fc20d0 100644 --- a/pysnmp/entity/rfc3413/oneliner/ntforg.py +++ b/pysnmp/entity/rfc3413/oneliner/ntforg.py @@ -1,12 +1,14 @@ 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.entity.rfc3413 import ntforg, context -from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable from pysnmp.entity.rfc3413.oneliner.auth import CommunityData, UsmUserData from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget, \ Udp6TransportTarget, UnixTransportTarget from pysnmp.entity.rfc3413.oneliner import cmdgen +# obsolete, compatibility symbols +from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable # Auth protocol usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol @@ -21,6 +23,8 @@ usmAesCfb192Protocol = config.usmAesCfb192Protocol usmAesCfb256Protocol = config.usmAesCfb256Protocol usmNoPrivProtocol = config.usmNoPrivProtocol +ContextData = cmdgen.ContextData + nextID = nextid.Integer(0xffffffff) class AsyncNotificationOriginator: @@ -28,21 +32,18 @@ class AsyncNotificationOriginator: self.__asyncCmdGen = cmdgen.AsyncCommandGenerator() def _getCache(self, snmpEngine): - if 'ntforg' not in snmpEngine.cache: - snmpEngine.cache['ntforg'] = { - 'auth': {}, - 'name': {} - } - return snmpEngine.cache['ntforg'] + cache = snmpEngine.getUserContext('ntforg') + if cache is None: + cache = { 'auth': {}, 'name': {} } + snmpEngine.setUserContext(ntforg=cache) + return cache def getMibViewController(self, snmpEngine): return self.__asyncCmdGen.getMibViewController(snmpEngine) def cfgNtfOrg(self, snmpEngine, authData, transportTarget, notifyType): cache = self._getCache(snmpEngine) - addrName, paramsName = self.__asyncCmdGen.cfgCmdGen( - snmpEngine, authData, transportTarget - ) + addrName, paramsName = self.__asyncCmdGen.cfgCmdGen( snmpEngine, authData, transportTarget ) tagList = transportTarget.tagList.split() if not tagList: tagList = [''] @@ -118,18 +119,30 @@ class AsyncNotificationOriginator: ) del cache['auth'][authDataKey] - def makeVarBinds(self, snmpEngine, varBinds, oidOnly=False): - return self.__asyncCmdGen.makeVarBinds(snmpEngine, varBinds, oidOnly) + def makeVarBinds(self, snmpEngine, varBinds): + mibViewController = self.getMibViewController(snmpEngine) + if isinstance(varBinds, NotificationType): + varBinds.resolveWithMib(mibViewController) + __varBinds = [] + for varBind in varBinds: + if isinstance(varBind, ObjectType): + pass + elif isinstance(varBind[0], ObjectIdentity): + varBind = ObjectType(*varBind) + else: + varBind = ObjectType(ObjectIdentity(varBind[0]), varBind[1]) + __varBinds.append(varBind.resolveWithMib(mibViewController)) + return __varBinds def unmakeVarBinds(self, snmpEngine, varBinds, lookupNames, lookupValues): - return self.__asyncCmdGen.unmakeVarBinds(snmpEngine, varBinds, - lookupNames, lookupValues) - + if lookupNames or lookupValues: + mibViewController = self.getMibViewController(snmpEngine) + varBinds = [ ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds ] + return varBinds + def sendNotification(self, snmpEngine, - authData, transportTarget, - snmpContext, contextName, + authData, transportTarget, contextData, notifyType, - notificationType, instanceIndex, varBinds=(), cbInfo=(None, None), lookupNames=False, lookupValues=False): @@ -148,7 +161,7 @@ class AsyncNotificationOriginator: cbCtx ) - (cbFun, cbCtx) = cbInfo + cbFun, cbCtx = cbInfo # Create matching transport tags if not given by user if not transportTarget.tagList: @@ -161,12 +174,8 @@ class AsyncNotificationOriginator: notifyName = self.cfgNtfOrg( snmpEngine, authData, transportTarget, notifyType ) - if isinstance(notificationType, MibVariable): - notificationType = notificationType.resolveWithMib( - self.getMibViewController(snmpEngine), oidOnly=True - ) - return ntforg.NotificationOriginator().sendVarBinds(snmpEngine, notifyName, snmpContext, contextName, notificationType, instanceIndex, self.makeVarBinds(snmpEngine, varBinds), __cbFun, (lookupNames, lookupValues, cbFun, cbCtx)) + return ntforg.NotificationOriginator().sendVarBinds(snmpEngine, notifyName, contextData.contextEngineId, contextData.contextName, self.makeVarBinds(snmpEngine, varBinds), __cbFun, (lookupNames, lookupValues, cbFun, cbCtx)) # substitute sendNotification return object for backward compatibility class ErrorIndicationReturn: @@ -176,7 +185,9 @@ class ErrorIndicationReturn: def __bool__(self): return bool(self.__vars[0]) def __str__(self): return str(self.__vars[0]) -# compatibility implementation, never use this class for new applications +# +# Compatibility implementation, never use this class for new applications +# class AsynNotificationOriginator: def __init__(self, snmpEngine=None, snmpContext=None): if snmpEngine is None: @@ -208,9 +219,10 @@ class AsynNotificationOriginator: def sendNotification(self, authData, transportTarget, notifyType, notificationType, - varBinds=(), + varBinds=(), # legacy, use NotificationType instead cbInfo=(None, None), lookupNames=False, lookupValues=False, + contextEngineId=None, # XXX ordering incompatibility contextName=null): def __cbFun(snmpEngine, sendRequestHandle, errorIndication, @@ -237,16 +249,23 @@ class AsynNotificationOriginator: if contextName is null and authData.contextName: contextName = authData.contextName - # legacy - if not isinstance(notificationType, MibVariable) and \ - isinstance(notificationType[0], tuple): - notificationType = MibVariable(notificationType[0][0], notificationType[0][1], *notificationType[1:]).resolveWithMib(self.mibViewController) + if not isinstance(notificationType, + (ObjectIdentity, ObjectType, NotificationType)): + if isinstance(notificationType[0], tuple): + # legacy + notificationType = ObjectIdentity(notificationType[0][0], notificationType[0][1], *notificationType[1:]) + else: + notificationType = ObjectIdentity(notificationType) + + if not isinstance(notificationType, NotificationType): + notificationType = NotificationType(notificationType) return self.__asyncNtfOrg.sendNotification( self.snmpEngine, authData, transportTarget, - self.snmpContext, contextName, - notifyType, notificationType, None, varBinds, + ContextData(contextEngineId or self.snmpContext.contextEngineId, + contextName), + notifyType, notificationType.addVarBinds(*varBinds), (__cbFun, cbInfo), lookupNames, lookupValues ) @@ -262,6 +281,8 @@ class NotificationOriginator: else: self.__asynNtfOrg = asynNtfOrg + # the varBinds parameter is legacy, use NotificationType instead + def sendNotification(self, authData, transportTarget, notifyType, notificationType, *varBinds, **kwargs): def __cbFun(sendRequestHandle, errorIndication, @@ -276,6 +297,7 @@ class NotificationOriginator: varBinds, (__cbFun, appReturn), kwargs.get('lookupNames', False), kwargs.get('lookupValues', False), + kwargs.get('contextEngineId'), kwargs.get('contextName', null) ) self.__asynNtfOrg.snmpEngine.transportDispatcher.runDispatcher() diff --git a/pysnmp/smi/compiler.py b/pysnmp/smi/compiler.py index c5fc2d9..dde6cdc 100644 --- a/pysnmp/smi/compiler.py +++ b/pysnmp/smi/compiler.py @@ -56,7 +56,7 @@ else: ) compiler.addBorrowers( - *[ PyFileBorrower(x) for x in getReadersFromUrls(*borrowers, originalMatching=False, lowcaseMatching=False) ] + *[ PyFileBorrower(x) for x in getReadersFromUrls(*borrowers, **dict(originalMatching=False, lowcaseMatching=False)) ] ) mibBuilder.setMibCompiler(compiler, destination) diff --git a/pysnmp/smi/rfc1902.py b/pysnmp/smi/rfc1902.py new file mode 100644 index 0000000..75fa7b9 --- /dev/null +++ b/pysnmp/smi/rfc1902.py @@ -0,0 +1,463 @@ +import sys +from pysnmp.proto import rfc1902, rfc1905 +from pysnmp.proto.api import v2c +from pysnmp.smi.builder import ZipMibSource +from pysnmp.smi.compiler import addMibCompiler, defaultDest +from pysnmp.smi.error import SmiError +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) +# +class ObjectIdentity: + stDirty, stClean = 1, 2 + + def __init__(self, *args): + self.__args = args + self.__mibSourcesToAdd = self.__modNamesToLoad = None + self.__asn1SourcesToAdd = None + self.__state = self.stDirty + + # + # public API + # + def getMibSymbol(self): + 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): + if self.__state & self.stClean: + return self.__oid + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + + def getLabel(self): + if self.__state & self.stClean: + return self.__label + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + + def getMibNode(self): + if self.__state & self.stClean: + return self.__mibNode + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + + # + # A gateway to MIBs manipulation routines + # + + def addMibCompiler(self, *asn1Sources, **kwargs): + if self.__asn1SourcesToAdd is None: + self.__asn1SourcesToAdd = asn1Sources + else: + self.__asn1SourcesToAdd += asn1Sources + self.__mibDir = kwargs.get('destDir', defaultDest) + return self + + def addMibSource(self, *mibSources): + if self.__mibSourcesToAdd is None: + self.__mibSourcesToAdd = mibSources + else: + self.__mibSourcesToAdd += mibSources + return self + + # provides deferred MIBs load + def loadMibs(self, *modNames): + if self.__modNamesToLoad is None: + self.__modNamesToLoad = modNames + else: + self.__modNamesToLoad += modNames + return self + + # this would eventually be called by an entity which posses a + # reference to MibViewController + def resolveWithMib(self, mibViewController): + if self.__mibSourcesToAdd is not None: + debug.logger & debug.flagMIB and debug.logger('adding MIB sources %s' % ', '.join(self.__mibSourcesToAdd)) + mibViewController.mibBuilder.addMibSources( + *[ ZipMibSource(x) for x in self.__mibSourcesToAdd ] + ) + self.__mibSourcesToAdd = None + + if self.__asn1SourcesToAdd is not None: + debug.logger & debug.flagMIB and debug.logger('adding MIB compiler with source paths %s' % ', '.join(self.__asn1SourcesToAdd)) + addMibCompiler( + mibViewController.mibBuilder, + sources=self.__asn1SourcesToAdd, + destination=self.__mibDir + ) + self.__asn1SourcesToAdd = self.__mibDir = None + + if self.__modNamesToLoad is not None: + debug.logger & debug.flagMIB and debug.logger('loading MIB modules %s' % ', '.join(self.__modNamesToLoad)) + mibViewController.mibBuilder.loadModules(*self.__modNamesToLoad) + self.__modNamesToLoad = None + + if self.__state & self.stClean: + return self + + MibScalar, MibTableColumn = mibViewController.mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalar', 'MibTableColumn') + + self.__indices = () + + if len(self.__args) == 1: # OID or label + debug.logger & debug.flagMIB and debug.logger('resolving %s as OID or label' % self.__args) + try: + self.__oid = rfc1902.ObjectName(self.__args[0]) + except PyAsn1Error: + try: + label = tuple(self.__args[0].split('.')) + except ValueError: + raise SmiError('Bad OID format %r' % (self.__args[0],)) + prefix, label, suffix = mibViewController.getNodeNameByOid( + label + ) + + if suffix: + try: + suffix = tuple([ int(x) for x in suffix ]) + except ValueError: + raise SmiError('Unknown object name component %r' % (suffix,)) + self.__oid = rfc1902.ObjectName(prefix + suffix) + else: + prefix, label, suffix = mibViewController.getNodeNameByOid( + self.__oid + ) + + debug.logger & debug.flagMIB and debug.logger('resolved %r into prefix %r and suffix %r' % (self.__args, prefix, suffix)) + + modName, symName, _ = mibViewController.getNodeLocation(prefix) + + self.__modName = modName + self.__symName = symName + + self.__label = label + + mibNode, = mibViewController.mibBuilder.importSymbols( + modName, symName + ) + + self.__mibNode = mibNode + + debug.logger & debug.flagMIB and debug.logger('resolved prefix %r into MIB node %r' % (prefix, mibNode)) + + if isinstance(mibNode, MibTableColumn): # table column + if suffix: + rowModName, rowSymName, _ = mibViewController.getNodeLocation( + mibNode.name[:-1] + ) + rowNode, = mibViewController.mibBuilder.importSymbols( + rowModName, rowSymName + ) + self.__indices = rowNode.getIndicesFromInstId(suffix) + elif isinstance(mibNode, MibScalar): # scalar + if suffix: + self.__indices = ( rfc1902.ObjectName(suffix), ) + else: + if suffix: + self.__indices = ( rfc1902.ObjectName(suffix), ) + self.__state |= self.stClean + + debug.logger & debug.flagMIB and debug.logger('resolved indices are %r' % (self.__indices,)) + + return self + elif len(self.__args) > 1: # MIB, symbol[, index, index ...] + self.__modName = self.__args[0] + if self.__args[1]: + self.__symName = self.__args[1] + else: + mibViewController.mibBuilder.loadModules(self.__modName) + oid, _, _ = mibViewController.getFirstNodeName(self.__modName) + _, self.__symName, _ = mibViewController.getNodeLocation(oid) + + mibNode, = mibViewController.mibBuilder.importSymbols( + self.__modName, self.__symName + ) + + self.__mibNode = mibNode + + self.__oid = rfc1902.ObjectName(mibNode.getName()) + + prefix, label, suffix = mibViewController.getNodeNameByOid( + self.__oid + ) + self.__label = label + + debug.logger & debug.flagMIB and debug.logger('resolved %r into prefix %r and suffix %r' % (self.__args, prefix, suffix)) + + if isinstance(mibNode, MibTableColumn): # table + rowModName, rowSymName, _ = mibViewController.getNodeLocation( + mibNode.name[:-1] + ) + rowNode, = mibViewController.mibBuilder.importSymbols( + rowModName, rowSymName + ) + if self.__args[2:]: + try: + instIds = rowNode.getInstIdFromIndices(*self.__args[2:]) + self.__oid += instIds + self.__indices = rowNode.getIndicesFromInstId(instIds) + except PyAsn1Error: + raise SmiError('Instance index %r to OID convertion failure at object %r: %s' % (self.__args[2:], mibNode.getLabel(), sys.exc_info()[1])) + elif self.__args[2:]: # any other kind of MIB node with indices + if self.__args[2:]: + instId = rfc1902.ObjectName( + '.'.join([ str(x) for x in self.__args[2:] ]) + ) + self.__oid += instId + self.__indices = ( instId, ) + self.__state |= self.stClean + + debug.logger & debug.flagMIB and debug.logger('resolved indices are %r' % (self.__indices,)) + + return self + else: + raise SmiError('Non-OID, label or MIB symbol') + + def prettyPrint(self): + if self.__state & self.stClean: + return '%s::%s%s%s' % ( + self.__modName, self.__symName, + self.__indices and '.' or '', + '.'.join(['"%s"' % x.prettyPrint() for x in self.__indices ]) + ) + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, ', '.join([ repr(x) for x in self.__args])) + + # Redirect some attrs access to the OID object to behave alike + + def __str__(self): + if self.__state & self.stClean: + return str(self.__oid) + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __eq__(self, other): + if self.__state & self.stClean: + return self.__oid == other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __ne__(self, other): + if self.__state & self.stClean: + return self.__oid != other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __lt__(self, other): + if self.__state & self.stClean: + return self.__oid < other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __le__(self, other): + if self.__state & self.stClean: + return self.__oid <= other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __gt__(self, other): + if self.__state & self.stClean: + return self.__oid > other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __ge__(self, other): + if self.__state & self.stClean: + return self.__oid > other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __nonzero__(self): + if self.__state & self.stClean: + return self.__oid != 0 + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __bool__(self): + if self.__state & self.stClean: + return bool(self.__oid) + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __getitem__(self, i): + if self.__state & self.stClean: + return self.__oid[i] + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __len__(self): + if self.__state & self.stClean: + return len(self.__oid) + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __add__(self, other): + if self.__state & self.stClean: + return self.__oid + other + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __radd__(self, other): + if self.__state & self.stClean: + return other + self.__oid + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __hash__(self): + if self.__state & self.stClean: + return hash(self.__oid) + else: + raise SmiError('%s object not properly initialized' % self.__class__.__name__) + + def __getattr__(self, attr): + if self.__state & self.stClean: + if attr in ( 'asTuple', 'clone', 'subtype', 'isPrefixOf', + 'isSameTypeWith', 'isSuperTypeOf'): + return getattr(self.__oid, attr) + raise AttributeError + else: + raise SmiError('%s object not properly initialized for accessing %s' % (self.__class__.__name__, attr)) + +# A two-element sequence of ObjectIdentity and SNMP data type object +class ObjectType: + stDirty, stClean = 1, 2 + def __init__(self, objectIdentity, objectSyntax=rfc1905.unSpecified): + if not isinstance(objectIdentity, ObjectIdentity): + raise SmiError('initializer should be ObjectIdentity instance, not %r' % (objectIdentity,)) + self.__args = [ objectIdentity, objectSyntax ] + self.__state = self.stDirty + + def __getitem__(self, i): + if self.__state & self.stClean: + return self.__args[i] + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, ', '.join([ repr(x) for x in self.__args])) + + def resolveWithMib(self, mibViewController): + if self.__state & self.stClean: + return self + + self.__args[0].resolveWithMib(mibViewController) + + MibScalar, MibTableColumn = mibViewController.mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalar', 'MibTableColumn') + + if not isinstance(self.__args[0].getMibNode(), + (MibScalar, MibTableColumn)): + if not isinstance(self.__args[1], AbstractSimpleAsn1Item): + raise SmiError('MIB object %r is not OBJECT-TYPE (MIB not loaded?)' % (self.__args[0],)) + self.__state |= self.stClean + return self + + if isinstance(self.__args[1], (rfc1905.UnSpecified, + rfc1905.NoSuchObject, + rfc1905.NoSuchInstance, + rfc1905.EndOfMibView)): + self.__state |= self.stClean + return self + + try: + self.__args[1] = self.__args[0].getMibNode().getSyntax().clone(self.__args[1]) + except PyAsn1Error: + raise SmiError('Value %r to type %r convertion failure: %s' % (self.__args[1], self.__args[0].getMibNode().getSyntax().__class__.__name__, sys.exc_info()[1])) + + self.__state |= self.stClean + + debug.logger & debug.flagMIB and debug.logger('resolved %r syntax is %r' % (self.__args[0], self.__args[1])) + + return self + + def prettyPrint(self): + if self.__state & self.stClean: + return '%s = %s' % (self.__args[0].prettyPrint(), + self.__args[1].prettyPrint()) + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + +# A sequence of ObjectType's +class NotificationType: + stDirty, stClean = 1, 2 + def __init__(self, objectIdentity, instanceIndex=(), objects={}): + if not isinstance(objectIdentity, ObjectIdentity): + raise SmiError('initializer should be ObjectIdentity instance, not %r' % (objectIdentity,)) + self.__objectIdentity = objectIdentity + self.__instanceIndex = instanceIndex + self.__objects = objects + self.__varBinds = [] + self.__additionalVarBinds = [] + self.__state = self.stDirty + + def __getitem__(self, i): + if self.__state & self.stClean: + return self.__varBinds[i] + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) + + def __repr__(self): + return '%s(%r, %r, %r)' % (self.__class__.__name__, self.__objectIdentity, self.__instanceIndex, self.__objects) + + def addVarBinds(self, *varBinds): + debug.logger & debug.flagMIB and debug.logger('additional var-binds: %r' % (varBinds,)) + if self.__state & self.stClean: + self.__varBinds.extend(varBinds) + else: + self.__additionalVarBinds.extend(varBinds) + return self + + def resolveWithMib(self, mibViewController): + if self.__state & self.stClean: + return self + + self.__objectIdentity.resolveWithMib(mibViewController) + + self.__varBinds.append( + ObjectType(ObjectIdentity(v2c.apiTrapPDU.snmpTrapOID), + self.__objectIdentity).resolveWithMib(mibViewController) + ) + + NotificationType, = mibViewController.mibBuilder.importSymbols('SNMPv2-SMI', 'NotificationType') + + mibNode = self.__objectIdentity.getMibNode() + + if isinstance(mibNode, NotificationType): + for notificationObject in mibNode.getObjects(): + objectIdentity = ObjectIdentity(*notificationObject+self.__instanceIndex).resolveWithMib(mibViewController) + self.__varBinds.append( + ObjectType(objectIdentity, self.__objects.get(notificationObject, rfc1905.unSpecified)).resolveWithMib(mibViewController) + ) + else: + debug.logger & debug.flagMIB and debug.logger('WARNING: MIB object %r is not NOTIFICATION-TYPE (MIB not loaded?)' % (self.__objectIdentity,)) + + if self.__additionalVarBinds: + self.__varBinds.extend(self.__additionalVarBinds) + self.__additionalVarBinds = [] + + self.__state |= self.stClean + + debug.logger & debug.flagMIB and debug.logger('resolved %r into %r' % (self.__objectIdentity, self.__varBinds)) + + return self + + def prettyPrint(self): + if self.__state & self.stClean: + return ' '.join([ '%s = %s' % (x[0].prettyPrint(), x[1].prettyPrint()) for x in self.__varBinds]) + else: + raise SmiError('%s object not fully initialized' % self.__class__.__name__) -- cgit v1.2.1