Sign in to follow this  
dpadam450

NAT Info

Recommended Posts

[PC1][PC2][PC3]-------------->[ROUTER]---------(internet)--------->[SERVER / Webpage]



So, all the pcs have firefox running. The http port is 80, so all their input/output ports use 80 correct?

They each have 3 local IPS: 192.168.0.X , X = 2, 3, 4

When PC1 sends data to the router, what does it send? It's local IP and then some data (like a web address)?

Then when the webpage comes back to the router, what exact info does it have to know that this is a request from PC1 to tell the Router this packet is for PC1? Because as far as I know the server ONLY receives the Routers IP and sends data back to the Router, but that packet has to have some knowledge embedded from the SERVER that says here ROUTER, this is for PC1.

This is my setup:

[PC1][PC2][PC3]-------------->[ROUTER]---------(internet)--------->[ROUTER2]---------->[MY SERVER]

What I know:

ROUTER2's IP Address.
MY SERVER's LAN IP address.
The udp port that MY SERVER calls recv() on.

Without port forwarding, how do I get a packet to hit from PC1 to MY SERVER? I know that if I port forward ROUTER2 to translate packets based on port, it WILL receive PC1's request, and then when it sends a packet back to PC1, it magically gets there, so what is the magic part I need to know about PC1?

Share this post


Link to post
Share on other sites
I assume maybe the problem is that a reply needs to come back from the IP address that was sent to so that the router know knows to forward that port temporarily to a certain machine on the LAN.

Share this post


Link to post
Share on other sites
The outgoing and incoming port numbers are not the same. If you remove the router for simplicitys sake and simply have a client and a server and have the client open a connection to the server on port 80 it will look something like this:

Client:94.120.84.43 : 35246 -> Server:54.65.4.10 : 80

the IP header contains the senders ip address and the port the reply should be directed to (aswell as the destination ip and port)

If you put a NAT router between them then the client will send its IP packet to the router
lets say it looks like this:
SRC: 192.168.0.34:32456
DST: 85.4.75.8:80

Then the router will open its own connection to the destination and rewrite the IP header to look like:
SRC: routerspublicip:23645
DST: 85.4.75.8:80

Then the router simply stores the mapping between its port 23645 and PC1s port 32456

All outgoing connections get their own unique port (these are assigned automatically by the OS, and are normally restricted to the 1024-65535 range to avoid conflicts with commonly used services)

Share this post


Link to post
Share on other sites
A TCP or UDP connection is a combination of four items:
The local IP address
The local port
The remote IP address
the remote port.

A connection from your local machine to a web server will have all of these items. The router then performs a mapping between the local IP/port to the the external IP and another port. Since the router knows this mapping, it can perform the reverse mapping when a packing comes back from the web server.

An example:
You have 2 PCs on your network and they both connect to google through your router who has a public IP address of 10.1.1.1.
PC A connects to google as 192.168.1.2 with port 8134
PC B connects to google as 192.168.1.3 with port 8134

Your router creates a mapping:
192.168.1.2:8134 -> 10.1.1.1:1635
192.168.1.3:8134 -> 10.1.1.1:1543

Now data can flow between both PCs and google without a care in the world. Note: all port numbers and IPs chosen at random.

This is known as PAT (Port Address Translation), because it uses the port and IP address for translation. NAT, or network address translation, is commonly used as another term for PAT, but is typically a 1 to 1 mapping of internal IP address to external IP address (mapped either statically or dynamically).

Share this post


Link to post
Share on other sites
My issue may be that it is UDP does not save those mappings when they get sent, but that TCP saves those mappings? I'm thinking that is maybe what it is then, that I have to keep a connection(mapping) going then?

So I stepped further along, so here is my simpler setup:

[Android]------->[Verizon Satellite]------------------[My Router]--port forward 8004----->[PC receive data on 8004]

So android has a local IP.
I open a socket on port 35000 and send some data to destination: [My Router IP]:8004, so that just goes forward to my PC.
I get the Phones packet. The packet came from IP of the Verizon Satellite, with a new port: 9724.

So my send back IP is Verizon Satellite, with port 9724.
Android tries to receive data on port 35000 but nothing ever shows up. So maybe it is forgetting that mapping you suggested?
I also try to receive on Androids port 9724, but nothing shows up there either.

Share this post


Link to post
Share on other sites
The router should not "forget" UDP mappings, they should stay active for atleast a few seconds.

Your server should send the data back on the ip and port you get when you call recvfrom (Which should be the phones ip or Verizon Satellite if they use NAT on their end (some ISPs do for phones since ipv4 numbers are running out), You should not open a listening socket on the android device, it should read back data from the same socket that you used to send data.

Share this post


Link to post
Share on other sites
Android:
[CODE]
DatagramSocket udpSocketOut = new DatagramSocket(35000);

String myName = "hey";
DatagramPacket sendData = new DatagramPacket(myName.getBytes(), myName.length(), InetAddress.getByName("97.101.51.157"), 8004);
SocketAddress socketAddress;
udpSocketOut.send(sendData);


byte recvBytes[] = new byte[100];
DatagramPacket recvData = new DatagramPacket(recvBytes, 100);
udpSocketOut.receive(recvData);

udpSocketOut.close();
[/CODE]

Windows:
[CODE]
SOCKADDR_IN FromAdd;
char Buffer[100];
int FromSize = sizeof(FromAdd);
int error = 1;

while(true)
{
error = recvfrom(UDP_IN, (char*)&Buffer, sizeof(Buffer), 0, (SOCKADDR*)&FromAdd, &FromSize );
if(error == SOCKET_ERROR)
{
break;
}
//otherwise we received some bytes
else
{
string name = Buffer;
name += 'a';
cout << name << " " << inet_ntoa(FromAdd.sin_addr) <<":" << FromAdd.sin_port;
char packet[3]={'A','B','A'};
//RESPOND
int error;
SOCKADDR_IN connection = FromAdd;

error = sendto(UDP_OUT, (char *)packet, 3, 0, (SOCKADDR*)&connection, sizeof(connection) );
[/CODE]

Share this post


Link to post
Share on other sites
First of all, don't pass a port to the DatagramSocket on the android side, let the OS assign a free port to it(otherwise you risk clashing with other applications), use the same socket to send and recieve data on both ends, (You're reading from the UDP_IN socket but sending on UDP_OUT on the server which will not work, the phone sent data to the UDP_IN socket and NAT routers will only route packets coming back from that specific socket (or its ip and port rather, but 2 sockets cannot be open on the same port so your UDP_IN and UDP_OUT sockets are definitly bound to different ports)(Otherwise it would be possible for users of a shared host to completely fuck eachothers clients over by sending junk data to them)

Share this post


Link to post
Share on other sites
In my code, I only have 1 socket called
udpSocketOut(35000), which send and then receive from it. Secondly when I check the port variable on the socket after it is created it gives -1, whether i put 35000 or not.
So I don't know what to do with it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this