# IP, IPv4, and IPv6

## 1. What IP Actually Does

The **Internet Protocol (IP)** is the network-layer protocol (see the OSI model and TCP/IP model topics) responsible for exactly one job: getting a packet from a source host to a destination host, across however many intermediate networks stand between them. It does this using **addresses** — every host that wants to be reachable on a network needs one.

IP itself is **connectionless** and **best-effort**: it does not guarantee a packet arrives, arrives once, or arrives in order. Those guarantees, when needed, are the transport layer's job (TCP — see the TCP vs UDP topic), not IP's. IP's contract is narrower and more honest: "I will try to route this packet toward its destination address using the information available to me right now."

There are two versions of IP in active use today: **IPv4** and **IPv6**. They coexist, but they are not directly compatible — a IPv4-only host cannot natively send a packet to an IPv6-only address, and vice versa.

## 2. IPv4 Addresses

An IPv4 address is **32 bits**, almost universally written in **dotted-decimal notation**: four 8-bit numbers (0-255) separated by dots.

```
192.168.1.10
```

Each of the four numbers is one **octet** (8 bits). Written in binary, that same address is:

```
192       .168      .1        .10
11000000  .10101000 .00000001 .00001010
```

32 bits gives a theoretical address space of 2³² ≈ 4.3 billion addresses. That sounds like a lot, but the internet has more than 4.3 billion connected devices today — this exhaustion is the single biggest reason IPv6 exists (more in the "Under the Hood" section).

### Address classes and private ranges

IPv4 addresses are split into **public** (globally routable on the internet) and **private** (only meaningful inside a private network, never routed on the public internet). Three ranges are reserved for private use (RFC 1918):

```
10.0.0.0    – 10.255.255.255    (10.0.0.0/8)
172.16.0.0  – 172.31.255.255    (172.16.0.0/12)
192.168.0.0 – 192.168.255.255   (192.168.0.0/16)
```

If you check your laptop's local IP address, it's almost certainly in one of these ranges — your home router uses NAT (its own topic) to let many devices on a private range share one public IP.

Two other reserved addresses worth knowing on sight:
- `127.0.0.1` — **loopback**, always refers to "this machine," never leaves the host.
- `0.0.0.0` — means "any address" (a server binding to it listens on all local interfaces) or "unspecified," depending on context.

## 3. IPv6 Addresses

IPv6 addresses are **128 bits** — written as eight groups of four hex digits, separated by colons.

```
2001:0db8:0000:0000:0000:0000:0000:0001
```

![IPv4's 32-bit dotted-decimal address next to IPv6's 128-bit hex address, showing the compression rule](diagrams/01-ipv4-vs-ipv6-address.svg)

128 bits gives 2¹²⁸ addresses — roughly 340 undecillion (340 followed by 36 zeros). That number is intentionally, absurdly large: it's designed to never run out again, even accounting for wasteful allocation practices.

### Compression rules

Writing out sixteen hex digits with seven colons every time is painful, so two shorthand rules exist:

