How to register a global hotkey for your application in C#

How to register a global hotkey for your application in C#

Register a hotkey for your application that can be triggered even if your form is minimized and does not have focus. More »

How to download a file in C# (progressbar and download speed)

How to download a file in C# (progressbar and download speed)

Learn how to download files in C# while displaying the percentage and the download speed. More »

UDP hole punching implementation in C#

UDP hole punching implementation in C#

Learn how to implement UDP hole punching so you can make your clients life a lot easier by not forcing them to open ports on their end. More »

 

UPNP port forwarding – The easy way

From my experience I noticed that the NATUPnP library is pretty unstable when it comes down to UPNP (mostly refusing to work on some routers regarding if the router is UPNP enabled or not) I decided to make a simple walk-through to help people resolve these kind of issues and aid them in creating a program that manual port forwarding is not needed, at least for UPNP enabled routers.

So, let’s get started. First you need to download the Mono.Nat library which can be found here. When the download is complete extract the contents of the .zip file anywhere you like.

In order to be able to take advantage of the library we need to locate the file we have extracted and add it as a reference to our project then import it in your project using

Now it’s time for some coding.

We will need to add a few lines in our class constructor.

The following event will trigger the DeviceFound method (which we will be adding shortly) when a new device (router) is detected.

The following event will trigger the DeciceLost method (which again we will be adding shortly) when the device goes offline.

And finally .StartDiscovery will initiate the search for active devices.

Now it’s time to add the methods to the above events.

Now that we have our two main event methods we can control and manipulate the ports in the devices by adding specific lines in our DeviceFound method, for example:

Adding the following line will allow TCP connections on port 80:

The following line will remove/close the port we added above:

To display all the port maps that are currently added in the device:

To display the external IP:

In addition, if you want to check if a specific map already exists in the device you can check it by using the following method (the method bellow checks TCP port 80):

If the public port (or private port, both should work equally good) is -1 then no map on that port exists on the device.

This should be enough to get you going. Happy coding !

Share on FacebookTweet about this on TwitterShare on Google+Share on StumbleUponShare on LinkedInShare on RedditPin on PinterestShare on TumblrDigg thisPrint this pageEmail this to someone

28 Responses to UPNP port forwarding – The easy way

  1. Young says:

    NatUtility.StartDiscovery();
    ….
    device.GetExternalIP ();

    The function was called successfully.
    How do I get External IP back after some time?

    NatUtility.StopDiscovery ();
    Calling this function does not work.

  2. macgyber says:

    Might give an example.
    I need to send a message to a computer.
    I have the external ip internal ip and port where that computer listening .
    as I can make a method to return my external ip using your library.

  3. cedifra says:

    Thanks!

  4. goldbalaji13 says:

    I don’t have a router I have created a hosted network using my wifi card in my laptop. I want to forward all the user connected to my hosted network while making a http request (port 80) to be forwarded to http://localhost:8080

  5. TA says:

    What is the license?

  6. AXER says:

    Hi, never mind about that last comment, it appears that, despite having uPnP enabled my router at just doesn’t like uPnP, it works fine on my laptop at home.

    Thanks, for this quick how-to guide. :)

  7. AXER says:

    When using device.GetAllMappings() I get MappingException: “Error 402: Invalid Argument”

    I’ve done it the same way as you have done it also.

  8. Michael Carey says:

    Hi, really interested in this DLL but I’m working in a Wince 5.0 platform (.Net 3.5). Do you have a dll that’s built for same ???? Thanks in Advance.
    Mike

  9. jonny says:

    how do you change the name it leaves on the router port forawarding it says mono.nat i want it to say something else

  10. Vitor says:

    Hi, does not work for me, the console does not display any messages when started and I tried to put to record a log, but the log records empty.

    My router has UPnP.

    Here is the code:

    • CooLMinE says:

      Hello Vitor,

      Is the DeviceFound found event being raised ?

      In some cases it might be quite problematic to use standard UPNP libraries if the device it self does not implement the UPnP protocol according to the standards. One of the banes that using UPNP as a solution for port forwarding sadly.

      If this is the case you don’t really have a lot of options left, even if you bother messing around with the library’s code to get it working it will probably have the same issue on another device.

      If the aim is to port forward your own server’s port take a look at the UDP hole punching techniques, if not, then I am afraid is down to the user to do the port forwarding manually.

      • Vitor says:

        But the strange thing is the fact that the log is not recorded anything. I believe he was to record at least the connection information.

        I read elsewhere that the log serves precisely for this, when there is no upnp, is to write to the log that the connection failed.

        Unfortunately I did not find any examples anywhere ready to test.
        It may be something wrong in my project.

        I need this because I am building a project of remote access to the company I work for, and it is not feasible to configure port for all customers.

        • CooLMinE says:

          Using your code a log file is generated when the class is instantiated. Even when the discovering fails there are around 10 lines of log entries in the file (based on my tests results). Do you have administration rights to write to the location you are trying to write the log ?

          If it’s for a company I’d go for the UDP hole punching technique I mentioned above (similar to how TeamViewer/LogMeIn/Skype etc operates), since it is more reliable and won’t fail if the router does not support UPNP or if it doesn’t obey the UPNP standards.

  11. Johan says:

    Very good.
    Thank you!

  12. Ziv says:

    Thanks :-)
    If I will have a definite answer I will post it here

  13. Ziv says:

    Just to be clear… if my router is UPNP disable, Does the port forwarding still work?
    Would my app forward to the port I specify at device.CreatePortMap(new Mapping(Protocol.Tcp, XXX, XXX)); ???

    • CooLMinE says:

      Hey Zin,

      The answer is no, if the router doesn’t support UPNP or if it’s disabled then the above method will not work.

      If you have access to the server you can use the hole punching technique to establish connection between the server and the client (this doesn’t rely on UPNP) without the client need to port forward any ports. Take a look at http://www.fluxbytes.com/csharp/udp-hole-punching-implementation-in-c/

      But if both cases are not possible, meaning, the client’s UPNP is disabled and you have no access to the server in order to implement the hole punching, then you are left with no other alternative than to tell the client to manually port forward specific ports.

      • Ziv says:

        Thanks for the informative answer… I have another question if you don’t mind.
        Does the implementation support both IPv4 and IPv6 (or dual) ?

        • CooLMinE says:

          Sadly I can’t give you a precise answer as I didn’t have the chance to test IPv6 and UPNP myself yet, so the correct person to answer that would probably be the author of the library (http://monotorrent.blogspot.co.uk/2011/03/mononat-110.html).

          Theoretically it shouldn’t be an issue since as you can see in the example above you don’t specify the address yourself, just the incoming and outgoing ports. My assumption would be that if the router actually supports the technology (UPNP port forwarding with IPv6 addresses) then it should be forwarded properly internally. But as I said, this is merely my assumption till I get to test it out myself.

  14. CooLMinE says:

    From what I’m aware the library should work equally good in VB.NET as well.

    You will only need to convert the above example to VB, I would recommend trying http://www.developerfusion.com/tools/convert/csharp-to-vb/ and just correct any mistakes it produces during the conversion.

  15. Rodolfo says:

    Is there something like this for Visual Basic.Net?

Leave a Reply

Your email address will not be published. Required fields are marked *