UPnP - Universal Plug and Play

I played with UPnP lately, and think it may be worth to share the experiences.

The wikipedia entry is pretty general, and does not cover the large scale of problems, apart from missing authentication and a lack of standard for the HTTPMU protocoll.

I'll focus on a specific use of UPnP, a hardware router from linksys (WRT54GS) with UPnP enabled, this is a 'servicepoint', and a controllpoint, a nepenthes module which will add portforwarding rules on the gateway using upnp.

So what happens on the wire, the servicepoint has the address 192.168.1.1, the controlpoint 192.168.3.1 (I refomatted the messages)

turning on the UPnP servicepoint

The servicepoint sends a a bunch of udp multicasts to its subnet.

UDP 192.168.1.1:1900 → 239.255.255.0:1900

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=180
Location: http:/ /192.168.1.1:5431/dyndev/uuid:00 13-1007-eefc0000eddc
NT: urn:schemas-upnp-org:service:WANPPPConnection:
NTS: ssdp:alive
SERVER: LINUX/2.4 UPnP/1.0 BRCM400/1.0
USN: uuid:0013-1007-eefc0200eddc::urn:schemas-upnp-org:service:WANPPPConnection:1

This kind of message is called HTTPMU and is not standarized, the ietf draft expired in 2001.

turning on the UPnP control point

The control point searches for service points which offer the service he can control.

UDP 192.168.1.3:38246 → 239.255.255.0:1900

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp: discover"
MX: 5
ST: urn:schema s-upnp-org:device:InternetGatewayDevice:1

the servicepoint answers

The servicepoint answers, and offers a URL where the control point can download a service description.

UDP 192.168.1.1:1900 → 192.168.1.3:38246

HTTP/1.1 200  OK
ST: urn:sche mas-upnp-org:device:InternetGatewayDevice:1
USN :uuid:0013-1007-eefc0000eddc::urn:schemas-upnp-org:device:Intern etGatewayDevice:1
Location: http://192.168.1.1:5431/dyndev/uuid:0013-1007-eefc0000eddc
Server:  Custom/1.0 UPnP /1.0 Proc/Ver
EXT:
Cache-Control:max-age=180
DATE: Sun, 02 Ju l 2006 04:55:30  GMT

the control point downloads the service description

the servicepoints service description contains the required informations which subservices the service offers, as well as which url to use to controll them.

Please note the http protocol, as well as the xml format

GET /dyndev/uuid:0013-1007-eefc0000eddc HTTP/1.1
HOST: 192.168.1.1:5431
DATE: Sun, 02 Jul 2006 11:56:29 GMT
CONNECTION: close
USER-AGENT: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.0
 
 
HTTP/1.0 200 OK
SERVER: LINUX/2.4 UPnP/1.0 BRCM400/1.0
DATE: Sun, 02 Jul 2006 04:55:30 GMT
CONTENT-TYPE: application/octet-stream
Cache-Control: max-age=1
PRAGMA: no-cache
Connection: Close
 
