Debugging the reason why your router cannot be found
Version 1 (Alan McGovern, 11/09/2009 12:59 AM)
1 | 1 | h1. Debugging the reason why your router cannot be found |
|
---|---|---|---|
2 | 1 | ||
3 | 1 | The uPnP specification is (generally speaking) badly implemented by a lot of router vendors. Some routers do case sensitive matching on the soap messages. Some routers advertise the incorrect service. Some routers don't support the full range of port forwarding features, and there's no way to query this. |
|
4 | 1 | ||
5 | 1 | To help debug these various incompatibilities, Mono.Nat can be made log a lot of useful information from each step in the router discovery process. |
|
6 | 1 | ||
7 | 1 | ||
8 | 1 | h2. Step 1: Detecting available services |
|
9 | 1 | ||
10 | 1 | In order to detect what services are available on the local network, a udp broadcast message is sent. There are two kinds of message: |
|
11 | 1 | # The 'tell me everything you support' message |
|
12 | 1 | # The 'respond if you support service X' message |
|
13 | 1 | ||
14 | 1 | Mono.Nat uses the 'tell me everything you support' style message. I haven't come across a router which has failed to respond to this, though there are some which fail to respond to the second type of message. If your router fails at this step, then this is probably why. Typical output from this step is a dozen or so copies of the following: |
|
15 | 1 | ||
16 | 1 | <pre> |
|
17 | 1 | UPnP Response: HTTP/1.1 200 OK |
|
18 | 1 | SERVER: Ambit OS/1.0 UPnP/1.0 AMBIT-UPNP/1.0 |
|
19 | 1 | EXT: |
|
20 | 1 | LOCATION: http://192.168.0.10:80/Public_UPNP_gatedesc.xml |
|
21 | 1 | CACHE-CONTROL: max-age=3600 |
|
22 | 1 | ST: upnp:rootdevice |
|
23 | 1 | USN: uuid:e346a71d-99ef-86a6-3222-e9ba2bb3dfa0::upnp:rootdevice |
|
24 | 1 | ||
25 | 1 | ||
26 | 1 | UPnP Response: HTTP/1.1 200 OK |
|
27 | 1 | SERVER: Ambit OS/1.0 UPnP/1.0 AMBIT-UPNP/1.0 |
|
28 | 1 | EXT: |
|
29 | 1 | LOCATION: http://192.168.0.10:80/Public_UPNP_gatedesc.xml |
|
30 | 1 | CACHE-CONTROL: max-age=3600 |
|
31 | 1 | ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1 |
|
32 | 1 | USN: uuid:e346a71d-99ef-86a6-3222-e9ba2bb3dfa0::urn:schemas-upnp-org:device:InternetGatewayDevice:1 |
|
33 | 1 | </pre> |
|
34 | 1 | ||
35 | 1 | h2. Step 2: Getting the service listing |
|
36 | 1 | ||
37 | 1 | If your router advertises one of the three services that Mono.Nat assumes will allow port forwarding, you will see output similar to this: |
|
38 | 1 | ||
39 | 1 | <pre> |
|
40 | 1 | UPnP Response: Router advertised a 'urn:schemas-upnp-org:service:WANIPConnection:' service |
|
41 | 1 | Found device at: http://192.168.0.10:80/Public_UPNP_gatedesc.xml |
|
42 | 1 | Parsed device as: 192.168.0.10:80 |
|
43 | 1 | Fetching service list: 192.168.0.10:80 |
|
44 | 1 | </pre> |
|
45 | 1 | ||
46 | 1 | h3. Step 3: Parsing a service listing |
|
47 | 1 | ||
48 | 1 | The service listing contains the details required to connect to the upnp service on the router. If the listing can be retrieved and parsed, you'll see output similar to this: |
|
49 | 1 | ||
50 | 1 | <pre> |
|
51 | 1 | 192.168.0.10:80: Parsed services list |
|
52 | 1 | 192.168.0.10:80: Found service: urn:schemas-upnp-org:service:Layer3Forwarding:1 |
|
53 | 1 | 192.168.0.10:80: Found service: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 |
|
54 | 1 | 192.168.0.10:80: Found service: urn:schemas-upnp-org:service:WANIPConnection:1 |
|
55 | 1 | 192.168.0.10:80: Found upnp service at: /Public_UPNP_C3 |
|
56 | 1 | 192.168.0.10:80: Assuming control Uri is relative: /Public_UPNP_C3 |
|
57 | 1 | 192.168.0.10:80: Handshake Complete |
|
58 | 1 | </pre> |
|
59 | 1 | ||
60 | 1 | h4: Step 4: Using the device |
|
61 | 1 | ||
62 | 1 | Once the control Uri has been discovered, the DeviceFound event will be raised and you will be passed the INatDevice to use. From here you just need to make calls to the various methods like INatDevice.MapPort or INatDevice.GetExternalIP. It's worth noting that some devices will accept port maps which have a different internal IP address and external IP address, for example mapping external port 10000 to internal port 5000, while others will throw an exception. A few devices will silently ignore the internal port value and just map the external port 5000 to the internal port 5000. |
|
63 | 1 | ||
64 | 1 | h5. Submitting patches so your router works without modifications |
|
65 | 1 | ||
66 | 1 | If your router requires a fix to be detected with Mono.Nat, please let me know and supply a patch with the required changes. I'll gladly incorporate any changes which increase compatibility with different router models. |