skip to content

PAT and Port Mapping

PAT lets one public IP serve a whole network by giving each flow its own source port, keyed on the full tuple. Port exhaustion under connection churn, and the carrier-grade version, are what to know.

on this pageshow

questions

5

How does Port Address Translation (NAPT) let many private hosts share one public IPv4 address, and how does a reply reach the right host?

level: juniorimportance: must knowfreq 68%

answer

  1. one address, many conversations
  2. address and port rewritten together
  3. a table of bindings
  4. the reply's destination port is the lookup key

basics

~20 s

A NAPT rewrites each outbound packet's private source address and port to the public address plus a port it assigns, records that binding, and uses a reply's destination port to find the binding and restore the private address and port.

solid answer

~40 s

Basic NAT (RFC 3022) maps addresses one for one, so it needs a public address per active host. NAPT, which most people call PAT, also translates the transport identifier: the TCP or UDP port, or the ICMP query identifier. When `10.20.0.15:51000` opens a connection, the translator records a binding `(10.20.0.15, 51000) -> (203.0.113.5, 40001)`, rewrites the source address and port, and adjusts the IP and TCP/UDP checksums. The server only ever sees `203.0.113.5:40001` and replies there; the translator looks up port 40001, rewrites the destination back to `10.20.0.15:51000` and forwards it. In the classic design every binding holds its own external port, so one address carries tens of thousands of simultaneous bindings per transport protocol (64,512 if it uses ports 1024-65535).

go deeper

for a junior

Recall the two halves: outbound packets get the public address and a translator-chosen port, and replies are matched back by that port. Be ready to name RFC 1918 space as the reason translation is needed at all.

for a middle

Walk a connection through the binding table with concrete addresses and ports, including the checksum adjustment and what happens when two hosts pick the same source port.

for a senior

Connect the table to its consequences: per-protocol port capacity on one address, idle bindings expiring, unsolicited inbound packets having nowhere to go without a static rule, and protocols that embed addresses in their payload.

for a principal

Frame NAPT as state in the network path: every flow now depends on a box's memory and timers, which is the cost IPv4 scarcity imposes and the argument IPv6 makes against translation.

## Why one-for-one translation is not enough IPv4 has about 4.3 billion addresses, far fewer than the devices that want to reach the internet. Most sites therefore number their hosts from the private blocks of RFC 1918 (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), which are not routed on the public internet. Something at the border has to replace those private addresses with public ones. RFC 3022 ("Traditional NAT") describes two ways to do it: - **Basic NAT** maps each private address to a public address from a pool. It rewrites addresses only, so it still needs one public address for every host that is talking at the same moment. - **NAPT** (Network Address Port Translation) extends the translation to the **transport identifier**: the TCP or UDP port, or the identifier field of an ICMP query such as an Echo Request. Because the port becomes part of what is translated, a single public address can serve a whole site. The industry name for this is **PAT** (Port Address Translation); RFC 2663 and RFC 3022 call it NAPT. ## What a NAPT rewrites | Direction | Fields rewritten | |---|---| | Outbound (inside to outside) | source address, source port (or ICMP query identifier) | | Inbound reply (outside to inside) | destination address, destination port (or ICMP query identifier) | | Both | IP header checksum, and the TCP/UDP checksum | The TCP and UDP checksums must change too, because they cover a **pseudo-header** that contains the source and destination IP addresses, as RFC 3022 section 4.1 points out. ICMP error messages need more work still: they carry a copy of the offending packet's header in their payload, and that embedded copy has to be translated as well. ## One connection, step by step Take a host `10.20.0.15` behind a translator whose public address is `203.0.113.5`, opening a TCP connection to a server at `198.51.100.20:443`: 1. The host sends a SYN from `10.20.0.15:51000` to `198.51.100.20:443`. 2. The translator finds no binding for `(TCP, 10.20.0.15, 51000)`, picks a free external port (say `40001`) and records the binding. 3. It rewrites the source to `203.0.113.5:40001`, adjusts the checksums and forwards the packet. 4. The server answers `203.0.113.5:40001`; it has no way of knowing a private host exists. 5. The translator looks up TCP port `40001` on its public address, finds the binding, rewrites the destination to `10.20.0.15:51000` and forwards the reply inside. 6. Every later packet of the connection reuses the binding and refreshes its idle timer; once the session ends or goes idle long enough, the binding is removed. A second host `10.20.0.16` that also happens to use source port `51000` gets a different external port, say `40002`, so the two conversations stay distinguishable on the outside. ## Choosing the external port A NAPT may try to keep the host's own port (**port preservation**) when it is free, and must pick another when it is not. RFC 4787 REQ-3 forbids what it calls **"port overloading"**: forcing the same external port on two internal endpoints even when they collide, which would make two flows to the same server indistinguishable. REQ-3a also recommends keeping the port's class: a host source port in 0-1023 maps into 0-1023, and one in 1024-65535 stays in that range. RFC 7857 section 9 adds that a NAPT that changes the port SHOULD choose it unpredictably, following RFC 6056, so outsiders cannot guess the next mapping. ## The binding table is the whole mechanism - A binding is created by **outbound** traffic. A packet arriving from outside that matches no binding has no internal host to go to, unless a static rule (port forwarding) names one. - Bindings are **soft state**: they live only as long as traffic or a timer keeps them alive. - In the classic design each binding occupies one external port per transport protocol on the public address, which is what eventually limits how many flows one address can carry. - Applications that write an IP address or port inside their own payload are not fixed by this rewrite, because the translator only touches headers. The model is simple to state and has sharp edges: capacity, idle timeouts and what happens to unsolicited inbound traffic all follow directly from this one table.

  • Why must a NAPT rewrite the TCP or UDP checksum and not just the IP header checksum?
    The TCP and UDP checksums cover a pseudo-header that includes the source and destination IP addresses, and they cover the ports themselves. Changing the address or port invalidates the transport checksum, so the translator adjusts it alongside the IP header checksum, usually incrementally rather than recomputing it over the whole segment (RFC 3022 section 4.1).
  • How does a NAPT translate an ICMP Echo Request, which has no ports?
    It treats the ICMP query identifier like a port. RFC 3022 maps the tuple (private address, query identifier) to (public address, assigned identifier); the responder echoes the identifier back unchanged, so the translator can find the binding and restore the original identifier and address on the Echo Reply.
  • Two internal hosts both send from source port 50000 to the same server address and port. What must the NAPT do?
    Give at least one of them a different external port. On the outside both flows share the public address, server address and server port, so the external source port is the only thing left to tell them apart. RFC 4787 REQ-3 forbids port overloading, which would keep 50000 for both.

