summaryrefslogtreecommitdiff
path: root/pysnmp/hlapi/v1arch/asyncio/ntforg.py
diff options
context:
space:
mode:
Diffstat (limited to 'pysnmp/hlapi/v1arch/asyncio/ntforg.py')
-rw-r--r--pysnmp/hlapi/v1arch/asyncio/ntforg.py106
1 files changed, 66 insertions, 40 deletions
diff --git a/pysnmp/hlapi/v1arch/asyncio/ntforg.py b/pysnmp/hlapi/v1arch/asyncio/ntforg.py
index 25d831e9..96005813 100644
--- a/pysnmp/hlapi/v1arch/asyncio/ntforg.py
+++ b/pysnmp/hlapi/v1arch/asyncio/ntforg.py
@@ -4,18 +4,19 @@
# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysnmp/license.html
#
-from pysnmp.hlapi.v1arch.auth import *
-from pysnmp.hlapi.varbinds import *
-from pysnmp.hlapi.v1arch.asyncio.transport import *
-from pysnmp.smi.rfc1902 import *
-from pysnmp.proto import api
-
try:
import asyncio
except ImportError:
import trollius as asyncio
+from pysnmp.hlapi.v1arch.auth import *
+from pysnmp.hlapi.varbinds import *
+from pysnmp.hlapi.v1arch.asyncio.transport import *
+from pysnmp.smi.rfc1902 import *
+from pysnmp.proto.api import v2c
+from pysnmp.proto.proxy import rfc2576
+
__all__ = ['sendNotification']
VB_PROCESSOR = NotificationOriginatorVarBinds()
@@ -54,24 +55,27 @@ def sendNotification(snmpDispatcher, authData, transportTarget,
or :py:class:`~pysnmp.smi.rfc1902.ObjectType` class instances
of :py:class:`~pysnmp.smi.rfc1902.NotificationType` objects.
- SNMP Notification PDU places rigid requirement on the ordering of
- the variable-bindings.
-
- Mandatory variable-bindings:
+ Besides user variable-bindings, SNMP Notification PDU requires at
+ least two variable-bindings to be present:
0. SNMPv2-MIB::sysUpTime.0 = <agent uptime>
- 1. SNMPv2-SMI::snmpTrapOID.0 = {SNMPv2-MIB::coldStart, ...}
+ 1. SNMPv2-SMI::snmpTrapOID.0 = <notification ID>
- Optional variable-bindings (applicable to SNMP v1 TRAP):
+ When sending SNMPv1 TRAP, more variable-bindings could be present:
2. SNMP-COMMUNITY-MIB::snmpTrapAddress.0 = <agent-IP>
3. SNMP-COMMUNITY-MIB::snmpTrapCommunity.0 = <snmp-community-name>
4. SNMP-COMMUNITY-MIB::snmpTrapEnterprise.0 = <enterprise-OID>
- Informational variable-bindings:
+ If user does not supply some or any of the above variable-bindings or
+ if they are at the wrong positions, the system will add/reorder the
+ missing ones automatically.
- * SNMPv2-SMI::NOTIFICATION-TYPE
- * SNMPv2-SMI::OBJECT-TYPE
+ On top of that, some notification types imply including some additional
+ variable-bindings providing additional details on the event being
+ reported. Therefore it is generally easier to use
+ :py:class:`~pysnmp.smi.rfc1902.NotificationType` object which will
+ help adding relevant variable-bindings.
Other Parameters
----------------
@@ -125,14 +129,50 @@ def sendNotification(snmpDispatcher, authData, transportTarget,
>>>
"""
+ sysUpTime = v2c.apiTrapPDU.sysUpTime
+ snmpTrapOID = v2c.apiTrapPDU.snmpTrapOID
+
+ def _ensureVarBinds(varBinds):
+ # Add sysUpTime if not present already
+ if not varBinds or varBinds[0][0] != sysUpTime:
+ varBinds.insert(0, (v2c.ObjectIdentifier(sysUpTime), v2c.TimeTicks(0)))
+
+ # Search for and reposition sysUpTime if it's elsewhere
+ for idx, varBind in enumerate(varBinds[1:]):
+ if varBind[0] == sysUpTime:
+ varBinds[0] = varBind
+ del varBinds[idx]
+ break
+
+ if len(varBinds) < 2:
+ raise error.PySnmpError('SNMP notification PDU requires '
+ 'SNMPv2-MIB::snmpTrapOID.0 to be present')
+
+ # Search for and reposition snmpTrapOID if it's elsewhere
+ for idx, varBind in enumerate(varBinds[2:]):
+ if varBind[0] == snmpTrapOID:
+ del varBinds[idx]
+ if varBinds[1][0] == snmpTrapOID:
+ varBinds[1] = varBind
+ else:
+ varBinds.insert(1, varBind)
+ break
+
+ # Fail on missing snmpTrapOID
+ if varBinds[1][0] != snmpTrapOID:
+ raise error.PySnmpError('SNMP notification PDU requires '
+ 'SNMPv2-MIB::snmpTrapOID.0 to be present')
+
+ return varBinds
+
def _cbFun(snmpDispatcher, stateHandle, errorIndication, rspPdu, _cbCtx):
if future.cancelled():
return
- errorStatus = pMod.apiTrapPDU.getErrorStatus(rspPdu)
- errorIndex = pMod.apiTrapPDU.getErrorIndex(rspPdu)
+ errorStatus = v2c.apiTrapPDU.getErrorStatus(rspPdu)
+ errorIndex = v2c.apiTrapPDU.getErrorIndex(rspPdu)
- varBinds = pMod.apiTrapPDU.getVarBinds(rspPdu)
+ varBinds = v2c.apiTrapPDU.getVarBinds(rspPdu)
try:
varBindsUnmade = VB_PROCESSOR.unmakeVarBinds(snmpDispatcher.cache, varBinds,
@@ -154,31 +194,17 @@ def sendNotification(snmpDispatcher, authData, transportTarget,
if lookupMib:
varBinds = VB_PROCESSOR.makeVarBinds(snmpDispatcher.cache, varBinds)
- # # make sure required PDU payload is in place
- # completeVarBinds = []
- #
- # # ensure sysUpTime
- # if len(varBinds) < 1 or varBinds[0][0] != pMod.apiTrapPDU.sysUpTime:
- # varBinds.insert(0, (ObjectIdentifier(pMod.apiTrapPDU.sysUpTime), pMod.Integer(0)))
- #
- # # ensure sysUpTime
- # if len(varBinds) < 1 or varBinds[0][0] != pMod.apiTrapPDU.sysUpTime:
- # varBinds.insert(0, (ObjectIdentifier(pMod.apiTrapPDU.sysUpTime), pMod.Integer(0)))
- #
- # # ensure snmpTrapOID
- # if len(varBinds) < 2 or varBinds[1][0] != pMod.apiTrapPDU.snmpTrapOID:
- # varBinds.insert(0, (ObjectIdentifier(pMod.apiTrapPDU.sysUpTime), pMod.Integer(0)))
-
- # input PDU is always v2c
- pMod = api.PROTOCOL_MODULES[api.SNMP_VERSION_2C]
-
if notifyType == 'trap':
- reqPdu = pMod.TrapPDU()
+ reqPdu = v2c.TrapPDU()
else:
- reqPdu = pMod.InformRequestPDU()
+ reqPdu = v2c.InformRequestPDU()
+
+ v2c.apiTrapPDU.setDefaults(reqPdu)
+ v2c.apiTrapPDU.setVarBinds(reqPdu, varBinds)
+
+ varBinds = v2c.apiTrapPDU.getVarBinds(reqPdu)
- pMod.apiTrapPDU.setDefaults(reqPdu)
- pMod.apiTrapPDU.setVarBinds(reqPdu, varBinds)
+ v2c.apiTrapPDU.setVarBinds(reqPdu, _ensureVarBinds(varBinds))
if authData.mpModel == 0:
reqPdu = rfc2576.v2ToV1(reqPdu)