skip to content

On an IPv6-only mobile network, how do NAT64 and DNS64 together let a phone reach a server that has only an IPv4 address?

level: seniorimportance: must knowfreq 33%

answer

  1. a fabricated AAAA record
  2. IPv4 address inside an IPv6 prefix
  3. 64:ff9b::/96
  4. stateful header rewrite at the border

basics

~20 s

DNS64 answers the phone's AAAA query with a synthetic address that embeds the server's IPv4 address in a NAT64 prefix such as 64:ff9b::/96; the stateful NAT64 translates packets to that address into IPv4 from a shared address pool.

solid answer

~40 s

The phone has only IPv6, so it asks for a AAAA record. A **DNS64** resolver (RFC 6147) tries the real AAAA first; when none exists it fetches the A record and **synthesises** a AAAA by embedding the IPv4 address in a translation prefix — the Well-Known Prefix `64:ff9b::/96` (RFC 6052) or the operator's own. The phone sends ordinary IPv6 to that address, which routes to the **stateful NAT64** (RFC 6146). The NAT64 extracts the IPv4 destination from the address, picks an IPv4 address and port from its pool NAPT-style, records the binding, rewrites the header to IPv4 and sends it on; replies are translated back. Neither the phone nor the server changes — but IPv4 literals, DNSSEC-validating hosts and protocols beyond TCP, UDP and ICMP need extra help.

code

pseudocode · 11 lines
pseudocode
function dns64_answer(name, pref64):          # pref64 = 64:ff9b::/96
    aaaa = resolve(name, AAAA)
    usable = [r for r in aaaa if not excluded(r)]   # e.g. ::ffff:0:0/96
    if usable is not empty:
        return usable                            # real IPv6 wins
    a = resolve(name, A)
    if a is empty:
        return empty_answer
    return [pref64.high_96_bits | r.ipv4 for r in a]

# 192.0.2.33 = c0.00.02.21 -> 64:ff9b::c000:221

go deeper

for a junior

Recall that DNS64 invents an IPv6 address for an IPv4-only name and that NAT64 translates the packets sent to it into IPv4.

for a middle

Trace one connection: AAAA query, fallback to A, synthesis under 64:ff9b::/96, routing to the NAT64, binding and header translation, and the reply path.

for a senior

Name what breaks — IPv4 literals, IPv4-only sockets, host DNSSEC validation, protocols beyond TCP, UDP and ICMP — and how operators handle shared-address logging.

for a principal

Weigh IPv6-only with NAT64 against dual stack for a large client population: IPv4 savings, translator capacity and state, and the share of traffic that will bypass it as AAAA coverage grows.

