IP Masquerading Code Follow-up

This is a follow-up article to the author's “IP Masquerading with Linux” in Linux Journal Issue 27.

IP Fragmentation used to be a problem with masqueraded connections. Because the follow-on fragments contained no transport (TCP or UDP) header information, the datagram could not be correlated to an existing connection. The option for “always defragment” from the configuration menu is shown here:

IP: always defragment (CONFIG_IP_ALWAYS_DEFRAG)
[N/y/?] (NEW) y

This option will cause fragmented datagrams to be reassembled at the masquerading host rather than at the destination.

Still, the notion of performing reassembly in the “middle” of data transfer goes against the general principle of IP delivery. Other methods exist to help eliminate fragmentation. Two of these are MSS negotiation and path MTU discovery.

MSS (maximum segment size) negotiation is an area where IP Masquerading could improve. What I mean by this is best shown in an example.

From Figure 1, let's look at the TCP traffic generated during a connection open from the machine called falcon to an external machine. Listings 3 and 4 shows the traffic.

Listing 3. TCP three-way hand-shake traffic from falcon to deathstar on

Listing 4

As we can see, the MSS advertised from the masqueraded connection (1326) is exactly the same as the one sent from the original host, falcon. The catch here is how I set up the PPP connection from deathstar to the PPP server. I set the MTU to be 296 knowing fragmentation would occur if the connection was not handled properly. A method of handling that takes advantage of the MSS to eliminate fragmentation is for deathstar, the masquerading host, to readjust the MSS based on knowledge it has of the next hop connection. An MSS of 256 (i.e. 296-40) is more appropriate.

You may also notice the (DF) field in the traffic from Figure 4. This is the “Don't Fragment” bit in the IP header. It indicates that if a datagram must be fragmented on its way to the destination, it will be discarded and an ICMP error message sent back to the source. Path MTU discovery is usually responsible for setting the DF bit. It does so in order to look for those ICMP error messages, and if found, it will adjust how much data is put into a TCP segment and resend. A host will continue to do this until a segment size can be found such that the Maximum Transmission Units of all of the data links between the source and destination can accommodate the datagrams without fragmentation.

Given the multitude of methods for overcoming fragmentation, it is no longer a problem in masqueraded networks.

Network Address Translation

A network address translator (NAT) device is one which performs address hiding. A NAT works on relationships that can be 1:1, many:1 or many:n; it also allocates addresses for external use statically or dynamically.

Instead of having a single ISP assigned IP address, a user or company may have an entire class-C, address space. However, the internal network might still be large. With NAT, addresses could be assigned for different functions. For example, assume is the address we have. Further, assume we are using through for our internal networks. We could assign the following:

  • permanent addresses assigned outside of NAT device

  • statically assigned to corresponding internal addresses

  • dynamically assigned to remaining internal addresses

IP Masquerading is a many:1, static allocation case of NAT

Linux 2.1.x kernels now have support for NAT as a marked entry in the routing table. A full-featured implementation is rumored to be implemented sometime during the 2.1.x development. For many of the abnormal protocols that IP Masquerading already supports, NAT will have to go through the same growing pains. However, it should lead to a more feature-rich and flexible address-hiding environment.


Although the basic functionality has stayed the same, IP Masquerading has progressed tremendously in the past year. Support for new protocols and better handling of old problems have evolved it from experimental status to a fully functional part of Linux kernels. It solves many real world problems for many people and will continue to do so. During the evolutionary development of Linux it may happen that NAT will replace the work that has preceded it, but until then I highly recommend this amazing piece of technology.

Code Maturity Levels



Chris Kostick is a Senior Computer Scientist at Computer Sciences Corporation's Network Security Department. He enjoys working with Linux, beginning with kernel version 1.1.18. As far as computers go, he's not sure if he has more fun debugging TCP/IP problems or shooting DOS machines. He can be reached at ckostick@csc.com or by just yelling “Chris” real loud.