PySNMP Project Logo

Project diary
Documentation
Examples
License
Download
Mailing lists

Projects using PySNMP
TwistedSNMP
Zenoss


Relevant projects
SNMPy
YAPSNMP
LibSMI
Scotty software

SourceForge Logo

import types
import string
import socket
import asyncore
import asynchat

# Import asynchronous wrap over PySNMP module
from pysnmp import asynsnmp

class telnet_engine (asynchat.async_chat):
    """Telnet engine class. Implements command line user interface.
    """
    def __init__ (self, sock):
        # Call constructor of the parent class
        asynchat.async_chat.__init__ (self, sock)

        # Set up input line terminator
        self.set_terminator ('\n')

        # Initialize input data buffer
        self.data = ''

        # User interface goodies
        self.prompt = 'query> '
        self.welcome = 'Example Telnet server / SNMP manager ready.\n'
        self.help = 'Syntax:   \n'

        # Send welcome message down to user. By using push() method we
        # having asynchronous engine delivering welcome message to user.
        self.push (self.welcome + self.help + self.prompt)
                  
    def collect_incoming_data (self, data):
        """Put data read from socket to a buffer
        """
        # Collect data in input buffer
        self.data = self.data + data

    def found_terminator (self):
        """This method is called by asynchronous engine when it finds
           command terminator in the input stream
        """   
        # Take the complete line
        line = self.data

        # Reset input buffer
        self.data = ''

        # Handle user command
        response = self.process_command (line)

        # Let's see if there is anything to reply to user
        if response:
            # Deliver message back to user
            self.push (response + '\n' + self.prompt)

    def request_done_fun (self, manager, context,\
                          encoded_objids, encoded_values):
        """Callback method invoked by SNMP manager object as request
           completes. Asynchronous SNMP manager object passes back a
           reference to object instance that initiated this SNMP request
           along with lists of BER encoded Object IDs and associated
           values as received from SNMP agent.
        """
        # Close SNMP session
        manager.close ()

        # Initialize response buffer
        response = 'Response from agent %s:\n' % manager.agent

        # See if there is a response from remote SNMP agent
        if encoded_objids is None or encoded_values is None:
            response = response + 'Remote SNMP agent reported an error (possibly bad Object ID)\n'
        else:
            # Decode BER encoded Object ID.
            objids = map (manager.decode_value, encoded_objids)

            # Decode BER encoded values associated with Object IDs.
            values = map (manager.decode_value, encoded_values)

            # Convert two lists into a list of tuples for easier printing
            results = map (None, objids, values)

            # Just print them out
            for (objid, value) in results:
                response =  response + objid + ' ---> ' + str(value) + '\n'

        # Send reply back to user
        self.push (response + self.prompt)

    def process_command (self, line):
        """Process user input
        """
        # Make sure request is not empty
        if not line:
            # Just do nothing
            return ''

        # Split request up to fields
        args = string.split (line)

        # Make sure we got enough arguments
        if len (args) < 3:
            return 'Insufficient number of arguments'

        # Create new asynchronous SNMP manager object and pass
        # user supplied arguments along with callback method and
        # a reference to an instance of calling class.
        manager = asynsnmp.async_session (args[0], args[1], \
                                          self.request_done_fun,\
                                          self)

        # Convert string type Object IDs into numeric representation
        numeric_objids = map (manager.str2nums, args[2:])

        # BER encode SNMP Object IDs to query
        encoded_objids = map (manager.encode_oid, numeric_objids)

        # Since we are going to _query_ SNMP agent for Object ID
        # associated value, there will be no Object ID value passed to SNMP
        # agent.
        encoded_values = []

        # Open SNMP session
        manager.open ()
        
        # Build and send SNMP message of type 'GETREQUEST', pass it a list
        # of BER encoded Object IDs to query (only one in this case) and
        # an empty list of associated values for these Object IDs (empty
        # list as there is no point to pass any values along the SNMP GET
        # request)
        manager.send_request (encoded_objids, encoded_values)

        # Expect a reply from SNMP agent later
        return None

class telnet_server (asyncore.dispatcher):
    """Telnet server class. Listens for incoming requests and creates
       instances of telnet engine classes for handling new session.
    """
    def __init__ (self, port=8989):
        """Takes optional TCP port number for the server to bind to.
        """
        # Call parent class constructor explicitly
        asyncore.dispatcher.__init__ (self)
        
        # Create socket of requested type
        self.create_socket (socket.AF_INET, socket.SOCK_STREAM)

        # Set it to re-use address
        self.set_reuse_addr ()
        
        # Bind to all interfaces of this host at specified port
        self.bind (('', port))
        
        # Start listening for incoming requests
        self.listen (5)

    def handle_accept (self):
        """Called by asyncore engine when new connection arrives
        """
        # Accept new connection
        (sock, addr) = self.accept ()

        # Create an instance of Telnet engine class to handle this new user
        # session and pass it socket object to use any further
        telnet_engine (sock)

# Run the module if it's invoked for execution
if __name__ == '__main__':
    # Create an instance of Telnet server
    server = telnet_server ()

    # Start the select() I/O multiplexing loop
    asyncore.loop()

Need help? Try PySNMP mailing lists.