## The setting Mobile networks are where IPv4 scarcity bites hardest: millions of devices, each wanting connectivity, and too few IPv4 addresses to give each one. Running the radio network **IPv6-only** removes that demand — but much of the internet is still reachable only over IPv4. Two cooperating mechanisms close the gap: - **DNS64** (RFC 6147) — a DNS resolver that fabricates IPv6 answers for IPv4-only names. - **Stateful NAT64** (RFC 6146) — a translator at the network's edge that rewrites IPv6 packets into IPv4 and back, sharing a small pool of IPv4 addresses among many IPv6 clients. RFC 6146 sums up the selling point: used together, they usually need **no changes** to the IPv6 client or the IPv4 server. ## Step by step 1. An app on the phone looks up a name. The phone's stack sends a **AAAA** query to the network's resolver, which is a DNS64. 2. DNS64 first tries to resolve the real AAAA records. If there are none — the normal case for an IPv4-only server — it queries the **A** record. 3. For each A record it builds a **synthetic AAAA**: the translator's prefix followed by the IPv4 address. With the Well-Known Prefix, `192.0.2.33` (RFC 6052's documentation example) becomes `64:ff9b::c000:221`, which may also be written `64:ff9b::192.0.2.33`. 4. The phone opens an ordinary IPv6 connection to that address. The network routes the prefix to the NAT64. 5. The NAT64 reads the IPv4 destination from the last 32 bits, allocates an IPv4 **transport address** from its pool, records the mapping in its **Binding Information Base** and session table, translates the IPv6 header into an IPv4 header and forwards the packet. 6. The server's reply arrives at the pool address; the NAT64 finds the binding, translates the packet back to IPv6 with a source inside the prefix, and delivers it to the phone. ## The address format (RFC 6052) | Element | What it is | |---|---| | Well-Known Prefix | `64:ff9b::/96`, reserved for algorithmic mapping | | Network-Specific Prefix | An operator's own prefix of length 32, 40, 48, 56, 64 or 96 | | Embedded IPv4 | The 32-bit IPv4 address, at a position that depends on the prefix length | The Well-Known Prefix **MUST NOT** represent non-global IPv4 addresses such as RFC 1918 space, and translators MUST drop packets that try; reaching private IPv4 servers through a translator needs a Network-Specific Prefix. DNS64 and NAT64 must use the **same** prefix, or the synthetic answers point nowhere. ## What the NAT64 keeps - **Bindings and sessions** per protocol, with **Endpoint-Independent Mapping**, so it behaves like a well-behaved NAPT and stays compatible with NAT traversal techniques such as ICE. - Only unicast **TCP, UDP and ICMP** are in scope; other protocols are not translated by RFC 6146. - Lifetimes are the RFC's protocol constants: for example UDP_DEFAULT is 5 minutes (UDP_MIN 2 minutes) and TCP_EST is 2 hours, which with the 4-minute TCP_TRANS timer gives an established session at least 2 hours 4 minutes. - Inbound IPv4-initiated connections work only through statically configured bindings. ## What breaks - **IPv4 literals.** An app that connects to `192.0.2.33` directly, or a protocol that carries an IPv4 address in its payload, never asks DNS, so nothing is synthesised and the phone has no IPv4 route. - **IPv4-only sockets.** Software that opens IPv4 sockets has nothing to bind to on an IPv6-only device. - **DNSSEC validation on the host.** A validator unaware of DNS64 may reject the synthetic AAAA as tampered (RFC 6147 §6.2); validation has to happen in the DNS64, or the host must do the synthesis itself. - **Wrong-network answers.** A host that keeps a synthetic AAAA from one network and uses it on another network without that NAT64 reaches nothing. - **Address attribution.** Many subscribers share each pool address, so the translator's logs are needed to say who used it. The first two are what 464XLAT (RFC 6877) adds a device-side translator for. ## Compared with dual stack Dual stack would give every phone an IPv4 address and carry both families end to end. NAT64/DNS64 gives each phone none, shares a small IPv4 pool at the edge, and makes IPv6 the only protocol inside the network — at the price of a stateful translator, shared-address logging and the breakages above. As more destinations publish AAAA records, more traffic bypasses the translator entirely.

  • Why must DNS64 and the NAT64 agree on the prefix?
    DNS64 writes the prefix into every synthetic AAAA, and the network routes that prefix to the NAT64, which strips it to recover the IPv4 destination. If DNS64 uses a prefix the translator does not own, phones send packets that are routed nowhere or dropped, while DNS lookups still appear to succeed.
  • Why can't the operator use 64:ff9b::/96 to reach its own RFC 1918 servers?
    RFC 6052 forbids the Well-Known Prefix for non-global IPv4 addresses and tells translators to drop such packets, because a globally shared prefix must not stand for addresses whose meaning is local. For private IPv4 destinations the operator uses a Network-Specific Prefix taken from its own IPv6 space.

saying these in an interview costs you the question

  • DNS64 synthesises a AAAA even when the name already has a real one.
  • NAT64 tunnels the phone's IPv6 packet to the server inside IPv4.
  • Each phone needs its own IPv4 address for NAT64 to work.
  • A URL containing an IPv4 literal works through DNS64 like any name.
  • 64:ff9b::/96 can reach RFC 1918 servers behind the translator.