Controlling your DSL Router via UPnP
When I was looking for a commandline tool to create port mappings on my broadband/DSL router, I detected the miranda.py script on http://www.sourcesec.com/2008/11/07/miranda-upnp-administration-tool/. I needed some functionality not yet provided by the script, namely, the possibility of passing arguments to host send commands. Usually, the script asks nicely for all required arguments; this is hard to automate. Using the patch provided below, a command such ashost send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32 1 22 80.80.80.80 tcp 22is now possible. This also allows bash scripting:
cat <<EOF | miranda.py -s ~/.miranda/struct_data.mir host get 0 host send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32 1 22 80.80.80.80 tcp 22 EOFI also fixed a nondescript exception message when no host had yet been loaded/found. Have fun with it,
yours,
Sebastian
--- miranda.py.orig 2009-03-15 13:51:03.000000000 +0100 +++ miranda.py 2009-03-15 13:58:37.000000000 +0100 @@ -1065,11 +1065,15 @@ #Send SOAP requests index = False inArgCounter = 0 - - if argc != 6: + + #sbr: allow to pass arguments to the call + numReqArgs = 6 + if argc < numReqArgs: showHelp(argv[0]) return + # number of arguments in addition to the send cmd else: + extraArgs = argc-numReqArgs try: index = int(argv[2]) except: @@ -1078,7 +1082,12 @@ deviceName = argv[3] serviceName = argv[4] actionName = argv[5] - hostInfo = hp.ENUM_HOSTS[index] + try: + hostInfo = hp.ENUM_HOSTS[index] + except Exception, e: + print "You need to discover or load some hosts, first" + return + actionArgs = False sendArgs = {} retTags = [] @@ -1106,11 +1115,18 @@ print "Are you sure you've specified the correct action?" return False + extraArgsUsed = 0 for argName,argVals in actionArgs.iteritems(): actionStateVar = argVals['relatedStateVariable'] stateVar = hostInfo['deviceList'][deviceName]['services'][serviceName]['serviceStateVariables'][actionStateVar] if argVals['direction'].lower() == 'in': + if extraArgs-extraArgsUsed > 0: + arg = argv[numReqArgs+extraArgsUsed] + print "Using ", arg, " for ", argName + sendArgs[argName] = (arg,stateVar['dataType']) + extraArgsUsed += 1 + else: print "Required argument:" print "\tArgument Name: ",argName print "\tData Type: ",stateVar['dataType']
6 comments:
Got it to work, with a couple potholes along the way.
1. The patch was generated with --ignore-whitespace, which causes problems with an indentation-sensitive language like Python. I had to manually go through and fix the indentation to account for changes in nesting.
2. If the last command piped into Miranda is not "quit", Miranda will throw a fatal exception (unexpected end-of-file) when it runs out of piped input.
Other than that, the changes work great and have really helped me automate my UPnP setup. Thanks!
Post a Comment