Well, something happened here. An argument was put forth that 32 bits is enough because the address does not have to do routing – the source route can handle the rest. Clearly it was recognized that a variable length something was needed, but the source route was deemed sufficient for that, and the 32-bit address won out in the end. So, perhaps what killed IP is not that the address is too short (though probably it is), but that the ability for DNS to hand a host a source route (which it could then put in the header so that the right thing could happen in the network) was not created.
Not only did the failure to fully implement source routing (in DNS) make it impossible to address into a private network, it also created the situation where NAT had to be implemented as it was.
Consider the following network:
/----------X-Y------------ / / \\ \\ / / \\ public \\ / 10.0.0.0 / \\ net \\ / / \\ \\ H1---------/ \\-----------H2
H1 is on a private network. H2 is a server of some kind on the public network. The two networks are interconnected by a router with address X on the private network and address Y on the public net.
Can H1 initiate a working TCP session to H2 without NAT tables on the router? The answer is yes! H1 addresses its packet as follows. Address X is the IP Destination Address. A Loose Source and Record Route (LSRR) option is also used with a single address – H2’s. What happens?
Well, the packet routes first to X on the private network, then the LSRR is processed. RFC 791:
If the address in destination address field has been reached and the pointer is not greater than the length, the next address in the source route replaces the address in the destination address field, and the recorded route address replaces the source address just used, and pointer is increased by four.
The recorded route address is the internet module’s own internet address as known in the environment into which this datagram is being forwarded.
So H2’s address is moved into the destination address field. Yet note carefully what else happens. The “recorded route address replaces the source address”, and the “recorded route address is the… internet address as known in the environment into which this datagram is being forwarded“. So address Y is placed into the LSRR option!
So H2 receives a packet addressed to it (of course), with H1’s private IP address as the source address and an LSRR option listing the address Y. This is enough information to construct a return packet addressed to Y with H1 listed in an LSRR option. Now, can H1 count on H2 to do this? According to RFC 1122 (section 126.96.36.199) it can:
When a TCP connection is OPENed passively and a packet arrives with a completed IP Source Route option (containing a return route), TCP MUST save the return route and use it for all segments sent on this connection.
So far, it certainly seems like we don’t need NAT! What’s the problem, then? Well, consider what H1’s routing table has to look like:
Destination Action ----------- ------ H1's local subnet direct delivery 10.0.0.0/8 local subnet's router default LSRR via X
It’s the default route that’s the problem. As far I know, there is not a single operating system today that can specify a loose source route as a target in a routing table entry. And even if the operating system supported it, how would such an entry be configured? Neither DHCP nor PPP can deliver such a route, and of course no routing protocol can communicate such a thing. Not to mention the simple fact that source routing is so heavily filtered that it is essentially unusable in the Internet.
So, not only was IP “killed” by the failure of DNS to hand out a source route (which would have let H2 connect to H1), but also by the failure to specify a source route in a routing table entry (to let H1 connect to H2).