From 9f6230113ecd60c40d9739bf43799f9eac306a32 Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Mon, 6 Nov 2017 14:32:00 +0100 Subject: encode IPv6 requirement into example scripts names (#102) --- ...enting-scalar-mib-objects-over-ipv4-and-ipv6.py | 165 +++++++++++++++++++++ .../cmdrsp/implementing-scalar-mib-objects.py | 165 --------------------- 2 files changed, 165 insertions(+), 165 deletions(-) create mode 100644 examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects-over-ipv4-and-ipv6.py delete mode 100644 examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects.py (limited to 'examples/v1arch') diff --git a/examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects-over-ipv4-and-ipv6.py b/examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects-over-ipv4-and-ipv6.py new file mode 100644 index 00000000..328e5d28 --- /dev/null +++ b/examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects-over-ipv4-and-ipv6.py @@ -0,0 +1,165 @@ +""" +Implementing scalar MIB objects ++++++++++++++++++++++++++++++++ + +Listen and respond to SNMP GET/GETNEXT queries with the following options: + +* SNMPv1 or SNMPv2c +* with SNMP community "public" +* over IPv4/UDP, listening at 127.0.0.1:161 +* over IPv6/UDP, listening at [::1]:161 +* serving two Managed Objects Instances (sysDescr.0 and sysUptime.0) + +Either of the following Net-SNMP commands will walk this Agent: + +| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6 +| $ snmpwalk -v2c -c public udp6:[::1] .1.3.6 + +The Command Receiver below uses two distinct transports for communication +with Command Generators - UDP over IPv4 and UDP over IPv6. + +"""# +from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher +from pysnmp.carrier.asyncore.dgram import udp, udp6, unix +from pyasn1.codec.ber import encoder, decoder +from pysnmp.proto import api +import time, bisect + + +class SysDescr(object): + name = (1, 3, 6, 1, 2, 1, 1, 1, 0) + + def __eq__(self, other): return self.name == other + + def __ne__(self, other): return self.name != other + + def __lt__(self, other): return self.name < other + + def __le__(self, other): return self.name <= other + + def __gt__(self, other): return self.name > other + + def __ge__(self, other): return self.name >= other + + def __call__(self, protoVer): + return api.protoModules[protoVer].OctetString( + 'PySNMP example command responder' + ) + + +class Uptime(object): + name = (1, 3, 6, 1, 2, 1, 1, 3, 0) + birthday = time.time() + + def __eq__(self, other): return self.name == other + + def __ne__(self, other): return self.name != other + + def __lt__(self, other): return self.name < other + + def __le__(self, other): return self.name <= other + + def __gt__(self, other): return self.name > other + + def __ge__(self, other): return self.name >= other + + def __call__(self, protoVer): + return api.protoModules[protoVer].TimeTicks( + (time.time() - self.birthday) * 100 + ) + + +mibInstr = ( + SysDescr(), Uptime() # sorted by object name +) + +mibInstrIdx = {} +for mibVar in mibInstr: + mibInstrIdx[mibVar.name] = mibVar + + +def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg): + while wholeMsg: + msgVer = api.decodeMessageVersion(wholeMsg) + if msgVer in api.protoModules: + pMod = api.protoModules[msgVer] + else: + print('Unsupported SNMP version %s' % msgVer) + return + reqMsg, wholeMsg = decoder.decode( + wholeMsg, asn1Spec=pMod.Message(), + ) + rspMsg = pMod.apiMessage.getResponse(reqMsg) + rspPDU = pMod.apiMessage.getPDU(rspMsg) + reqPDU = pMod.apiMessage.getPDU(reqMsg) + varBinds = [] + pendingErrors = [] + errorIndex = 0 + # GETNEXT PDU + if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()): + # Produce response var-binds + for oid, val in pMod.apiPDU.getVarBinds(reqPDU): + errorIndex = errorIndex + 1 + # Search next OID to report + nextIdx = bisect.bisect(mibInstr, oid) + if nextIdx == len(mibInstr): + # Out of MIB + varBinds.append((oid, val)) + pendingErrors.append( + (pMod.apiPDU.setEndOfMibError, errorIndex) + ) + else: + # Report value if OID is found + varBinds.append( + (mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer)) + ) + elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()): + for oid, val in pMod.apiPDU.getVarBinds(reqPDU): + if oid in mibInstrIdx: + varBinds.append((oid, mibInstrIdx[oid](msgVer))) + else: + # No such instance + varBinds.append((oid, val)) + pendingErrors.append( + (pMod.apiPDU.setNoSuchInstanceError, errorIndex) + ) + break + else: + # Report unsupported request type + pMod.apiPDU.setErrorStatus(rspPDU, 'genErr') + pMod.apiPDU.setVarBinds(rspPDU, varBinds) + # Commit possible error indices to response PDU + for f, i in pendingErrors: + f(rspPDU, i) + transportDispatcher.sendMessage( + encoder.encode(rspMsg), transportDomain, transportAddress + ) + return wholeMsg + + +transportDispatcher = AsyncoreDispatcher() +transportDispatcher.registerRecvCbFun(cbFun) + +# UDP/IPv4 +transportDispatcher.registerTransport( + udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161)) +) + +# UDP/IPv6 +transportDispatcher.registerTransport( + udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 161)) +) + +## Local domain socket +# transportDispatcher.registerTransport( +# unix.domainName, unix.UnixSocketTransport().openServerMode('/tmp/snmp-agent') +# ) + +transportDispatcher.jobStarted(1) + +try: + # Dispatcher will never finish as job#1 never reaches zero + transportDispatcher.runDispatcher() +except: + transportDispatcher.closeDispatcher() + raise diff --git a/examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects.py b/examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects.py deleted file mode 100644 index 328e5d28..00000000 --- a/examples/v1arch/asyncore/agent/cmdrsp/implementing-scalar-mib-objects.py +++ /dev/null @@ -1,165 +0,0 @@ -""" -Implementing scalar MIB objects -+++++++++++++++++++++++++++++++ - -Listen and respond to SNMP GET/GETNEXT queries with the following options: - -* SNMPv1 or SNMPv2c -* with SNMP community "public" -* over IPv4/UDP, listening at 127.0.0.1:161 -* over IPv6/UDP, listening at [::1]:161 -* serving two Managed Objects Instances (sysDescr.0 and sysUptime.0) - -Either of the following Net-SNMP commands will walk this Agent: - -| $ snmpwalk -v2c -c public 127.0.0.1 .1.3.6 -| $ snmpwalk -v2c -c public udp6:[::1] .1.3.6 - -The Command Receiver below uses two distinct transports for communication -with Command Generators - UDP over IPv4 and UDP over IPv6. - -"""# -from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher -from pysnmp.carrier.asyncore.dgram import udp, udp6, unix -from pyasn1.codec.ber import encoder, decoder -from pysnmp.proto import api -import time, bisect - - -class SysDescr(object): - name = (1, 3, 6, 1, 2, 1, 1, 1, 0) - - def __eq__(self, other): return self.name == other - - def __ne__(self, other): return self.name != other - - def __lt__(self, other): return self.name < other - - def __le__(self, other): return self.name <= other - - def __gt__(self, other): return self.name > other - - def __ge__(self, other): return self.name >= other - - def __call__(self, protoVer): - return api.protoModules[protoVer].OctetString( - 'PySNMP example command responder' - ) - - -class Uptime(object): - name = (1, 3, 6, 1, 2, 1, 1, 3, 0) - birthday = time.time() - - def __eq__(self, other): return self.name == other - - def __ne__(self, other): return self.name != other - - def __lt__(self, other): return self.name < other - - def __le__(self, other): return self.name <= other - - def __gt__(self, other): return self.name > other - - def __ge__(self, other): return self.name >= other - - def __call__(self, protoVer): - return api.protoModules[protoVer].TimeTicks( - (time.time() - self.birthday) * 100 - ) - - -mibInstr = ( - SysDescr(), Uptime() # sorted by object name -) - -mibInstrIdx = {} -for mibVar in mibInstr: - mibInstrIdx[mibVar.name] = mibVar - - -def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg): - while wholeMsg: - msgVer = api.decodeMessageVersion(wholeMsg) - if msgVer in api.protoModules: - pMod = api.protoModules[msgVer] - else: - print('Unsupported SNMP version %s' % msgVer) - return - reqMsg, wholeMsg = decoder.decode( - wholeMsg, asn1Spec=pMod.Message(), - ) - rspMsg = pMod.apiMessage.getResponse(reqMsg) - rspPDU = pMod.apiMessage.getPDU(rspMsg) - reqPDU = pMod.apiMessage.getPDU(reqMsg) - varBinds = [] - pendingErrors = [] - errorIndex = 0 - # GETNEXT PDU - if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()): - # Produce response var-binds - for oid, val in pMod.apiPDU.getVarBinds(reqPDU): - errorIndex = errorIndex + 1 - # Search next OID to report - nextIdx = bisect.bisect(mibInstr, oid) - if nextIdx == len(mibInstr): - # Out of MIB - varBinds.append((oid, val)) - pendingErrors.append( - (pMod.apiPDU.setEndOfMibError, errorIndex) - ) - else: - # Report value if OID is found - varBinds.append( - (mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer)) - ) - elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()): - for oid, val in pMod.apiPDU.getVarBinds(reqPDU): - if oid in mibInstrIdx: - varBinds.append((oid, mibInstrIdx[oid](msgVer))) - else: - # No such instance - varBinds.append((oid, val)) - pendingErrors.append( - (pMod.apiPDU.setNoSuchInstanceError, errorIndex) - ) - break - else: - # Report unsupported request type - pMod.apiPDU.setErrorStatus(rspPDU, 'genErr') - pMod.apiPDU.setVarBinds(rspPDU, varBinds) - # Commit possible error indices to response PDU - for f, i in pendingErrors: - f(rspPDU, i) - transportDispatcher.sendMessage( - encoder.encode(rspMsg), transportDomain, transportAddress - ) - return wholeMsg - - -transportDispatcher = AsyncoreDispatcher() -transportDispatcher.registerRecvCbFun(cbFun) - -# UDP/IPv4 -transportDispatcher.registerTransport( - udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161)) -) - -# UDP/IPv6 -transportDispatcher.registerTransport( - udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 161)) -) - -## Local domain socket -# transportDispatcher.registerTransport( -# unix.domainName, unix.UnixSocketTransport().openServerMode('/tmp/snmp-agent') -# ) - -transportDispatcher.jobStarted(1) - -try: - # Dispatcher will never finish as job#1 never reaches zero - transportDispatcher.runDispatcher() -except: - transportDispatcher.closeDispatcher() - raise -- cgit v1.2.1