A hotel switchboard with one outside number: each outgoing call goes out on a numbered outside line, and the operator's note of which room holds which line is how an answer arriving on that line is put through to the right room.

saying these in an interview costs you the question

  • PAT gives every internal host its own public address from a pool.
  • The translator rewrites only the address; source ports always pass through unchanged.
  • A NAPT finds the internal host for a reply by its MAC address.
  • Two internal hosts can share one external port to the same server address and port because their private addresses differ.
  • One public IPv4 address supports unlimited concurrent flows because ports are reused freely.
open as a page

Why do idle TCP connections and UDP flows through a NAPT break, and what do RFC 4787 and RFC 5382 require of mapping timers?

level: middleimportance: should knowfreq 42%

basics

~20 s

NAPT bindings expire after an idle period, and later packets then find no binding. RFC 4787 forbids UDP timers under two minutes; RFC 5382 forbids established-TCP timers under 2 hours 4 minutes, but many devices use far shorter ones.

open as a page

A NAPT gives 5,000 clients one public IPv4 address; how many concurrent flows can it carry, and what makes it run out of ports?

level: middleimportance: should knowfreq 38%

basics

~20 s

Using ports 1024-65535, one address offers 64,512 external ports per transport protocol, about 13 concurrent bindings per client across 5,000. Churn exhausts it: closed sessions keep their port for minutes, so short-lived connections drain the pool.

open as a page

Why does carrier-grade NAT number the links to subscribers' routers from 100.64.0.0/10 rather than RFC 1918 space, and what changes for subscribers?

level: seniorimportance: should knowfreq 30%

basics

~20 s

RFC 1918 space may already be used inside the subscriber's home, so the provider uses RFC 6598 Shared Address Space, 100.64.0.0/10. Subscribers then share public addresses, lose unsolicited inbound reachability, face per-subscriber port limits and need port-level logs for attribution.

open as a page

Designing a carrier-grade NAT, how would you choose between per-session port allocation, per-subscriber port blocks and fixed port ranges, and how would you size them?

level: principalimportance: nice to knowfreq 14%

basics

~20 s

RFC 6888 asks a carrier-grade NAT's port scheme to maximize port use, minimize log volume and resist guessing; no scheme wins all three: per-session allocation uses ports best, fixed ranges log least, blocks sit between.

open as a page