2

I am implementing a Pysnmp responder that receives SNMP GET/SET requests currently and would like to extend with Walk, getNext and getBulk operations. All the OID and its values are stored in key-value in a file.

What I have tried is to use readNextVars() method from instrum.AbstractMibInstrumController class where I iterate over OID's list by calling self.readVars() within readNextVars()

Below is a code snippet showing only GET request and SET request is similar but it writes value to its respective OID in oid.json file.

from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
from pysnmp.carrier.asynsock.dgram import udp
from pysnmp.smi import instrum, error
from pysnmp.proto.api import v2c
import json

class SnmpData:

    def __init__(self, host, port):
        self.snmpEngine = engine.SnmpEngine()

        config.addSocketTransport(
            self.snmpEngine,
            udp.domainName,
            udp.UdpTransport().openServerMode((host, port))
        )
        config.addV1System(self.snmpEngine, 'my-area', 'public', contextName='my-context')

        config.addVacmUser(self.snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1, 3, 6), (4, 5, 7))

        self.snmpContext = context.SnmpContext(self.snmpEngine)

    def snmp_run_command(self):
        self.snmpContext.registerContextName(
            v2c.OctetString('my-context'),
            FileInstrumController()
        )

        cmdrsp.GetCommandResponder(self.snmpEngine, self.snmpContext)
        cmdrsp.SetCommandResponder(self.snmpEngine, self.snmpContext)
        cmdrsp.NextCommandResponder(self.snmpEngine, self.snmpContext)
        cmdrsp.BulkCommandResponder(self.snmpEngine, self.snmpContext)

        self.snmpEngine.transportDispatcher.jobStarted(1)

        try:
            self.snmpEngine.transportDispatcher.runDispatcher()
        except:
            self.snmpEngine.transportDispatcher.closeDispatcher()
            return "yes"

    def main(self):
        self.snmp_run_command()

class FileInstrumController(instrum.AbstractMibInstrumController):
    def readVars(self, vars, acInfo=(None, None)):
        try:
            data = None
            final_data = None
            with open('oid.json') as f:
                data = json.load(f)

                if str(vars[0][0]) in data.keys())):
                    final_data = data[str(vars[0][0])]
                    return [(vars[0][0], v2c.OctetString(str(final_data)))]
                else:
                    return [(vars[0][0], v2c.OctetString(str("Not a Valid OID")))]
        except IOError:
            raise error.SmiError

    def readNextVars(self, vars, acInfo=(None, None))
        # get oid & split and match if in file than return its value
        # else return invalid oid and break but its not breaking 
        # and sending continuously requests of next oid (OID + 1)

Here is the oid file (oid.json)

{
      "1.3.6.1.1.999.1.1.0": 1,
      "1.3.6.1.1.999.1.2.0": 2,
      "1.3.6.1.1.999.1.3.0": 3,
      "1.3.6.1.1.999.1.4.0": 4,
      "1.3.6.1.1.999.1.5.0": 5,
      "1.3.6.1.1.999.1.6.0": 100,
      "1.3.6.1.1.999.1.7.0": 200,
      "1.3.6.1.1.999.1.8.0": 300,
      "1.3.6.1.1.999.1.9.0": 400,
      "1.3.6.1.1.999.1.10.0": 500
}

0 Answers0