1. **Leading zeros in each group can be dropped.** `0db8` → `db8`.
2. **One contiguous run of all-zero groups can be collapsed to `::`,** but only once per address (if you could do it twice, the address would be ambiguous — you couldn't tell how many zero groups each `::` represents).

```
2001:0db8:0000:0000:0000:0000:0000:0001
  → drop leading zeros:  2001:db8:0:0:0:0:0:1
  → collapse zero run:   2001:db8::1
```

```
0000:0000:0000:0000:0000:0000:0000:0001  →  ::1        (this is IPv6's loopback address)
0000:0000:0000:0000:0000:0000:0000:0000  →  ::         (this is IPv6's "unspecified" address)
```

### IPv6 address types worth knowing

- **Global unicast** — publicly routable, IPv6's equivalent of a public IPv4 address (typically starts `2000::/3`).
- **Link-local** — always starts `fe80::/10`, auto-assigned to every interface, only valid on the local network segment (used heavily for things like router discovery — never routed beyond the local link).
- **Unique local** — starts `fc00::/7`, IPv6's rough equivalent of private IPv4 ranges (not routed on the public internet).

## 4. Why IPv6 Exists (Beyond "More Addresses")

Address exhaustion is the headline reason, but IPv6 also cleans up several IPv4 design issues:

- **No more built-in NAT dependency.** IPv4 exhaustion forced NAT (its own topic) to become mandatory just to make private networks work; IPv6 has enough addresses that every device can get a real, globally unique address again, restoring true end-to-end connectivity (though NAT-like techniques still exist for other reasons, like privacy or firewalling).
- **Simpler header.** The IPv6 header is fixed-size and simpler to process than IPv4's variable-length header with optional fields, which helps routers process packets faster.
- **No header checksum.** IPv4 headers carry a checksum that every router must recompute at every hop (since fields like TTL change per hop); IPv6 drops this, relying on lower layers (link layer) and upper layers (TCP/UDP) for error detection instead.
- **Built-in address autoconfiguration.** IPv6 hosts can self-assign a valid address (SLAAC — Stateless Address Autoconfiguration) without needing DHCP (its own topic), by combining a network prefix advertised by a router with a locally generated interface identifier.

## 5. Public vs Private Addresses, and NAT's Role

A private IPv4 address (like `192.168.1.10`) only makes sense inside its own local network — no router on the public internet knows how to route to it, and in fact many networks reuse the exact same private ranges independently (your home network and your neighbor's home network can both use `192.168.1.10` for a different device, with zero conflict, because neither address is ever visible outside its own network).

To reach the public internet, a private address is translated to a public one at the network's edge — this translation is **NAT**, covered in depth in the NAT/DHCP/ARP topic. IPv6's abundant address space removes the *forcing function* for NAT (there's no shortage requiring address sharing), but doesn't eliminate every use of NAT-like techniques.

## 6. Under the Hood

### IPv4 exhaustion, concretely

IPv4's 32-bit space was carved up early using wasteful "class-based" allocations (entire /8 blocks — 16.7 million addresses each — handed to single organizations). By the 1990s it was clear this would run out, which is why:
1. **CIDR** (Classless Inter-Domain Routing — its own topic) replaced rigid address classes with flexible, variable-length prefixes, slowing exhaustion by allocating exactly as many addresses as needed instead of oversized fixed blocks.
2. **NAT** let entire private networks share one public address, further slowing exhaustion.
3. IANA still fully allocated the last free top-level IPv4 blocks to regional registries in 2011. IPv4 address space today is a scarce, actively traded resource — companies buy and sell IPv4 blocks for real money because there simply aren't more being created.

IPv6 doesn't patch this problem — it sidesteps it entirely with an address space so large that even extremely wasteful allocation (handing out a `/64` — 2⁶⁴ addresses, more than the entire IPv4 space — to a single home network, which is standard practice) still leaves the space effectively inexhaustible.

### Dual-stack and the transition mechanism

Because IPv4 and IPv6 packets are structurally different and neither host understands the other's addressing, the internet cannot flip a switch from one to the other — both must run side by side indefinitely. This coexistence strategy is called **dual-stack**: a host, router, or server keeps both an IPv4 and an IPv6 address/route simultaneously, and picks whichever protocol the other end of a connection also supports. When you resolve a hostname today (see DNS in a later topic), you often get back both an `A` record (IPv4 address) and an `AAAA` record (IPv6 address) — the OS chooses which to actually connect with, generally preferring IPv6 when both work end-to-end.

Where dual-stack isn't available end-to-end, transition mechanisms like **NAT64** (translating between IPv6-only clients and IPv4-only servers) and **tunneling** (encapsulating IPv6 packets inside IPv4 ones, or vice versa, to cross a network that only understands one) bridge the gap — these exist purely because the two protocols cannot speak to each other natively.

### Why the header actually got simpler

The IPv4 header has a variable length (with an "Options" field that's rarely used but that every router must still be prepared to parse) and includes a header checksum that must be recalculated at every single router hop, because the Time-To-Live (TTL) field decrements at each hop, changing the header's contents. Recomputing a checksum on every packet at every hop is real, non-trivial CPU work multiplied across billions of packets per second in core routers.

IPv6 fixes the header at a constant 40 bytes, removes the checksum entirely (trusting the link layer's own error detection, plus TCP/UDP's own checksums, to catch corruption), and moves rarely-used fields into optional "extension headers" that most routers can skip over entirely without parsing. The result: less per-packet, per-hop work in the routers that matter most for internet-scale throughput.

## 7. Common Pitfalls

1. **Treating `192.168.x.x` as "the" private range** — there are three separate RFC 1918 ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`); assuming only `192.168.x.x` is private leads to misconfigured firewall rules that let unintended "private-looking" traffic through.
2. **Assuming an IPv6 address with `::` in it is missing information** — `::` is a lossless compression of a run of zero groups, not an indication of a partial or unknown address; `2001:db8::1` and `2001:db8:0:0:0:0:0:1` are the exact same address.
3. **Trying to use `::` twice in one address** — this is invalid and ambiguous (the parser can't tell how many zero groups each `::` stands for); RFC 5952 mandates at most one `::` per address.
4. **Assuming NAT is a security feature** — NAT exists to conserve addresses, not to secure a network; the fact that unsolicited inbound connections can't reach a NAT'd private address is a side effect of NAT's translation table (explained in the NAT/DHCP/ARP topic), not a designed firewall — a real firewall enforces policy on purpose, NAT just happens to make certain traffic patterns impossible.
5. **Believing IPv6 adoption means IPv4 is going away soon** — the two protocols have coexisted via dual-stack for over two decades and will continue to for the foreseeable future; large parts of the internet's infrastructure and countless private networks remain IPv4-only or IPv4-primary.
6. **Confusing a private IPv4 address with a loopback or link-local address** — `192.168.1.5` (private, routable within its LAN), `127.0.0.1` (loopback, never leaves the host), and `fe80::1` (IPv6 link-local, never leaves the local link) all serve different, non-interchangeable purposes.

## 8. Quick Reference

```
IPv4: 32 bits, dotted-decimal (192.168.1.10)
  Private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
  Loopback: 127.0.0.1     Unspecified: 0.0.0.0
  Total space: ~4.3 billion addresses (exhausted at the registry level since 2011)

IPv6: 128 bits, hex groups (2001:0db8:0000:...:0001)
  Compression: drop leading zeros per group, collapse ONE run of zero groups to "::"
  Loopback: ::1            Unspecified: ::
  Link-local: fe80::/10    Unique local (private-ish): fc00::/7
  Total space: ~340 undecillion addresses

Coexistence: dual-stack (both protocols side by side) + NAT64/tunneling where needed
Neither protocol guarantees delivery — that's the transport layer's job (TCP/UDP)
```
