2018-07-30 23:48:20 +02:00
|
|
|
import argparse
|
|
|
|
import logging
|
|
|
|
from twisted.internet import reactor, defer
|
|
|
|
from txupnp.upnp import UPnP
|
2018-08-02 15:38:00 +02:00
|
|
|
from txupnp.fault import UPnPError
|
2018-07-30 23:48:20 +02:00
|
|
|
|
|
|
|
log = logging.getLogger("txupnp")
|
|
|
|
|
|
|
|
|
2018-08-01 22:29:00 +02:00
|
|
|
def debug_device(u, include_gateway_xml=False, *_):
|
|
|
|
print(u.get_debug_info(include_gateway_xml=include_gateway_xml))
|
|
|
|
return defer.succeed(None)
|
|
|
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
def get_external_ip(u, *_):
|
|
|
|
ip = yield u.get_external_ip()
|
|
|
|
print(ip)
|
|
|
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
def list_mappings(u, *_):
|
|
|
|
redirects = yield u.get_redirects()
|
2018-08-01 23:57:27 +02:00
|
|
|
ext_ip = yield u.get_external_ip()
|
|
|
|
for (ext_host, ext_port, proto, int_port, int_host, enabled, desc, lease) in redirects:
|
|
|
|
print("{}:{}/{} --> {}:{} ({}) (expires: {}) - {} ".format(
|
|
|
|
ext_host or ext_ip, ext_port, proto, int_host, int_port, "enabled" if enabled else "disabled",
|
|
|
|
"never" if not lease else lease, desc)
|
|
|
|
)
|
2018-08-01 22:29:00 +02:00
|
|
|
|
|
|
|
|
2018-08-02 15:38:00 +02:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
def add_mapping(u, *_):
|
|
|
|
port = 4567
|
|
|
|
protocol = "UDP"
|
|
|
|
description = "txupnp test mapping"
|
|
|
|
yield u.get_next_mapping(port, protocol, description)
|
|
|
|
result = yield u.get_specific_port_mapping(port, protocol)
|
|
|
|
if result:
|
|
|
|
print("added mapping")
|
|
|
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
|
|
|
def delete_mapping(u, *_):
|
|
|
|
port = 4567
|
|
|
|
protocol = "UDP"
|
|
|
|
yield u.delete_port_mapping(port, protocol)
|
|
|
|
mapping = yield u.get_specific_port_mapping(port, protocol)
|
|
|
|
if mapping:
|
|
|
|
print("failed to remove mapping")
|
|
|
|
else:
|
|
|
|
print("removed mapping")
|
|
|
|
|
|
|
|
|
2018-08-01 22:29:00 +02:00
|
|
|
cli_commands = {
|
|
|
|
"debug_device": debug_device,
|
|
|
|
"get_external_ip": get_external_ip,
|
2018-08-02 15:38:00 +02:00
|
|
|
"list_mappings": list_mappings,
|
|
|
|
"add_mapping": add_mapping,
|
|
|
|
"delete_mapping": delete_mapping
|
2018-08-01 22:29:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-30 23:48:20 +02:00
|
|
|
@defer.inlineCallbacks
|
2018-08-01 22:29:00 +02:00
|
|
|
def run_command(found, u, command, debug_xml):
|
2018-07-30 23:48:20 +02:00
|
|
|
if not found:
|
|
|
|
print("failed to find gateway")
|
|
|
|
reactor.callLater(0, reactor.stop)
|
|
|
|
return
|
2018-08-01 22:29:00 +02:00
|
|
|
if command not in cli_commands:
|
|
|
|
print("unrecognized command: valid commands: %s" % list(cli_commands.keys()))
|
|
|
|
else:
|
|
|
|
yield cli_commands[command](u, debug_xml)
|
2018-07-30 23:48:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser(description="upnp command line utility")
|
2018-08-02 15:38:00 +02:00
|
|
|
parser.add_argument(dest="command", type=str, help="debug_gateway | list_mappings | get_external_ip | add_mapping | delete_mapping")
|
2018-07-31 17:35:24 +02:00
|
|
|
parser.add_argument("--debug_logging", dest="debug_logging", default=False, action="store_true")
|
2018-08-01 22:29:00 +02:00
|
|
|
parser.add_argument("--include_igd_xml", dest="include_igd_xml", default=False, action="store_true")
|
2018-07-30 23:48:20 +02:00
|
|
|
args = parser.parse_args()
|
2018-07-31 17:35:24 +02:00
|
|
|
if args.debug_logging:
|
2018-07-30 23:48:20 +02:00
|
|
|
from twisted.python import log as tx_log
|
|
|
|
observer = tx_log.PythonLoggingObserver(loggerName="txupnp")
|
|
|
|
observer.start()
|
|
|
|
log.setLevel(logging.DEBUG)
|
|
|
|
command = args.command
|
|
|
|
|
2018-07-31 22:53:08 +02:00
|
|
|
def show(err):
|
|
|
|
print("error: {}".format(err))
|
|
|
|
|
2018-07-30 23:48:20 +02:00
|
|
|
u = UPnP(reactor)
|
|
|
|
d = u.discover()
|
2018-08-01 22:29:00 +02:00
|
|
|
d.addCallback(run_command, u, command, args.include_igd_xml)
|
2018-07-31 22:53:08 +02:00
|
|
|
d.addErrback(show)
|
2018-07-30 23:48:20 +02:00
|
|
|
d.addBoth(lambda _: reactor.callLater(0, reactor.stop))
|
|
|
|
reactor.run()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|