<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>
    <device>
        <deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>
        <friendlyName>Residential Gateway Device</friendlyName>
        <manufacturer>Linksys Inc.</manufacturer>
        <manufacturerURL>http://www.linksys.com/</manufacturerURL>
        <modelDescription>Internet Access Server</modelDescription>
        <modelName>WRT54GS</modelName>
        <modelNumber>v4.71.0</modelNumber>
        <modelURL>http://www.linksys.com/</modelURL>
        <UDN>uuid:0013-1007-eefc0000eddc</UDN>
        <serviceList>
            <service>
                <serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
                <serviceId>urn:upnp-org:serviceId:Layer3Forwarding:11</serviceId>
                <controlURL>/uuid:0013-1007-eefc0000eddc/Layer3Forwarding:1</controlURL>
                <eventSubURL>/uuid:0013-1007-eefc0000eddc/Layer3Forwarding:1</eventSubURL>
                <SCPDURL>/dynsvc/Layer3Forwarding:1.xml</SCPDURL>
            </service>
        </serviceList>
        <deviceList>
            <device>
                <deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType>
                <friendlyName>urn:schemas-upnp-org:device:WANDevice:1</friendlyName>
                <manufacturer>Linksys Inc.</manufacturer>
                <manufacturerURL>http://www.linksys.com/</manufacturerURL>
                <modelDescription>Internet Access Server</modelDescription>
                <modelName>WRT54GS</modelName>
                <modelNumber>v4.71.0</modelNumber>
                <modelURL>http://www.linksys.com/</modelURL>
                <UDN>uuid:0013-1007-eefc0100eddc</UDN>
                <serviceList>
                    <service>
                        <serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType>
                        <serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId>
                        <controlURL>/uuid:0013-1007-eefc0100eddc/WANCommonInterfaceConfig:1</controlURL>
                        <eventSubURL>/uuid:0013-1007-eefc0100eddc/WANCommonInterfaceConfig:1</eventSubURL>
                        <SCPDURL>/dynsvc/WANCommonInterfaceConfig:1.xml</SCPDURL>
                    </service>
                </serviceList>
                <deviceList>
                    <device>
                        <deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType>
                        <friendlyName>urn:schemas-upnp-org:device:WANConnectionDevice:1</friendlyName>
                        <manufacturer>Linksys Inc.</manufacturer>
                        <manufacturerURL>http://www.linksys.com/</manufacturerURL>
                        <modelDescription>Internet Access Server</modelDescription>
                        <modelName>WRT54GS</modelName>
                        <modelNumber>v4.71.0</modelNumber>
                        <modelURL>http://www.linksys.com/</modelURL>
                        <UDN>uuid:0013-1007-eefc0200eddc</UDN>
                        <serviceList>
                            <service>
                                <serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>
                                <serviceId>urn:upnp-org:serviceId:WANIPConn1</serviceId>
                                <controlURL>/uuid:0013-1007-eefc0200eddc/WANIPConnection:1</controlURL>
                                <eventSubURL>/uuid:0013-1007-eefc0200eddc/WANIPConnection:1</eventSubURL>
                                <SCPDURL>/dynsvc/WANIPConnection:1.xml</SCPDURL>
                            </service>
                            <service>
                                <serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType>
                                <serviceId>urn:upnp-org:serviceId:WANPPPConn1</serviceId>
                                <controlURL>/uuid:0013-1007-eefc0200eddc/WANPPPConnection:1</controlURL>
                                <eventSubURL>/uuid:0013-1007-eefc0200eddc/WANPPPConnection:1</eventSubURL>
                                <SCPDURL>/dynsvc/WANPPPConnection:1.xml</SCPDURL>
                            </service>
                        </serviceList>
                    </device>
                </deviceList>
            </device>
        </deviceList>
    </device>
</root>

the controlpoint subscribes to subservices

TCP 192.168.3.1: → 192.168.1.1:5431

When subscribing to a subservice, the controll point has to provide a callback url, where the service point can post http messages in the G Event Notification Architecture (which is based upon xml).

Please note that this means, your controlpoint runs a http server too, which allows the servicepoint to send you GENA messages

SUBSCRIBE /uuid:0013-1007-eefc0100eddc/WANCommonInterfaceConfig:1 HTTP/1.1
HOST: 192.168.1.1:5431
CALLBACK: <http://192.168.1.3:49152/>
NT: upnp:event
TIMEOUT: Second-1801




HTTP/1.1 200 OK
Server: LINUX/2.4 UPnP/1.0 BRCM400/1.0
SID: uuid:0013-1007-eefc03f0a4b3
TIMEOUT: Second-1801
SUBSCRIBE /uuid:0013-1007-eefc0000eddc/Layer3Forwarding:1 HTTP/1.1
HOST: 192.168.1.1:5431
CALLBACK: <http://192.168.1.3:49152/>
NT: upnp:event
TIMEOUT: Second-1801



HTTP/1.1 200 OK
Server: LINUX/2.4 UPnP/1.0 BRCM400/1.0
SID: uuid:0013-1007-eefc04f09cab
TIMEOUT: Second-1801
SUBSCRIBE /uuid:0013-1007-eefc0200eddc/WANIPConnection:1 HTTP/1.1
HOST: 192.168.1.1:5431
CALLBACK: <http://192.168.1.3:49152/>
NT: upnp:event
TIMEOUT: Second-0



