title: NAT Implementation
body: <p>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.</p>
  
  <p>There are 2 network interfaces in the system:</p>
  
  <ul>
  <li>a physical network interface (00:0c:29:bc:4c:11 192.168.133.130) that uses as a gateway 00:50:56:eb:f5:15 - 192.168.133.2 (operated by VMware)</li>
  <li>a virtual TAP network interface (00:ff:15:08:ac:26 192.168.200.100) used by my app that uses as a gateway 03:03:03:03:03:03 - 192.168.200.1 (operated by my app)</li>
  </ul>
  
  <p>What my app does:</p>
  
  <ul>
  <li>responds to ARP requests to 192.168.200.1 (the virtual gateway)</li>
  <li>performs one-to-one NAT for ICMP, UDP and TCP between the TAP interface and the physical one</li>
  </ul>
  
  <p>To demonstrate what's going on I have attached a <a href="https://skydrive.live.com/redir?resid=2CF05A900F9844D3%217172" rel="nofollow">.cap file</a> with the packets captured by <a href="http://www.microsoft.com/en-us/download/details.aspx?id=4865" rel="nofollow">Microsoft Network Monitor 3.4</a> (it can also be opened with <a href="http://www.wireshark.org/" rel="nofollow">Wireshark</a>) 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.</p>
  
  <p>Packet analysis from top to bottom:</p>
  
  <ul>
  <li>1 - TCP SYN sent to google.com directly through the physical interface</li>
  <li>2 - TCP SYN-ACK received from google.com through the physical if</li>
  <li>3 - TCP ACK sent to google.com through physical if</li>
  <li>4 - TCP RST-ACK sent to google.com through physical if, to close connection</li>
  </ul>
  
  <p>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)</p>
  
  <ul>
  <li>5 - Windows notices the default gateway changed to 192.168.200.1 and sends an ARP request to 192.168.200.1</li>
  <li>6 - my app responds that 192.168.200.1 is at 03:03:03:03:03:03</li>
  <li>7 - TCP SYN sent to google.com through the TAP interface (192.168.200.100) to the virtual router (192.168.200.1)</li>
  <li>8 - my app performs NAT on the packet (source and destination MAC address are changed accordingly, and IP source address is changed to 192.168.133.130) and sends the packet on the physical interface to 00:50:56:eb:f5:15 (192.168.133.2)</li>
  <li>9 - no response received, so a second TCP SYN is sent on TAP if</li>
  <li>10 - my app performs NAT the same way and sends the packet on the physical if</li>
  <li>11 - again no response, so a third attempt is made</li>
  <li>12 - my app performs NAT in the same manner</li>
  </ul>
  
  <p>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.</p>
  
  <p>The program is using WinPcap. <a href="http://pastebin.com/ZZRcfHNz" rel="nofollow">Here</a> is the code if interested.</p>