Sunday 13 January 2013

UPnP - auto port forwarding in C++ for windows

How hard can it be?

I want my windows program to be able to automatically configure the router to forward a port.
I soon find some source code https://compilr.com/tntblow/asdas/upnpnat.cpp
..yes it works!
I eventually need to use this in my program so I incorporate the source into my project, use it, but it doesn't work. "discovery error is Fail to find an UPNP NAT.". Odd.
I last tested the source ages ago while on XP, and now on Win7. I wonder.. I run the program on and old xp laptop and success, UPNP NAT is found, although further errors occur.

Time for another solution..
A-ha, windows includes some UPnP support!
http://msdn.microsoft.com/en-gb/library/windows/desktop/aa382290(v=vs.85).aspx
Erm.. only seems to search for the UPnP device, and it's not clear how to actually configure the thing. Hmm, shelve that..

The search continues. "class PortForward"
http://social.msdn.microsoft.com/Forums/en-GB/netfxnetcom/thread/41701acc-22d5-42d1-87e1-7f4dd5f1b666
Looking promising.. but lots of compile errors to sort out.. hmm

ooh something else, maybe even simpler!
http://forum.emule-project.net/index.php?showtopic=34100

How odd, spmc is always NULL after this..

get_StaticPortMappingCollection(&spmc);


Maybe this is an XP vs Win7 thing.
Well this doesnt look very promising..
http://support.microsoft.com/kb/928233

More searching..
MiniUPnp. Surely..
Oooh there are prebuild win32 exes.. Grab! Run!

C:\MiniUPnP>upnpc-static.exe -a 192.168.0.2 53200 43300 UDP
upnpc : miniupnpc library test client. (c) 2006-2012 Thomas Bernard
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
 desc: http://192.168.0.1:49153/gateway.xml
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1
Socket error: connect, 0
Found a (not connected?) IGD : http://192.168.0.1:49152/upnp/control/WANIPConnection
Trying to continue anyway
Local LAN ip address : 192.168.0.2
Socket error: connect, 0
ExternalIPAddress = (
Socket error: connect, 0
AddPortMapping(43300, 53200, 192.168.0.2) failed with code -3 (UnknownError)
Socket error: connect, 0
GetSpecificPortMappingEntry() failed with code -3 (UnknownError)
InternalIP:Port = ╦t^±╩t☺:_
external (:43300 UDP is redirected to internal ╦t^±╩t☺:_ (duration=╦t┴úð¯H■() 

Yikes. Not good.

I have UPnP enabled in my router, and it list entries there from other members of the LAN, so I would expect the problem lies in the code.

Back to "class PortForward" listed earlier..
Compiles.. run and get:
PortForward::Access Nat->get_StaticPortMappingCollection succeeded, but left Collection null

Same old story, bah!!!

Apps like shareaza must have a go at this, and the source is available!
Running shareaza, viewing log..



[23:45:14] Windows Firewall setup for UPnP succeeded.
[23:45:14] Trying to setup port mappings using NAT UPnP...
[23:45:19] Trying to setup port mappings using Control Point UPnP...
[23:45:19] Accepting incoming TCP connections on 0.0.0.0 port 0.
[23:45:19] Listening for UDP datagrams on 0.0.0.0 port 0.
[23:45:19] Found UPnP device: WANConnectionDevice (ChildLevel: 0, UID: uuid:ab5d9077-0710-4373-a4ea-5192c8781666)
[23:45:29] Traversing the service list of UPnP device failed.


Well that's looking like a non-starter.

Maybe my trusty old netgear DG834G router is only partially UPnP compatible?