HTTP/1.1 200 OK
Server: LINUX/2.4 UPnP/1.0 BRCM400/1.0
SID: uuid:0013-1007-eefc05f09ba7
TIMEOUT: Second-0
SUBSCRIBE /uuid:0013-1007-eefc0200eddc/WANPPPConnection:1 HTTP/1.1
HOST: 192.168.1.1:5431
CALLBACK: <http://192.168.1.3:49152/>
NT: upnp:event
TIMEOUT: Second-0



HTTP/1.1 200 OK
Server: LINUX/2.4 UPnP/1.0 BRCM400/1.0
SID: uuid:0013-1007-eefc06f09ca8
TIMEOUT: Second-0

the servicepoint sends us notifications using gena

Please make sure to notice the service point POSTS these messages to a webserver on our controll point.

Please note this is SOAP formatted

TCP 192.168.1.1:any → 192.168.1.3:49152

NOTIFY / HTTP/1.1
HOST: 192.168.1.3:49152
CONTENT-TYPE: text/xml
CONTENT-LENGTH: 153
NT: upnp:event
NTS: upnp:propchange
SID: uuid:0013-1007-eefc04f09cab
SEQ: 0
 
 
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <DefaultConnectionService></DefaultConnectionService>
    </e:property>
</e:propertyset>
 
 
HTTP/1.1 200 OK
SERVER: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.0
CONNECTION: close
CONTENT-LENGTH: 41
CONTENT-TYPE: text/html
 
 
<html>
    <body>
        <h1>200 OK</h1>
    </body>
</html>
NOTIFY / HTTP/1.1
HOST: 192.168.1.3:49152
CONTENT-TYPE: text/xml
CONTENT-LENGTH: 211
NT: upnp:event
NTS: upnp:propchange
SID: uuid:0013-1007-eefc03f0a4b3
SEQ: 0
 
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <PhysicalLinkStatus>Up</PhysicalLinkStatus>
    </e:property>
    <e:property>
        <EnabledForInternet>1</EnabledForInternet>
    </e:property>
</e:propertyset>
 
 
HTTP/1.1 200 OK
SERVER: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.0
CONNECTION: close
CONTENT-LENGTH: 41
CONTENT-TYPE: text/html
 
<html>
    <body>
        <h1>200 OK</h1>
    </body>
</html>
NOTIFY / HTTP/1.1
HOST: 192.168.1.3:49152
CONTENT-TYPE: text/xml
CONTENT-LENGTH: 420
NT: upnp:event
NTS: upnp:propchange
SID: uuid:0013-1007-eefc08f09baa
SEQ: 0
 
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <PossibleConnectionTypes>Unconfigured,IP_Routed,IP_Bridged</PossibleConnectionTypes>
    </e:property>
    <e:property>
        <ConnectionStatus>Connected</ConnectionStatus>
    </e:property>
    <e:property>
        <ExternalIPAddress>192.168.53.223</ExternalIPAddress>
    </e:property>
    <e:property>
        <PortMappingNumberOfEntries>18</PortMappingNumberOfEntries>
    </e:property>
</e:propertyset>
HTTP/1.1 200 OK
SERVER: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.0
CONNECTION: close
CONTENT-LENGTH: 41
CONTENT-TYPE: text/html
 
<html>
    <body>
        <h1>200 OK</h1>
    </body>
</html>
NOTIFY / HTTP/1.1
HOST: 192.168.1.3:49152
CONTENT-TYPE: text/xml
CONTENT-LENGTH: 420
NT: upnp:event
NTS: upnp:propchange
SID: uuid:0013-1007-eefc05f09ba7
SEQ: 0
 
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <PossibleConnectionTypes>Unconfigured,IP_Routed,IP_Bridged</PossibleConnectionTypes>
    </e:property>
    <e:property>
        <ConnectionStatus>Connected</ConnectionStatus>
    </e:property>
    <e:property>
        <ExternalIPAddress>192.168.53.223</ExternalIPAddress>
    </e:property>
    <e:property>
        <PortMappingNumberOfEntries>18</PortMappingNumberOfEntries>
    </e:property>
