UPnP for asyncio
Find a file
Jack Robison beaa7bc3cb
fix scpd breaking if content-length is not provided
-applies to at least actiontec
-add actiontec and dd-wrt discover + get_external_ip replay tests
2020-11-01 15:26:50 -05:00
.github/workflows update python-package.yml 2020-10-30 15:22:38 -04:00
aioupnp fix scpd breaking if content-length is not provided 2020-11-01 15:26:50 -05:00
stubs mypy 2019-05-22 01:56:16 -04:00
tests fix scpd breaking if content-length is not provided 2020-11-01 15:26:50 -05:00
.coveragerc stubs 2019-05-22 00:45:33 -04:00
.gitignore mypy refactor 2019-05-21 18:16:30 -04:00
.pylintrc pylint, more mypy refactoring, improve tests 2019-05-22 00:29:23 -04:00
CHANGELOG.md refactoring, add protocol tests 2018-10-24 19:16:17 -04:00
generate_bug_report.py update generate_bug_report 2020-10-29 17:17:31 -04:00
LICENSE Update LICENSE 2020-02-03 04:39:59 +07:00
mypy.ini refactoring, add protocol tests 2018-10-24 19:16:17 -04:00
README.md Update README.md 2020-10-30 15:27:37 -04:00
setup.py remove mock testing requirement 2020-01-15 16:25:31 -05:00
wine_build.sh pyinstaller 2018-10-18 12:31:36 -04:00

[Build Status codecov PyPI version Python 3.6 Python 3.7 Python 3.8

UPnP for asyncio

aioupnp is a python 3.6-8 library and command line tool to interact with UPnP gateways using asyncio. aioupnp requires the netifaces and defusedxml modules.

Supported devices

img

Installation

Verify python is version 3.6-8

python --version

Installation for normal usage

pip install aioupnp

Installation for development

git clone https://github.com/lbryio/aioupnp.git
cd aioupnp
pip install -e .

Usage

aioupnp [-h] [--debug_logging] [--interface=<interface>] [--gateway_address=<gateway_address>]
        [--lan_address=<lan_address>] [--timeout=<timeout>]
        [(--<case sensitive m-search header>=<value>)...]
        command [--<arg name>=<arg>]...

Commands

  • help
  • get_external_ip
  • m_search
  • add_port_mapping
  • get_port_mapping_by_index
  • get_redirects
  • get_specific_port_mapping
  • delete_port_mapping
  • get_next_mapping
  • gather_debug_info

To get the documentation for a command

aioupnp help get_external_ip

To get the external ip address

aioupnp get_external_ip

To list the active port mappings on the gateway

aioupnp get_redirects

To set up a TCP port mapping

aioupnp add_port_mapping --external_port=1234 --internal_port=1234 --lan_address=<lan_addr> --description=test --protocol=TCP

To delete a TCP port mapping

aioupnp delete_port_mapping --external_port=1234 --protocol=TCP

M-Search headers

UPnP uses a multicast protocol (SSDP) to locate the gateway. Gateway discovery is automatic by default, but you may provide specific headers for the search to use to override automatic discovery.

If m-search headers are provided as keyword arguments then all of the headers to be used must be provided, in the order they are to be used. For example:

aioupnp --HOST=239.255.255.250:1900 --MAN=\"ssdp:discover\" --MX=1 --ST=upnp:rootdevice m_search

Using non-default network interfaces

By default, the network device will be automatically discovered. The interface may instead be specified with the --interface, provided before the command to be run. The gateway used on the interface network may be specified with the --gateway_address argument.

aioupnp --interface=wlp4s0 --gateway_address=192.168.1.6 m_search

Example usage from python

from aioupnp.upnp import UPnP

async def main():
    upnp = await UPnP.discover()
    print(await upnp.get_external_ip())
    print(await upnp.get_redirects())

    print("adding a port mapping")
    await upnp.add_port_mapping(1234, 'TCP', 1234, upnp.lan_address, 'test mapping')
    print(await upnp.get_redirects())

    print("deleting the port mapping")
    await upnp.delete_port_mapping(1234, 'TCP')
    print(await upnp.get_redirects())


asyncio.run(main())

Troubleshooting

Debug logging

To enable verbose debug logging, add the --debug_logging argument before the command being run

aioupnp --debug_logging m_search

Is it turned on?

Check that UPnP is turned on in the web gui for your router.

It really doesn't work

If it always fails with an m-search error, or the UPnP device is found but making a port mapping or getting the external address fails, a bug report can be generated and automatically sent using the generate_bug_report.py script. This script will run a packet capture while attempting to find the device and add/remove a mapping using miniupnpc and aioupnp. Once complete, it will submit a bug report of the packets sent/recieved by aioupnp/miniupnpc.

To run the bug report script, first pip install certifi aiohttp miniupnpc. You'll also need aioupnp installed. Then generate and send the bug report with sudo /full/path/to/your/python generate_bug_report.py.

License

This project is MIT licensed. For the full license, see LICENSE.

Contact

The primary contact for this project is @jackrobison