Hello all.

I'm feeling pretty confused about how UDP port forwarding is done. My situation is: I have Comp1 with a local IP (192.168.0.2) connected to Comp2 with external IP and internet connection, and some unknown Internet Client (IC) (three of them actually), who needs to send data to the Server hosted at Comp1 through UDP port 7777 and then receive a response.

I managed to forward UDP data from Comp2 to Comp1 by simply accepting IC's packets at Comp2's port 7777 and sending them to Comp1's port 7777, but the problem is that Comp1's Server sees sender as Comp2 and sends response to it (192.168.0.1), rather than to IC. I can't modify Server application and it judges about packets' source by UDP's IEP. Server then stores IEPs and sends data itself (it's p2p application actually).

I would think that the task is impossible, but this kind of forwarding is implemented in applications like AUTAPF (for both UDP and TCP ports).

So how do I forward ICs' data from Comp2 to Comp1 with Comp1's Server knowing, that response must be sent to ICs?

Here's what I managed to do:

namespace PortForwarder
{
    class Program
    {
        public static UdpClient UDP1 = new UdpClient(7777);
        static void Main(string[] args)
        {
            Console.Title = "Port Forwarder";
            Console.WriteLine("-= Port Forwarder started. =-");
            Console.WriteLine("UDP ports forwarded: 7777");
            UDP1.BeginReceive(ReceiveDataUDP1, null);
            while (true) { };
        }

         static void ReceiveDataUDP1(IAsyncResult ar)
        {
            IPEndPoint IEP = new IPEndPoint(IPAddress.Any, 0);
            Byte[] receiveBytes = UDP1.EndReceive(ar, ref IEP);
            
            // Trying to "lie" about local IEP results in exception
            // UdpClient US1 = new UdpClient(IEP);
            // US1.Send(receiveBytes, receiveBytes.Length, "192.168.0.2", 7777);

            UDP1.Send(receiveBytes, receiveBytes.Length, "192.168.0.2", 7777);
            UDP1.BeginReceive(ReceiveDataUDP1, null);
        }
    }

P.S. Comp1 is connected to the internet through Comp2's ICS (Internet Connection Sharing). Comp2 is running Windows Server 2008 and connects to the internet through VPN connection. I tried to set up NAT there, but VPN connection cannot be shared for some reason (and sharing public adapter doesn't help). If, by any chance, anybody knows how it's configured, I would be really grateful. :)

Normally you would fake the sender address for UDP packets but this has been disable in the win32 core as of XP SP2 and later. If you attempt to fake the sender address it will crash your application on a very low level.

That being said if you control the packet format then you need to add more data in the packet with the original senders IP address. If you don't control the packet format then you need to establish a common lookup table for translations or shoot the packet back to the original machine that received it, so it can forward it to the proper host.

That being said if you control the packet format then you need to add more data in the packet with the original senders IP address.

As I have stated, the Server app is not mine so there's no way to alter packets in a way for them to remain readable by Server (and especially to make Server store IPs from the packets rather than from their IEP).

If you don't control the packet format then shoot the packet back to the original machine that received it, so it can forward it to the proper host.

Well, they ARE shoot back to Comp2, but how can it know where to send them further? It would most probably work if there was 1 IC sending data and receiving response (by simply storing IC's IEP), but there are 3 ICs and Server sends data itself (seeing all ICs as 192.168.0.1).

you need to establish a common lookup table for translations

Could you please tell more about it and the way it's done?

Somehow some way you need to maintain the source IP address with the packet. Is there some sort of identifier in the packet you could use to route the message? Explain what you're doing, why you're doing it, and what the packets contain in great detail so we can try to find a solution for this.

Well, I have explained it pretty much it the first post, but I'll try to add some more detail.

Comp1 has internal IP (192.168.0.2) and is connected to Comp2, which provides internet connection.
Comp2 has external IP and internal IP (192.168.0.1). It is connected to the internet via VPN connection. It shares VPN connection with Comp1 via Internet Connection Sharing. My whole problem could be solved by simply setting up NAT (Network Address Translation) there, but I fail to set up NAT with VPN connection (unable to share it).

I am using Comp1 and trying to host a Borderlands server there. Borderlands online mode is based on p2p, so my Comp1 behaves both as a client and as a server. Game should works precisely like this: Comp1 receives "join packets" from up to 3 other players, stores packets' IPs in game's data and then, as a client, send "sync packets" to these IPs. All being done via 7777 UDP port. But, as you understand, players send packets to external IP, which belongs to Comp2, so it receives them. The task is to forward them to Comp1 without losing packets' IPs.

As you can see, there's not much choice here. I have control neither over packets, nor over application receiving/sending them. I need an application at Comp2 to either forward packets to Comp1 keeping their IPs (so that Comp1 can then send responses itself) or to somehow make Comp2 to both forward packets to Comp1 and forward its response to other players then (which, as I said, is unlikely, since Borderlands sees all the players as 192.168.0.1 and randomly sends packets to three absolutely identical adresses - how is Comp2 supposed to guess who is who?).

So... this is it.

You have nailed the solution... you need to get NAT working on the Comp1. I do extensive networking setup but I have never tried to make a windows machine act as a router or NAT machine so I don't have any advice on that.

Either way I don't think a c# application is capable of solving this issue. You need to keep trying to get the NAT working.

Can Comp2 browse the internet via the VPN? Does everything seem to work properly with the internet connection aside from not being able to forward packets? What version of windows is Comp1?

you need to get NAT working on the Comp1

Uh... On Comp1? It's a typo?

Either way I don't think a c# application is capable of solving this issue. You need to keep trying to get the NAT working.

As I said, there are some programs like AUTAPF which succesfully forward UDP/TCP ports. Don't know whether they are written in C# or not, but they surely DO work.

Can Comp2 browse the internet via the VPN?

Obviously, since it's directly connected to it.

Does everything seem to work properly with the internet connection aside from not being able to forward packets?

Yes, internet works for both computers currently.

What version of windows is Comp1?

Windows 7. Though can't see how it matters.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.