</e:propertyset>
HTTP/1.1 412 Precondition Failed
SERVER: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.0
CONNECTION: close
CONTENT-LENGTH: 58
CONTENT-TYPE: text/html
 
<html>
    <body>
        <h1>412 Precondition Failed</h1>
    </body>
</html>
NOTIFY / HTTP/1.1
HOST: 192.168.1.3:49152
CONTENT-TYPE: text/xml
CONTENT-LENGTH: 470
NT: upnp:event
NTS: upnp:propchange
SID: uuid:0013-1007-eefc07f09cab
SEQ: 0
 
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <PossibleConnectionTypes>Unconfigured,IP_Routed,DHCP_Spoofed,PPPOE_Bridged,PPTP_Relay,L2TP_Relay,PPOE_Relay</PossibleConnectionTypes>
    </e:property>
    <e:property>
        <ConnectionStatus>Unconfigured</ConnectionStatus>
    </e:property>
    <e:property>
        <ExternalIPAddress>192.168.53.223</ExternalIPAddress>
    </e:property>
    <e:property>
        <PortMappingNumberOfEntries></PortMappingNumberOfEntries>
    </e:property>
</e:propertyset>
 
HTTP/1.1 200 OK
SERVER: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.0
CONNECTION: close
CONTENT-LENGTH: 41
CONTENT-TYPE: text/html
 
<html>
    <body>
        <h1>200 OK</h1>
    </body>
</html>

the control point adds a portmapping

Now, finally we can add a portmapping …

POST /uuid:0013-1007-eefc0200eddc/WANIPConnection:1 HTTP/1.1
HOST: 192.168.1.1:5431
CONTENT-LENGTH: 590
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
USER-AGENT: Linux/2.6.14.4, UPnP/1.0, Portable SDK for UPnP devices/1.4.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>443</NewExternalPort>
            <NewProtocol>tcp</NewProtocol>
            <NewInternalPort>443</NewInternalPort>
            <NewInternalClient>192.168.1.3</NewInternalClient>
            <NewEnabled>1</NewEnabled>
            <NewPortMappingDescription>Nepenthes PFW (tcp) 443</NewPortMappingDescription>
            <NewLeaseDuration>0</NewLeaseDuration>
        </u:AddPortMapping>
    </s:Body>
</s:Envelope>
 
HTTP/1.1 200 OK
DATE: Sun, 02 Jul 2006 04:55:44 GMT
Connection: Keep-Alive
Server: LINUX/2.4 UPnP/1.0 BRCM400/1.0
Content-Length: 289
Content-Type: text/xml; charset="utf-8"
EXT:
 
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <m:AddPortMappingResponse xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1"></m:AddPortMappingResponse>
    </s:Body>
</s:Envelope>

What did we learn about UPnP

I hope this little excerpt was able to show: UPnP relies on

  • xml
  • SOAP
  • http
    • clientside protocol
    • as well as serverside protocol

for service and control points.

as well as UPnP

  • does not offer any kind of authorization who changes the portforwardings on your router (but we knew that before)

From my own experience implementing the clientside http protocol is non trivial, I never tried doing it serverside. XML and SOAP, the majors when talking about enterprise software, define bloat in most usecases.

The library I used to write the controlpoint, libupnp (written by intel years ago and unmaintained), comes with:

  • an own threading wrapper
  • own xml parser
  • own http client implementation
  • own webserver implementation

And as you may expect it, it did not work, I had to tweak it for very trivial things, the content type the servicepoint replied for its content was “application/octet-stream” where the lib would only accept “text/xml”.

The library tries to hides every dirty detail about its internal threading to run the webserver and get/post content from/to the servicepoint 'asynchronous', one has to provide threading safe callbacks, and lock mutexes for shared informations.
Inadequate complexity for the actual use.

What you could not see, after adding 18 rules via upnp, I used Windows XP networking *whatever* to list the enabled UPnP forwardings, it took like 2 minutes to download all forwardings rules as the router was pretty loaded with requests.
Bad performance.

For now, even if its working, we won't include the nepenthes module which would allow creating port forwards on upnp enabled devides, as the upnp library needs to be patched, and UPnP is nothing we want to support.

Some links about UPnP:

Comments



2006/07/03/upnp.txt · Last modified: 2010/06/15 13:19 by common
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0