RFC 1631
The IP Network Address Translator (NAT)
RFC 1631: The IP Network Address Translator (NAT) ๐
okay bestie, come sit next to me ๐ง this is the RFC that gave us NAT, and it's giving early-90s internet problem-solving ๐ here's the title block tea:
- Working group: Network Working Group
- RFC number: 1631
- Authors: K. Egevang (Cray Communications) and P. Francis (NTT)
- Category: Informational
- Date: May 1994
- Obsoletes / Updates: nothing listed in the title block ๐
Status of this Memo โจ
okay so first, the legal-ish stuff ๐ this memo is just providing information for the Internet community ๐. It does not specify an Internet standard of any kind, so it's not the official rulebook ๐ โโ๏ธ. And distribution is unlimited, so share away ๐!
Abstract ๐
so the two biggest problems the IP Internet is dealing with are IP address depletion ๐ญ and scaling in routing ๐. both have fixes being cooked up ๐ณ. the short-term fix is CIDR (Classless InterDomain Routing), and the long-term fixes are a bunch of proposals for new internet protocols with bigger addresses ๐.
but here's the thing: CIDR might not be enough to keep the IP Internet going until the long-term stuff is ready ๐ฌ. so this memo proposes another short-term fix, address reuse โป๏ธ, which can either complement CIDR or make it unnecessary (main character energy ๐). the way it works is you put Network Address Translators (NAT) at the borders of stub domains. each NAT box has a table of pairs: local IP addresses and globally unique addresses ๐๏ธ. the IP addresses inside the stub domain are not globally unique. they get reused in other domains, which solves address depletion ๐. the globally unique addresses get handed out using the current CIDR allocation schemes, and CIDR takes care of the scaling problem ๐ง . the biggest perk of NAT is that you can install it without changing routers or hosts ๐ซถ. this memo has a preliminary design for NAT and talks through its pros and cons ๐.
Acknowledgments ๐ซถ
this memo is based on a paper by Paul Francis (formerly Tsuchiya) and Tony Eng, published in Computer Communication Review in January 1993 ๐. Paul got the concept of address reuse from Van Jacobson ๐.
Kjeld Borch Egevang edited the paper to make this memo, and he introduced adjustment of sequence-numbers for FTP ๐ง. big thanks to Jacob Michael Christensen for his comments on the idea and text ๐ (we thought for a long time that we were the only ones who had had the idea ๐ญ relatable).
1. Introduction ๐ธ
the two big problems from the abstract are the headline here too ๐ฐ: IP address depletion and routing scaling. the short-term fix is CIDR (Classless InterDomain Routing) [2] ๐ , and the long-term fixes are new internet protocols with larger addresses ๐.
until the long-term stuff is ready, address reuse is an easy way to keep the demand for IP addresses down ๐. the trick is that only a tiny percentage of hosts in a stub domain are talking outside the domain at any given time ๐ค. (a stub domain is a domain, like a corporate network, that only handles traffic originated by or destined to hosts in that domain ๐ข.) honestly, lots of hosts (if not most) never talk outside their stub domain ๐. so only a subset of the IP addresses inside a stub domain need be translated into globally unique IP addresses when outside communication is required โจ.
the downside is that this takes away the end-to-end meaning of an IP address ๐ฌ, and it makes up for that with more state in the network ๐งพ. there are various work-arounds that cut down on the potential pitfalls ๐ ๏ธ. and ngl, connection-oriented protocols are basically doing address reuse at every hop ๐คฏ.
the huge perk is that it can be installed incrementally, without changes to either hosts or routers ๐. (a few unusual applications may require changes, fr.) because of that, this solution can be implemented and experimented with quickly โก. if nothing else, it can provide temporary relief while other, more complex and far-reaching solutions get worked out ๐ซ .
2. Overview of NAT ๐ฆ
the design in this memo is called NAT, for Network Address Translator ๐. NAT is a router function that can be configured the way figure 1 shows. only the stub border router requires modifications ๐ ๏ธ.
NAT's basic operation goes like this. the addresses inside a stub domain can be reused by any other stub domain ๐. for example, a single Class A address could be used by many stub domains ๐๏ธ. NAT gets installed at each exit point between a stub domain and the backbone ๐ช. if there's more than one exit point, it's super important that every NAT has the same translation table ๐๏ธ.
\ | / . /
+---------------+ WAN . +-----------------+/
|Regional Router|----------------------|Stub Router w/NAT|---
+---------------+ . +-----------------+\
. | \
. | LAN
. ---------------
Stub border
Figure 1: NAT Configuration
for instance, in the example of figure 2, both stubs A and B internally use class A address 10.0.0.0. Stub A's NAT is assigned the class C address 198.76.29.0, and Stub B's NAT is assigned the class C address 198.76.28.0. the class C addresses are globally unique, so no other NAT boxes can use them ๐.
\ | /
+---------------+
|Regional Router|
+---------------+
WAN | | WAN
| |
Stub A .............|.... ....|............ Stub B
| |
{s=198.76.29.7,^ | | v{s=198.76.29.7,
d=198.76.28.4}^ | | v d=198.76.28.4}
+-----------------+ +-----------------+
|Stub Router w/NAT| |Stub Router w/NAT|
+-----------------+ +-----------------+
| |
| LAN LAN |
------------- -------------
| |
{s=10.33.96.5, ^ | | v{s=198.76.29.7,
d=198.76.28.4}^ +--+ +--+ v d=10.81.13.22}
|--| |--|
/____\ /____\
10.33.96.5 10.81.13.22
Figure 2: Basic NAT Operation
so when stub A host 10.33.96.5 wants to send a packet to stub B host 10.81.13.22 ๐ฆ, it uses the globally unique address 198.76.28.4 as the destination and sends the packet to its primary router ๐ฎ. the stub router has a static route for net 198.76.0.0, so the packet gets forwarded onto the WAN-link ๐ฃ๏ธ. but wait, NAT swaps the source address 10.33.96.5 in the IP header for the globally unique 198.76.29.7 before the packet gets forwarded ๐. return-path IP packets go through similar address translations too ๐ซ.
notice that this needs no changes to hosts or routers ๐. for instance, as far as the stub A host is concerned, 198.76.28.4 is just the address of the host in stub B ๐. the address translations are totally transparent ๐ซฅ.
of course, this is just a simple example, and there are loads of issues to explore ๐. next up, we look at various aspects of NAT ๐.
3. Various Aspects of NAT โจ
3.1 Address Spaces ๐ฆ
Partitioning of Reusable and Non-reusable Addresses ๐งฉ
for NAT to work properly, the IP address space has to be split into two parts: the reusable addresses used inside stub domains, and the globally unique addresses ๐ช. we call the reusable ones local addresses and the globally unique ones global addresses. any given address must either be a local address or a global address, and there is no overlap ๐ซ.
the problem with overlap goes like this: say a host in stub A wants to send packets to a host in stub B, but stub B's local addresses overlap with stub A's local addresses ๐ต. then the routers in stub A wouldn't be able to distinguish stub B's global address from their own local addresses ๐คฏ.
Initial Assignment of Local and Global Addresses ๐
a single Class A address should be allocated for local networks (see RFC 1597 [3]) ๐ฎ. that address could then be used for internets with no connection to the Internet ๐๏ธ. NAT then gives you an easy way to turn an experimental network into a "real" network by translating the experimental addresses into globally unique Internet addresses ๐ช.
existing stubs that have unique addresses assigned internally, but are running out of them, can switch addresses subnet by subnet over to local addresses ๐. the freed-up addresses can then be used by NAT for external communications ๐.
3.2 Routing Across NAT ๐ฃ๏ธ
the router running NAT should never advertise the local networks to the backbone ๐ซ๐ก. only the networks with global addresses may be known outside the stub ๐. however, global information that NAT receives from the stub border router can be advertised inside the stub the usual way ๐ข.
Private Networks that Span Backbones ๐
in lots of cases, a private network (like a corporate network) is spread across different locations and uses a public backbone to talk between those locations ๐ข๐. in that situation, address translation isn't desirable ๐ โโ๏ธ. a lot of hosts might want to talk across the backbone, which would need big address tables ๐, and there would be more applications that depend on configured addresses instead of going to a name server ๐งพ. we call this kind of private network a backbone-partitioned stub ๐งฉ.
backbone-partitioned stubs should behave as though they were a non-partitioned stub ๐งธ. that means the routers in all partitions should maintain routes to the local address spaces of every partition ๐บ๏ธ. of course, the (public) backbones don't maintain routes to any local addresses ๐. so the border routers must tunnel through the backbones using encapsulation ๐. to do that, each NAT box sets aside one global address for tunneling ๐ฆ. when NAT box x in stub partition X wants to deliver a packet to stub partition Y, it encapsulates the packet in an IP header whose destination address is the global address of NAT box y that's been reserved for encapsulation ๐. when NAT box y receives a packet with that destination address, it decapsulates the IP header and routes the packet internally ๐.
3.3 Header Manipulations
okay so NAT doesn't just swap out the IP address and call it a day ๐ . It also has to fix the IP checksum AND the TCP checksum ๐ญ. And bestie, TCP's checksum also covers a pseudo header that includes the source and destination addresses, so everything is connected ๐ธ๏ธ. NAT must also look out for ICMP and FTP and fix every spot where an IP address shows up. There are undoubtedly other places that need changes too ๐. Hopefully most of them get discovered during experimentation with NAT.
The checksum fixes for IP and TCP are actually simple and efficient โจ. Both use a one's complement sum, so you only need the arithmetic difference between the before-translation and after-translation addresses, and then you add that to the checksum. The only tricky part is figuring out whether the addition wrapped around (in either the positive or negative direction) ๐. If it did, you have to add or subtract 1 to keep the one's complement math correct. Here's the sample C code for it ๐:
void checksumadjust(unsigned char *chksum, unsigned char *optr,
int olen, unsigned char *nptr, int nlen)
/* assuming: unsigned char is 8 bits, long is 32 bits.
- chksum points to the chksum in the packet
- optr points to the old data in the packet
- nptr points to the new data in the packet
*/
{
long x, old, new;
x=chksum[0]*256+chksum[1];
x=~x;
while (olen) {
if (olen==1) {
old=optr[0]*256+optr[1];
x-=old & 0xff00;
if (x<=0) { x--; x&=0xffff; }
break;
}
else {
old=optr[0]*256+optr[1]; optr+=2;
x-=old & 0xffff;
if (x<=0) { x--; x&=0xffff; }
olen-=2;
}
}
while (nlen) {
if (nlen==1) {
new=nptr[0]*256+nptr[1];
x+=new & 0xff00;
if (x & 0x10000) { x++; x&=0xffff; }
break;
}
else {
new=nptr[0]*256+nptr[1]; nptr+=2;
x+=new & 0xffff;
if (x & 0x10000) { x++; x&=0xffff; }
nlen-=2;
}
}
x=~x;
chksum[0]=x/256; chksum[1]=x & 0xff;
}
Now FTP, which is a whole mood ๐ญ. The arguments to the File Transfer Protocol (FTP) PORT command include an IP address, and it's written in ASCII (yes, really!) ๐. If that IP address is local to the stub domain, NAT has to substitute it. Because it's ASCII, the packet size can change. For example, 10.18.177.42 is 12 ASCII characters, but 193.45.228.137 is 14 ASCII characters ๐ข. If the new size matches the old one, only the TCP checksum needs adjusting again. If the new size is smaller, ASCII zeroes may be inserted, but that's not guaranteed to work ๐. If the new size is larger, TCP sequence numbers have to change too.
NAT also keeps a special table to fix the TCP sequence and acknowledge numbers for packets with source port FTP or destination port FTP ๐ง. Each table entry should have the source, destination, source port, destination port, initial sequence number, delta for sequence numbers, and a timestamp. New entries only get created when FTP PORT commands are seen. The initial sequence numbers are how NAT figures out whether a packet's sequence number is before or after the last FTP PORT command (and delta may be increased for every FTP PORT command) ๐. Sequence numbers get incremented and acknowledge numbers get decremented. If the FIN bit is set in one of the packets, the entry may be deleted soon after (1 minute should be safe) ๐งน. Entries that haven't been used for, e.g., 24 hours should be safe to delete too.
The sequence number adjustment has to be coded carefully so it doesn't hurt TCP performance in general ๐๏ธ. And of course, if the FTP session is encrypted, the PORT command will fail ๐.
Now ICMP ๐. If an ICMP message passes through NAT, it may need two address modifications and three checksum modifications. Why? Because most ICMP messages contain part of the original IP packet in the body ๐ฆ. So for NAT to be completely transparent to the host, the IP address of the IP header embedded in the ICMP data must be modified, the checksum field of that same embedded IP header must be modified to match, and the ICMP header checksum must be modified to reflect those changes in the ICMP body. On top of that, the normal IP header also needs to be modified, as already described.
It's not totally clear whether the IP header inside the ICMP body really needs to be modified ๐ค. That depends on whether any host code actually looks at that embedded IP header. In fact, it might be useful to provide the exact header seen by the router or host that issued the ICMP message, to help with debugging ๐. Either way, no modifications are needed for Echo and Timestamp messages, and NAT should never need to handle a Redirect message.
SNMP messages could be modified, but it's even more dubious than ICMP that it will be necessary ๐คท.
Applications with IP-address Content
Any application that carries (and uses) an IP address inside the application itself won't work through NAT unless NAT knows about that application and does the right translation ๐ . It's not possible, or even necessarily desirable, for NAT to know about all of these applications. And if encryption is used, it's impossible for NAT to make the translation ๐.
These systems might be able to avoid NAT if the hosts they run on are assigned global addresses ๐. Whether that works depends on the intra-domain routing algorithm and the internal topology, because the global address has to be advertised in the intra-domain routing algorithm. With a low-feature routing algorithm like RIP, the host might need its own class C address space, which has to be advertised internally AND externally (thus hurting global scaling) ๐. With a high-feature routing algorithm like OSPF, the host address can be passed around individually and can come from the NAT table ๐ฆ.
Privacy, Security, and Debugging Considerations
Unfortunately, NAT reduces the number of options for providing security ๐ค. With NAT, nothing that carries an IP address, or information derived from an IP address (like the TCP-header checksum), can be encrypted. Most application-level encryption should be ok, but this still prevents encryption of the TCP header ๐.
On the other hand, NAT can be seen as providing a kind of privacy mechanism ๐ถ๏ธ. That's because machines on the backbone can't monitor which hosts are sending and receiving traffic (assuming, of course, that the application data is encrypted).
The same thing that boosts privacy can also make debugging problems (including security violations) harder ๐จ. If a host is abusing the Internet in some way (like trying to attack another machine, or sending huge amounts of junk mail or something), it's much harder to pinpoint the source of the trouble, because the host's IP address is hidden.
4. Conclusions โจ
NAT may be a good short-term solution to the address depletion and scaling problems ๐ธ. That's because it requires very few changes and can be installed incrementally. But NAT has several negative characteristics that make it inappropriate as a long-term solution, and may even make it inappropriate as a short-term solution ๐ฌ. Only implementation and experimentation will determine whether it's appropriate.
The negative characteristics are:
- It requires a sparse end-to-end traffic matrix. Otherwise, the NAT tables will be large, which gives lower performance. The expectation is that end-to-end traffic matrices really are sparse, but experience with NAT will show whether they are. Either way, future applications may need a rich traffic matrix (for instance, distributed resource discovery), which makes long-term use of NAT unattractive ๐.
- It increases the probability of mis-addressing.
- It breaks certain applications (or at least makes them more difficult to run).
- It hides the identity of hosts. This has the benefit of privacy, but it's generally a negative effect ๐ซ .
- Problems with SNMP, DNS, ... you name it ๐.
Current Implementations
Paul and Tony implemented an experimental prototype of NAT on public domain KA9Q TCP/IP software [1] ๐ ๏ธ. This implementation manipulates addresses and IP checksums.
Kjeld implemented NAT in a Cray Communications IP-router ๐ฅ๏ธ. It was tested with Telnet and FTP. This implementation manipulates addresses, IP checksums, TCP sequence/acknowledge numbers, and FTP PORT commands.
The prototypes have demonstrated that IP addresses can be translated transparently to hosts, within the limitations described in this paper ๐.
REFERENCES โจ
[1] Karn, P., "KA9Q", anonymous FTP from ucsd.edu (hamradio/packet/ka9q/docs).
[2] Fuller, V., Li, T., and J. Yu, "Classless Inter-Domain Routing (CIDR) an Address Assignment and Aggregation Strategy", RFC 1519, BARRNet, cisco, Merit, OARnet, September 1993.
[3] Rekhter, Y., Moskowitz, B., Karrenberg, D., and G. de Groot, "Address Allocation for Private Internets", RFC 1597, T.J. Watson Research Center, IBM Corp., Chrysler Corp., RIPE NCC, March 1994.
Security Considerations ๐
Security issues are not discussed in this memo. ๐จ Read that again, bestie: the memo itself doesn't cover them, so don't assume anything is secured just because this document says nothing about it ๐.
Authors' Addresses ๐ฆ
Kjeld Borch Egevang
Cray Communications
Smedeholm 12-14
DK-2730 Herlev
Denmark
Phone: +45 44 53 01 00
EMail: kbe@craycom.dk
Paul Francis
NTT Software Lab
3-9-11 Midori-cho Musashino-shi
Tokyo 180 Japan
Phone: +81-422-59-3843
Fax +81-422-59-3765
EMail: francis@cactus.ntt.jp
๐ฆ where this page comes from
- ietf: rfc1631 1994-05
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms