Closely related with the above problem of keeping state information
about TCP and possibly UDP connections is the problem of IP fragments.
It is often desirable to base the decision wether a packet should
be translated not just on the IP addresses, but also on the TCP/UDP
addresses, the ports. This way telnet packets can be treated different
compared to http packets. An example for a use of it is to have just
one (virtual) IP or DNS name for all services, which will than be
remapped to different hosts providing the service. Such services might
even be provided a virtual host. A firewall with application level
gateways does the same to a certain degree, but it can only do this
for services where a gateway exists and mostly does gateways are not
transparent. Besides, this is just an example for why it might be
of use to look at the ports of packets for NAT.
The problem is that as soon as a packet has been fragmented the NAT
router cannot tell the port except of the first fragment containing
the TCP header. That is why we must also keep state information about
fragments. We must store all data of the first fragment including
its TCP or UDP port, of course, in order to be able to know the port
the other fragments or going to. Even this measure might not be sufficient
since IP does not guarantee that packets arrive with the correct sequence,
i.e. the third fragment of a fragmented packet might pass through
the NAT router first, before the first fragment still carrying the
port information. In this case all we can do is to hold back all non-first
fragments of a fragmented packet until the first one arrives, so that
we know if we have to translate the packet or not.
When we have to do that much just to be able to use the TCP or UDP addresses for our to-NAT-or-not decision the idea to use NAT to also rewrite these addresses is almost obvious. This way we have not just IP address translation but also UDP/TCP address translation. It may be less significant but it certainly is a useful extension. An example for its use are virtual servers: Let us assume we want to create a virtual webserver. Let us further assume that the real webserver daemons running on different machines listen on different ports for some reason. When we do not rewrite the destination port in packets to the virtual server (and insert the original port on answer packets) this setup is impossible, than all webservers must listen on the same port where the virtual server provides its web service.