The idea: the same job, two versions of IP

IPv4 and IPv6 do the same job: they carry a packet from one host to another across many routers. They differ in the size of an address (32 bits vs 128 bits) and in what that size forces around them. IPv4 ran out of addresses, so a home gets one public address and hides its devices behind NAT. IPv6 has enough for every device to have its own global address, so there is no NAT, and the header was cleaned up while it was being redesigned. This page runs the same laptop, the same home router, the same ISP router and the same server on both, one step of each lane at a time.

Left, IPv4: a laptop 192.168.1.10, a phone 192.168.1.11 and a TV 192.168.1.12 sit behind a home router with NAT and one public address 203.0.113.7; the server sees only 203.0.113.7. Right, IPv6: the same three devices each have a global address in 2001:db8:1:2::/64; the router only routes and filters, and the server sees each device's own address.
IPv4: the whole home shares one public address and the router rewrites every packet. IPv6: each device has its own global address and the router only forwards and filters.

IPv4: 32-bit addresses, DHCP and NAT

An IPv4 address is 32 bits, written as four bytes: 192.168.1.10. That gives about 4.3 billion addresses, fewer than the devices online. A home network uses a private range (RFC 1918: 10/8, 172.16/12, 192.168/16). A DHCP server in the router hands the addresses out with four messages (DISCOVER, OFFER, REQUEST, ACK) and keeps a lease row for each device (Demo: home network gets an address).

Private addresses cannot be used on the Internet, so the home router does NAT: on the way out it replaces the source 192.168.1.10:51000 with its own public 203.0.113.7:40001 and remembers the pair; on the way back it puts the private address back (Demo: laptop talks to a server). Nothing outside can start a connection to the laptop, because 203.0.113.7 stands for the whole home (Demo: outside host connects in).

IPv6: 128-bit addresses and SLAAC

An IPv6 address is 128 bits, written as eight groups of 16 bits in hex, with one run of zero groups shortened to ::: 2001:db8:1:2:11:22ff:fe33:4455. The first 64 bits are the network's prefix; a home typically gets a whole /64 or more, so the last 64 bits can be anything the host picks.

With SLAAC (stateless address autoconfiguration, RFC 4862) the host builds its own address. It asks with a Router Solicitation, the router answers with a Router Advertisement carrying the prefix, and the host adds an interface ID. Before using the address it runs Duplicate Address Detection: a Neighbor Solicitation for the new address; if nobody answers, it is unique. The router stores nothing about the host.

The 64-bit prefix 2001:db8:1:2 from the Router Advertisement plus the 64-bit interface ID made from the MAC 02:11:22:33:44:55: split in half, ff:fe inserted, and bit 7 of the first byte flipped from 02 to 00, giving 0011:22ff:fe33:4455. Together: 2001:db8:1:2:11:22ff:fe33:4455.
SLAAC: the router supplies the first 64 bits, the host makes the last 64 itself (here EUI-64 from its MAC address).

EUI-64 puts the MAC address into every address the laptop uses, so it can be tracked from network to network. Modern systems use a random-looking but stable interface ID instead (RFC 7217) and add short-lived temporary addresses for outgoing connections (RFC 8981).

The headers, field by field

The IPv6 header is twice as long, because the two addresses alone take 32 bytes. But it has fewer fields and a fixed size (Demo: header layouts):

IPv4 (20 bytes + options)IPv6 (40 bytes, fixed)What changed
Version 4Version 6same place, so a receiver can tell them apart
IHL (header length)—removed: the header is always 40 bytes
DSCP / ECNTraffic classrenamed, same use
—Flow label (20 bits)new: marks the packets of one flow, used for load balancing
Total lengthPayload lengthcounts only what follows the header
Identification, Flags, Fragment offset—moved to a Fragment extension header, used only when the source fragments
TTLHop limitrenamed; it always counted hops, not seconds
ProtocolNext headeralso chains extension headers (44 = Fragment, 58 = ICMPv6)
Header checksum—removed (see below)
Source, Destination: 32 bitsSource, Destination: 128 bits4 times as long
Options (0–40 bytes)extension headerschained after the header, skipped by most routers

