sbstp / rust-igd

Internet Gateway Device (UPNP) client
https://docs.rs/igd/
MIT License
105 stars 41 forks source link

Wrong order of arguments in AddPortMapping #48

Closed FloGa closed 4 years ago

FloGa commented 4 years ago

I found your library a few days ago and I struggled to get your examples to work with my router, I always ended up with error code 402.

After comparing the library with miniupnp (which works with my router), I found out that the order of arguments that are sent to the router is different. With your library, the body looks like:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
            <NewProtocol>TCP</NewProtocol>
            <NewExternalPort>12345</NewExternalPort>
            <NewInternalClient>192.168.0.115</NewInternalClient>
            <NewInternalPort>12345</NewInternalPort>
            <NewLeaseDuration>60</NewLeaseDuration>
            <NewPortMappingDescription>crust</NewPortMappingDescription>
            <NewEnabled>1</NewEnabled>
            <NewRemoteHost></NewRemoteHost>
        </u:AddPortMapping>
    </s:Body>
</s:Envelope>

While miniupnp produces the following body:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
            <NewRemoteHost></NewRemoteHost>
            <NewExternalPort>12345</NewExternalPort>
            <NewProtocol>TCP</NewProtocol>
            <NewInternalPort>12345</NewInternalPort>
            <NewInternalClient>192.168.0.115</NewInternalClient>
            <NewEnabled>1</NewEnabled>
            <NewPortMappingDescription>libminiupnpc</NewPortMappingDescription>
            <NewLeaseDuration>60</NewLeaseDuration>
        </u:AddPortMapping>
    </s:Body>
</s:Envelope>

Note, that only the order of arguments is different. In fact, this is the only reason, why miniupnp works, while your library doesn't.

The routers that provide UPnP functionality also provide a schema document, describing the actions and arguments. According to the Spec (https://openconnectivity.org/upnp-specs/UPnP-arch-DeviceArchitecture-v2.0-20200417.pdf, page 79):

Every “in” argument in the definition of the action in the service description shall be included, in the same order as specified in the service description (SCPD) that is available from the device.

I am currently working on a method to parse this SCPD (XML) and generate the Action body exactly as requested. Would you be willing to include this as a Pull-Request once I am done? Or are you by chance already working on the same issue?

(EDIT: Fixed wrong page number and description)

sbstp commented 4 years ago

I am not working on fixing this, but I'll be happy to merge your pull request!