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)