No header checksum

Every IPv4 router decrements TTL, so the header changes, so every router must recompute the header checksum (a 16-bit one's-complement sum of the header). IPv6 dropped it: Ethernet and Wi-Fi already check each frame with a CRC, and TCP and UDP checksum their data together with the addresses. An IPv6 router only decrements Hop limit. In Demo: laptop talks to a server the IPv4 routers rewrite 12 fields, 4 of them checksums; the IPv6 routers rewrite 4 Hop limits. (Because of this, UDP's checksum, optional over IPv4, is mandatory over IPv6.) See How a Router Forwards a Packet for the rest of a router's work.

Fragmentation: routers vs the source

Each link has an MTU, the largest packet it carries. When a 1500-byte IPv4 packet with DF = 0 meets a 1400-byte link, the router splits it into fragments, each with its own header, and the destination puts them back together. IPv6 routers never fragment. They drop the packet and send ICMPv6 Packet Too Big with the MTU back to the source, which remembers the path MTU and sends smaller packets, or fragments them itself with a Fragment header (Demo: 1500 B over an MTU 1400 link).

Time runs down. IPv4: the laptop sends 1500 bytes, the router before the 1400-byte link splits it into 1396 and 124 bytes and both reach the server. IPv6: the router drops the 1500-byte packet and sends Packet Too Big (MTU 1400) back; the laptop resends as 1400 and 156 bytes, which reach the server one round trip later.
IPv4 lets the router fragment on the way; IPv6 sends the job back to the source, one round trip later.

This only works if Packet Too Big gets through. A firewall that drops all ICMPv6 creates a black hole: small packets work and big ones vanish with no error (Demo: ICMPv6 blocked). RFC 4890 lists the ICMPv6 types a firewall must let through. IPv4 has the same trap whenever DF = 1, which is how TCP sends.

Side by side

IPv4IPv6
Address32 bits, about 4.3 × 10⁹128 bits, about 3.4 × 10³⁸
Header20–60 bytes, 13 fields40 bytes, 8 fields
Getting an addressDHCP (4 messages, lease in the server)SLAAC (RS, RA, DAD; no state), or DHCPv6
Finding a neighbour's MACARP broadcastNeighbor Discovery over ICMPv6 multicast
Home networkprivate addresses + NATglobal addresses + a stateful firewall
Incoming connectionsneed port forwardingreach the device if the firewall allows
Fragmentationby any router (if DF = 0)only by the source
Header checksumrecomputed at every hopnone
Minimum MTU68 bytes (576 to reassemble)1280 bytes

Common mistakes

  • "NAT is a firewall." NAT blocks unsolicited traffic only as a side effect of not knowing where to send it. An IPv6 home router needs a real stateful firewall that blocks unsolicited traffic by default, as RFC 6092 recommends.
  • "IPv6 is faster because the header is simpler." Hardware routes both at line rate. The gain is less work and no NAT state, not speed you can measure on one packet.
  • Blocking all ICMPv6. It breaks path MTU discovery and Neighbor Discovery, so IPv6 stops working in confusing ways.
  • Reading the 40-byte header as overhead that doubles. It is 20 more bytes per packet: about 1.3% of a 1500-byte packet.

See also How NAT Shares One Public Address, How a Device Gets an IP Address, How ARP Finds a MAC Address and How a Router Forwards a Packet.

What the page leaves out

The page has one laptop, two routers and one server, and both lanes run the same scenario. It leaves out DHCPv6 and prefix delegation (how the home router gets its /64 from the ISP), privacy and stable addresses, link-local scopes and zone IDs, multicast and Neighbor Discovery beyond DAD, extension headers other than Fragment, IPv4 options, and the ways the two versions live together: dual stack, Happy Eyeballs, NAT64/DNS64, 464XLAT and tunnels.