copying Cisco configs using snmp

Cisco has a set of OID that can be used to copy things to and from a router using SNMP.  You can set a source or destination to be ‘network’ which means snmp or other protocols.  You can then push or pull files using SNMP.  This example can push commands to the running-config, pull a running config, push a starting-config, pull a stating-config, push a file, or pull a file.  This example uses the pysnmp library.

#!/usr/bin/python
import sys
import argparse
import random
from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.proto import rfc1902

class routerTransfer(object):
    def __init__(self, filename, source, router, server, communityString, push):
        self._filename = filename
        self._router = router
        self._server = server
        self._communityString = communityString
        self._push = push
        if isinstance(source, int):
            self._source = source
        elif isinstance(source, str):
            if source == 'starting-config':
                self._source = 3
            elif source == 'running-config':
                self._source = 4
            elif source == 'IOS-file':
                self._source = 2

    def sendCommands(self):
        # send snmp commands
        if self._push is True:
            source = 1
            destination = self._source
        else:
            source = self._source
            destination = 1
        cmdGen = cmdgen.CommandGenerator()
        index = random.randint(100,10000)
        routerAuth = cmdgen.CommunityData('agent', self._communityString,1)
        routerHost = cmdgen.UdpTransportTarget((self._router,161))
        ErrorIndication, ErrorStatus, ErrorIndex, VarBindTable = cmdGen.setCmd(routerAuth, routerHost, ('1.3.6.1.4.1.9.9.96.1.1.1.1.2.' + str(index), rfc1902.Integer(1)))
        ErrorIndication, ErrorStatus, ErrorIndex, VarBindTable = cmdGen.setCmd(routerAuth, routerHost, ('1.3.6.1.4.1.9.9.96.1.1.1.1.3.' + str(index), rfc1902.Integer(source)))
        ErrorIndication, ErrorStatus, ErrorIndex, VarBindTable = cmdGen.setCmd(routerAuth, routerHost, ('1.3.6.1.4.1.9.9.96.1.1.1.1.4.' + str(index), rfc1902.Integer(destination)))
        ErrorIndication, ErrorStatus, ErrorIndex, VarBindTable = cmdGen.setCmd(routerAuth, routerHost, ('1.3.6.1.4.1.9.9.96.1.1.1.1.5.' + str(index), rfc1902.IpAddress(self._server)))
        ErrorIndication, ErrorStatus, ErrorIndex, VarBindTable = cmdGen.setCmd(routerAuth, routerHost, ('1.3.6.1.4.1.9.9.96.1.1.1.1.6.' + str(index), rfc1902.OctetString(self._filename)))
        ErrorIndication, ErrorStatus, ErrorIndex, VarBindTable = cmdGen.setCmd(routerAuth, routerHost, ('1.3.6.1.4.1.9.9.96.1.1.1.1.14.' + str(index), rfc1902.Integer(1)))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("file", help="Remote Filename")
    parser.add_argument("source", help="The Router Source (of Destination if a push): Starting config, Running config, or File", choices=['starting-config', 'running-config', 'IOS-file'])
    parser.add_argument("router", help="router ip address")
    parser.add_argument("server", help="server ip address")
    parser.add_argument("-p", "--push", help="push to router rather then pull", action='store_true')
    parser.add_argument("-c", "--community", help="SNMP RW String", type=str, default='private')
    args = parser.parse_args()

    temp = routerTransfer(args.file, args.source, args.router, args.server, args.community, args.push)
    temp.sendCommands()

if __name__ == "__main__":
    main()

#  networkFile(1), -- file on another network device, e.g. a file-server on the net
#  iosFile(2),     -- a file on the local agent, other than startup or running config
#  startupConfig(3),
#  runningConfig(4),
#  terminal(5)

Leave a Reply

Your email address will not be published.