Chris
Chris

Reputation: 1283

NAT Implementation

I'm developing an app that performs NAT between 2 network interfaces on a Windows machine, and I have a bit of a problem making sense of what's going on.

There are 2 network interfaces in the system:

What my app does:

To demonstrate what's going on I have attached a .cap file with the packets captured by Microsoft Network Monitor 3.4 (it can also be opened with Wireshark) during a test. The test consist in establishing a TCP connection with google.com:80. First the connection is established directly through the physical interface to prove that there is internet connectivity, and then the connection is established through the TAP interface to test the NAT.

Packet analysis from top to bottom:

All good, we have internet connectivity. Now I change the default gateway to be the virtual router operated by my app (192.168.200.1)

After NAT, the packet that is sent on the physical interface, is nearly identical to the one sent in the first test, and nothing is changed in the network topology. Why is the second TCP connection unsuccessful? It doesn't make any sense.

The program is using WinPcap. Here is the code if interested.

Upvotes: 1

Views: 904

Answers (1)

rodolk
rodolk

Reputation: 5907

I have checked the captured file and I don't see any difference at TCP level and MAC layer headers (between the successul SYN and the unsuccessful one). Only I see that in the successful SYN, the IP header checksum is 0, probably because the calculation is offloaded to the interface card. In the unsuccessful SYN, the checksum is calculated and correct according to Wireshark. That should not be a problem if the checksum is correct. That's the only difference I see at IP layer.

I would say either google or somebody in the middle is filtering out your next messages.

Now, something weird to me is why when your app closes the socket in stream index 0, it is sending a RST instead of FIN. Maybe some node is trying to prevent a RST attack from your IP address? Is there a way to close the socket and send a [FIN, ACK] message? Can you wait more time before running the second test?

Other weirdness is that in the second test both connections 192.168.200.100-your app (03:03:03:03:03:03) and "your app"-Google use the same source port 49181. That doesn't seem to be a problem because these are two different machines but I would investigate there as a very last resource. I don't think that's a problem though.

Edited:

After you explained the TCP segment is handed over unmodified I realized the problem is that you are not recalculating the TCP checksum!!! Both SYN messages (frame 7 and 8) have the same TCP checksum. If the IP addresses change, TCP checksum has to change.

BTW, this is a very interesting problem to look at.

Upvotes: 1

Related Questions