24.0 What this chapter gives you#
- You will be able to say exactly what an IP address labels, and why it is not
a label for a device and not a label for a person.
- You will be able to convert any IPv4 address to binary by hand, and back
again, without a calculator.
- You will be able to read a CIDR prefix such as
/24 or /12 and work out
the network address, the broadcast address, the first and last usable host,
and the exact host count.
- You will be able to look at any address and say instantly whether it is
public, private, loopback, link-local, multicast, or something special, and
name the RFC that says so.
- You will be able to explain why every home near you can use 192.168.0.1 at
the same time without anything colliding.
- You will be able to describe NAT precisely: what the translation table holds,
what source NAT and destination NAT are, and what your home router really
does, which is PAT.
- You will be able to explain what a port is, why NAT would be impossible
without ports, and what the real limit on simultaneous connections is.
- You will be able to say what NAT breaks, why peer-to-peer software needs
STUN, TURN and ICE, and why NAT is honestly a workaround rather than a
design.
- You will be able to read the reader’s own traceroute, hop by hop, and say
what the private addresses at hops 2 to 6 do and do not prove about
carrier-grade NAT.
- You will be able to run the exact macOS commands that reveal your address,
your gateway, your mask and your public address, and decide in under a
minute whether you are behind carrier-grade NAT.
24.1 What an IP address is#
PLAIN24.1.1 in simple words#
- An IP address is a label. It says where to deliver something on a network.
- The thing it labels is a network interface: one connection point, one way
in and out of a machine.
- It does not label the machine. A machine can have many connection points.
- Your laptop has a Wi-Fi radio. That is one interface. It has an Ethernet
socket. That is another. Each gets its own address.
- If you turn on a VPN, the operating system makes a pretend interface in
software. That gets an address too.
- The reader’s own macOS machine showed several interfaces named
utun. Those
are software tunnels. Each one can carry its own address.
- So the question “what is my IP address” has no single answer. The honest
answer is “which interface, and seen from where”.
- An IP address also does not label a person. It labels a doorway. Many people
can walk through the same doorway.
- Addresses are borrowed, not owned. Most home machines are given an address
for a while and handed a different one later.
PLAIN24.1.2 a picture in your head#
- Think of a large office building with several entrances.
- The building has a main street entrance, a loading bay at the back, and a
staff door at the side.
- Each entrance has its own number painted above it. Deliveries come to the
number that matches the entrance.
- The number is not the name of the company inside. The company could move out
tomorrow and a different one moves in, keeping the same painted number.
- The number is not the name of any person inside either. Hundreds of people
use the same doorway every day.
- If the building opens a new temporary door for a festival, that door gets its
own number for the week. That is what a VPN interface is like.
Where this comparison breaks: painted door numbers are stable for decades and
tied to a physical place you can walk to. IP addresses are handed out for hours
or days, can be moved between cities in minutes, and one address can be served
by machines on three continents at once. A door number also cannot be shared by
a thousand separate buildings at the same time, which is exactly what private
addresses do.
PLAIN24.1.3 a worked example#
- An IPv4 address is 32 switches in a row. Each switch is on or off, 1 or 0.
- Writing 32 ones and zeros is horrible for humans, so we chop them into four
groups of 8 and write each group as an ordinary number.
- A group of 8 bits can hold 0 to 255. That is why every part of an address
stays between 0 and 255.
- The four numbers are written with dots between them. That is called dotted
quad notation.
- Let us convert the reader’s own router address, 192.168.0.1, by hand.
- Each of the 8 bits has a value. From left to right they are 128, 64, 32, 16,
8, 4, 2, 1. You take the biggest value that fits, subtract, and repeat.
| Part |
Working |
Binary |
| 192 |
128 + 64 |
11000000 |
| 168 |
128 + 32 + 8 |
10101000 |
| 0 |
nothing |
00000000 |
| 1 |
1 |
00000001 |
- So 192.168.0.1 in full is:
11000000 10101000 00000000 00000001
- Now the address the reader’s machine got for github.com, 20.207.73.82.
| Part |
Working |
Binary |
| 20 |
16 + 4 |
00010100 |
| 207 |
128+64+8+4+2+1 |
11001111 |
| 73 |
64 + 8 + 1 |
01001001 |
| 82 |
64 + 16 + 2 |
01010010 |
- So 20.207.73.82 in full is:
00010100 11001111 01001001 01010010
- Going backwards is just addition. Take 11001111, add up the columns that
hold a 1: 128 + 64 + 8 + 4 + 2 + 1 = 207.
- There are 32 bits, so there are 2 multiplied by itself 32 times possible
addresses. That is 4,294,967,296, usually said as about 4.29 billion.
PLAIN24.1.4 what is really happening inside#
- When your machine sends data, it wraps it in a small header, like an address
label stuck on a parcel.
- Inside that header are two fixed slots: 32 bits for where it came from, and
32 bits for where it is going.
- The dots are not in the header. The dots exist only on paper and on screens
for humans. On the wire it is 32 raw bits and nothing else.
- Every router that touches the parcel reads the destination slot, looks it up
in a table, and decides which cable to push it down next.
- The router does not open the parcel. It does not care what is inside. It
reads the label and forwards.
- The source slot matters for the reply. Without it the far end would have no
idea where to send anything back.
- This is why a wrong source address is a real problem. If a machine lies about
where it came from, replies go to the wrong place. That is called spoofing.
- Your machine keeps a small list of its own interfaces and the address on
each. When you open a connection, it picks the interface that can reach the
destination and stamps that interface’s address as the source.
TECHNICAL24.1.5 the engineer’s version#
- IPv4 is specified in RFC 791, published September 1981, by Jon Postel at the
Information Sciences Institute. It is Internet Standard STD 5.
- The address is a 32-bit unsigned integer carried in network byte order,
which means big-endian, most significant byte first.
- In a standard 20-byte IPv4 header, the source address occupies bytes 12 to
15 and the destination address occupies bytes 16 to 19, counting from zero.
- Dotted quad notation is a presentation convention, not part of the protocol.
RFC 791 itself writes addresses that way, but the wire format has no
separators.
- The same address has several equally valid written forms.
| Form |
192.168.0.1 |
20.207.73.82 |
| Dotted quad |
192.168.0.1 |
20.207.73.82 |
| Decimal integer |
3232235521 |
349129042 |
| Hexadecimal |
c0a80001 |
14cf4952 |
| Old class |
C |
A |
- The total space is 2 to the power 32, exactly 4,294,967,296 addresses. Not
all of them are usable, as section 24.4 shows.
- An interface may hold more than one address. On Linux this is normal and
unlimited in practice. On macOS you add extra addresses with
ifconfig en0 alias.
- Loopback is an interface too, normally
lo0 on macOS and lo on Linux,
carrying 127.0.0.1.
- Tunnel interfaces created by VPN software on macOS appear as
utun0,
utun1 and so on. The reader’s session showed several. Each can carry its
own address and its own routes, which is exactly why a VPN can change which
address the world sees without changing your Wi-Fi address at all.
- Commands that observe this:
ifconfig -a, ipconfig getifaddr en0,
networksetup -listallhardwareports on macOS; ip -4 addr show on Linux.
ipconfig getifaddr en0 # just the IPv4 address of Wi-Fi
ifconfig en0 | grep 'inet ' # address, netmask, broadcast
ifconfig -a | grep utun # the VPN tunnel interfaces
WORDS24.1.6 remember these#
- IP address — a delivery label for one connection point — a 32-bit unsigned
integer in the IPv4 header, bytes 12 to 15 and 16 to 19.
- Interface — one way in or out of a machine — a network endpoint, physical or
virtual, that can hold addresses and routes.
- Dotted quad — writing an address as four numbers with dots — the
presentation format for a 32-bit IPv4 address, one decimal octet per byte.
- Octet — one of the four numbers, 0 to 255 — an 8-bit field; the term is used
instead of “byte” because early machines had bytes of other sizes.
- Big-endian — biggest part written first — network byte order, the byte
ordering all IP header fields use.
- Spoofing — lying about where a packet came from — forging the source address
field, mitigated by ingress filtering as described in BCP 38.
24.2 Networks and hosts: the split, the mask and CIDR#
PLAIN24.2.1 in simple words#
- An IP address is really two facts glued together.
- The left part says which network you are on. The right part says which
machine you are within that network.
- The glue point is not fixed. It can sit anywhere along the 32 bits.
- Something has to say where the split is. That something is the subnet
mask.
- A mask is another 32-bit pattern. Every 1 in it means “this bit belongs to
the network part”. Every 0 means “this bit belongs to the machine part”.
- The ones always come first and never have gaps. So a mask is fully described
by counting them.
- Counting them is the whole idea of CIDR notation. You write a slash and the
number of network bits.
/24 means the first 24 bits are network.
- So 192.168.0.1/24 means: the network is the first 24 bits, and 8 bits are
left over to number machines.
- Two addresses are on the same network when their network parts match. That
single fact decides whether your machine talks to something directly or
hands it to the router.
PLAIN24.2.2 a picture in your head#
- Think of a phone number written as an area code plus a local number.
- The area code says which town. The local number says which phone in that
town.
- If you are calling someone in your own town, you dial the local part only.
You do not need the area code.
- If they are in a different town, you dial the whole thing, and the call goes
through the long-distance exchange first.
- Your machine does the same test. Same network part means “shout directly
down the wire”. Different network part means “give it to the router”.
- The router is the long-distance exchange. It is the only way out.
Where this comparison breaks: phone area codes are a fixed number of digits and
map to real geography. A CIDR prefix can be any number of bits from 0 to 32, and
it maps to whoever was allocated it, which can be a company with offices in ten
countries. Phone numbers also have no equivalent of the broadcast address, and
no equivalent of a mask you can change on your own equipment.
PLAIN24.2.3 a worked example#
- Take the reader’s own home network, written as 192.168.0.0/24.
/24 means the first 24 bits are the network. In binary:
address 192.168.0.1 11000000 10101000 00000000 00000001
mask /24 11111111 11111111 11111111 00000000
|------ network -----------|- host -|
- The network address is what you get when every host bit is 0. Here the
last 8 bits go to zero, giving 192.168.0.0.
- The broadcast address is what you get when every host bit is 1. The last
8 bits become 11111111, which is 255, giving 192.168.0.255.
- The first usable host is the network address plus one: 192.168.0.1. That is
the reader’s router.
- The last usable host is the broadcast address minus one: 192.168.0.254.
- The total addresses are 2 to the power 8, which is 256. Two are reserved for
network and broadcast, so 254 machines can be numbered.
- Now take 137.97.0.0/16, the classical block containing the reader’s hop 3 at
137.97.29.249.
/16 means the first 16 bits are the network, so the whole last two octets
are host bits.
| Item |
192.168.0.0/24 |
137.97.0.0/16 |
| Mask |
255.255.255.0 |
255.255.0.0 |
| Network address |
192.168.0.0 |
137.97.0.0 |
| Broadcast |
192.168.0.255 |
137.97.255.255 |
| First usable |
192.168.0.1 |
137.97.0.1 |
| Last usable |
192.168.0.254 |
137.97.255.254 |
| Total addresses |
256 |
65,536 |
| Usable hosts |
254 |
65,534 |
- Check that 137.97.29.249 really falls inside 137.97.0.0/16. Compare the
first 16 bits: 137.97 matches 137.97. It does.
- Honest note: 137.97.0.0/16 is the historical block boundary. We are using it
as a clean worked example. The actual prefix the reader’s ISP announces to
the internet could be smaller, such as a /19 or /22, carved out of it. The
arithmetic is the same either way.
PLAIN24.2.4 what is really happening inside#
- When your machine wants to send to some address, it does one calculation
first, and it does it for every single packet.
- It takes the destination address and lines it up with its own mask.
- It performs a bitwise AND. That means: for each bit position, the answer is
1 only if both are 1.
- ANDing an address with its mask wipes out the host bits and leaves the
network number.
- It does the same to its own address, and compares the two results.
- If they match, the destination is a neighbour. The machine finds the
neighbour’s hardware address and sends the frame straight to it.
- If they do not match, the destination is elsewhere. The machine sends the
frame to the router instead, using the router’s hardware address but keeping
the far-away destination IP inside.
- Worked through: the reader’s laptop wants 20.207.73.82.
- 20.207.73.82 AND 255.255.255.0 gives 20.207.73.0.
- The laptop’s own 192.168.0.x AND 255.255.255.0 gives 192.168.0.0.
- They differ, so the packet goes to 192.168.0.1, the router. This is the
exact reason hop 1 of the reader’s trace is the router.
- The router then repeats the same test against its own, much larger, table.
TECHNICAL24.2.5 the engineer’s version#
- CIDR, Classless Inter-Domain Routing, is defined in RFC 4632, August 2006,
which is BCP 122. It obsoletes RFC 1519 and RFC 1518, both published in
September 1993.
- A prefix is written
address/length. The length is the count of leading 1
bits in the mask. Masks must be contiguous; discontiguous masks were legal
in some ancient equipment and are not permitted now.
- The number of addresses in a prefix of length n is 2 to the power (32 - n).
- Usable host count is that minus 2 for any prefix shorter than /31, because
the all-zeros and all-ones host patterns are the network identifier and the
directed broadcast.
- RFC 3021, December 2000, permits /31 on point-to-point links, where both
addresses are usable and there is no broadcast. Service provider backbones
use /31 heavily to save address space.
- A /32 is a single host route, used for loopbacks on routers and for
advertising one address.
- Full reference table, /8 to /32:
| Prefix |
Mask |
Addresses |
Usable hosts |
| /8 |
255.0.0.0 |
16,777,216 |
16,777,214 |
| /9 |
255.128.0.0 |
8,388,608 |
8,388,606 |
| /10 |
255.192.0.0 |
4,194,304 |
4,194,302 |
| /11 |
255.224.0.0 |
2,097,152 |
2,097,150 |
| /12 |
255.240.0.0 |
1,048,576 |
1,048,574 |
| /13 |
255.248.0.0 |
524,288 |
524,286 |
| /14 |
255.252.0.0 |
262,144 |
262,142 |
| /15 |
255.254.0.0 |
131,072 |
131,070 |
| /16 |
255.255.0.0 |
65,536 |
65,534 |
| /17 |
255.255.128.0 |
32,768 |
32,766 |
| /18 |
255.255.192.0 |
16,384 |
16,382 |
| /19 |
255.255.224.0 |
8,192 |
8,190 |
| /20 |
255.255.240.0 |
4,096 |
4,094 |
| /21 |
255.255.248.0 |
2,048 |
2,046 |
| /22 |
255.255.252.0 |
1,024 |
1,022 |
| /23 |
255.255.254.0 |
512 |
510 |
| /24 |
255.255.255.0 |
256 |
254 |
| /25 |
255.255.255.128 |
128 |
126 |
| /26 |
255.255.255.192 |
64 |
62 |
| /27 |
255.255.255.224 |
32 |
30 |
| /28 |
255.255.255.240 |
16 |
14 |
| /29 |
255.255.255.248 |
8 |
6 |
| /30 |
255.255.255.252 |
4 |
2 |
| /31 |
255.255.255.254 |
2 |
2 point-to-point |
| /32 |
255.255.255.255 |
1 |
1 host route |
- Routers select a next hop by longest prefix match: among all routes that
contain the destination, the one with the most network bits wins. A /24 beats
a /16 which beats the default route 0.0.0.0/0.
- VLSM, Variable Length Subnet Masking, means different prefix lengths inside
one organization. It became possible once routing protocols carried the mask
with the prefix, which OSPF and BGP-4 do and RIP version 1 did not.
- Aggregation is the point of CIDR: an ISP holding 137.97.0.0/16 announces one
route to the world instead of 256 separate /24 routes. Without this the
global routing table would have collapsed under its own size in the 1990s.
- Observation commands:
ipcalc 192.168.0.0/24, sipcalc, netstat -rn on
macOS to see the routing table, route -n get 20.207.73.82 to ask macOS
which route and gateway it would pick for one destination.
route -n get 20.207.73.82
# route to: 20.207.73.82
# destination: default
# gateway: 192.168.0.1
# interface: en0
WORDS24.2.6 remember these#
- Subnet mask — the pattern saying which part is the network — a 32-bit value
of contiguous 1 bits followed by 0 bits, ANDed with an address.
- CIDR notation — the slash number — prefix length in bits, defined in RFC
4632, replacing the class system.
- Network address — the address with all host bits 0 — the prefix identifier,
not assignable to a host.
- Broadcast address — the address with all host bits 1 — the directed
broadcast for that subnet, per RFC 919.
- Bitwise AND — keep only bits that are 1 in both — the masking operation used
for every local-versus-remote forwarding decision.
- Longest prefix match — the most specific route wins — the forwarding rule
that picks the entry with the greatest prefix length.
- VLSM — different sized subnets in one network — variable length subnet
masking, requires classless routing protocols.
- Aggregation — announcing one big block instead of many small ones — route
summarization, the mechanism that keeps the global BGP table finite.
24.3 Public and private addresses#
PLAIN24.3.1 in simple words#
- Some addresses are meant for the open internet. Anyone anywhere can reach
them. Those are public addresses.
- Some addresses are set aside for use inside one building or one home. Those
are private addresses.
- A private address only means something inside its own network. Outside, it
means nothing.
- Three blocks of addresses were reserved for private use in 1996, in a
document called RFC 1918.
- The three blocks are: everything starting 10, a range starting 172.16 up to
172.31, and everything starting 192.168.
- The reader’s router is 192.168.0.1. That is in the third block. So is almost
every home router in the world.
- Your neighbour’s router is very likely also 192.168.0.1 or 192.168.1.1. That
causes no problem at all.
- It causes no problem because private addresses never travel on the public
internet. Routers out there refuse to carry them.
- So the two 192.168.0.1 addresses never meet. They live in separate sealed
worlds.
- Something must translate between the sealed world and the open one. That
something is NAT, and it is section 24.6.
PLAIN24.3.2 a picture in your head#
- Think of the extension numbers in an office phone system.
- Inside the office you dial 101 and reach reception. Extension 101 exists in
that office and nowhere else.
- Every office in the city has an extension 101. There is no clash, because you
cannot dial an extension from outside.
- From outside you dial the single main number of the building. Only that
number is listed publicly.
- The main number is the public address. The extensions are the private
addresses.
- The switchboard is the router doing NAT. It is the only thing that knows both
worlds.
Where this comparison breaks: a human switchboard operator can put an incoming
call through to any extension on request. A home router cannot do that by
default. Nobody outside can ask for an extension, because the router has no idea
which internal machine an unexpected incoming packet is meant for. That single
difference is the source of most of the pain in section 24.8.
PLAIN24.3.3 a worked example#
- Here are the three private blocks with their exact boundaries.
| Block |
Range |
Addresses |
| 10.0.0.0/8 |
10.0.0.0 to 10.255.255.255 |
16,777,216 |
| 172.16.0.0/12 |
172.16.0.0 to 172.31.255.255 |
1,048,576 |
| 192.168.0.0/16 |
192.168.0.0 to 192.168.255.255 |
65,536 |
- The middle one confuses people, so let us prove its range.
- 172.16.0.0/12 fixes the first 12 bits. The first octet, 172, uses 8 of them.
That leaves 4 more, taken from the second octet.
- In binary, 172 is 10101100. The second octet 16 is 00010000. The first four
bits of the second octet are 0001, and those are frozen.
- The remaining four bits of the second octet are free. They range from 0000 to
1111. So the second octet runs from 00010000 to 00011111, which is 16 to 31.
- Therefore the block covers 172.16.x.x all the way to 172.31.x.x. It does not
cover 172.32.x.x, and it does not cover 172.15.x.x.
- Now apply that to the reader’s own traceroute. Hops 2 to 6 were:
2 172.31.0.17
3 137.97.29.249
4 172.26.22.235
5 172.16.18.33 / 172.26.14.75 / 172.26.22.234
6 172.26.14.75 / 172.16.18.33
- 172.31.0.17 has second octet 31. That is inside 16 to 31. Private.
- 172.26.22.235, 172.26.14.75 and 172.26.22.234 all have second octet 26.
Inside 16 to 31. Private.
- 172.16.18.33 has second octet 16, the very bottom edge of the block.
Private.
- 137.97.29.249 is not in any private block. 137 is not 10, not 172, not 192.
Public.
- So of the reader’s first six hops, five are private and one is public. That
single fact is the whole story of section 24.9.
PLAIN24.3.4 what is really happening inside#
- There is nothing physically different about a private address. The bits look
the same as any other bits.
- The difference is entirely an agreement. Everyone agreed not to give these
blocks to anybody as public addresses, and agreed that routers on the public
internet would not carry them.
- Two mechanisms enforce it. First, the address registries never allocate these
blocks to anyone. Second, network operators filter them.
- Filtering means a router is configured with a rule: if a route for
192.168.0.0/16 arrives from a neighbour, discard it. If a packet with a
private source arrives from outside, drop it.
- Those unwanted routes and packets are called bogons, short for bogus.
- So a packet with source 192.168.0.24 sent onto the open internet would either
be dropped, or would arrive somewhere and generate a reply that could never
find its way home.
- That is why the translation in NAT is not optional. A private address must be
swapped for a public one before it leaves.
- Inside a network, private addresses behave exactly like public ones. Routing,
masks, broadcasts, all identical. Only the outside world treats them
differently.
- Large organizations use 10.0.0.0/8 precisely because it is huge: 16.7 million
addresses, enough for a national telecom network’s internal plumbing.
TECHNICAL24.3.5 the engineer’s version#
- RFC 1918, “Address Allocation for Private Internets”, February 1996, is
BCP 5. Authors include Yakov Rekhter and Robert Moskowitz. It updated the
earlier RFC 1597 from March 1994.
- The three blocks and their historical classful description:
| Prefix |
RFC 1918 name |
Old class equivalent |
| 10.0.0.0/8 |
24-bit block |
one class A network |
| 172.16.0.0/12 |
20-bit block |
16 class B networks |
| 192.168.0.0/16 |
16-bit block |
256 class C networks |
- RFC 1918 hosts are described in the document as being in one of three
categories, from category 1 needing no external access at all up to category
3 needing full external access through translation.
- The complete authoritative list of special IPv4 blocks lives in the IANA
IPv4 Special-Purpose Address Registry, whose framework is RFC 6890, April
2013, later corrected by RFC 8190, June 2017.
- Filtering practice: operators drop RFC 1918 prefixes at the edge. This is a
strong convention and appears in BCP 84 and in the Team Cymru bogon lists,
but it is not enforced by the protocol itself. A misconfigured network can
and does leak private prefixes.
- Private addresses appearing inside a traceroute are entirely normal. Many
carriers number their internal point-to-point links from 10.0.0.0/8 or
172.16.0.0/12 to conserve public space. The reader’s hops 2, 4, 5 and 6 are
exactly this.
- Important precision: an RFC 1918 address seen in a traceroute is the address
of the router interface that generated the ICMP time-exceeded reply. It is
not the address your packet was carrying. Do not confuse the two. Section
24.9 depends on this distinction.
- A private address can still be globally reachable through a tunnel, a VPN or
an MPLS VPN, because those carry it inside another packet. The rule is about
the public routing table, not about physics.
- Overlap is a real operational problem. When two companies merge and both use
10.0.0.0/8, engineers have to renumber one side or deploy NAT between them,
sometimes called twice-NAT or NAT overlapping networks.
- Observation:
netstat -rn shows which prefixes your machine treats as local.
whois 137.97.29.249 at a regional registry will name the holder of a
public block; whois 172.31.0.17 will tell you it is RFC 1918 and nothing
more, because nobody holds it.
WORDS24.3.6 remember these#
- Public address — an address the whole internet can reach — a globally unique
address allocated through IANA and a regional registry.
- Private address — an address meaningful only inside one network — an address
from 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16 per RFC 1918, BCP 5.
- RFC 1918 — the 1996 document reserving private ranges — Best Current
Practice 5, “Address Allocation for Private Internets”.
- Bogon — an address or route that should never appear — a martian prefix;
traffic or routing announcements from reserved or unallocated space.
- Ingress filtering — dropping packets with impossible sources at the edge —
the practice described in BCP 38 and RFC 2827.
- Address overlap — two networks using the same private numbers — the merger
problem solved by renumbering or twice-NAT.
24.4 The other special ranges#
PLAIN24.4.1 in simple words#
- Private addresses are not the only ones with a special job. Several other
blocks are carved out and cannot be used as ordinary addresses.
- Loopback: everything starting with 127. This means “me, this machine”.
Packets sent there never touch a cable. They turn around inside the software.
- 127.0.0.1 is the one everybody types. The name for it is
localhost.
- Link-local: everything starting 169.254. A machine gives itself one of
these when it asks for an address and nobody answers.
- If you ever see 169.254 on your laptop, it means the address request failed.
It is a symptom, not a setting.
- Shared address space: everything from 100.64 to 100.127. This block was
set aside in 2012 for internet providers to number their customers when they
have run out of public addresses.
- Multicast: everything from 224 to 239. These are not one machine. They
are a group. One packet, many listeners.
- All zeros, 0.0.0.0, means “no address yet” or “every address here”,
depending on where it appears.
- All ones, 255.255.255.255, means “everyone on this wire, right now”.
- There are also three blocks reserved purely for writing examples in books
and manuals, so that a printed example never accidentally names a real
machine.
PLAIN24.4.2 a picture in your head#
- Think of the reserved words in a language.
- In English, “here” and “everyone” and “nobody” are not names. You cannot call
a child “Everyone” and expect the register to accept it.
- 127.0.0.1 is the word “here”. It always points back at the speaker, whoever
is speaking.
- 255.255.255.255 is the word “everyone in this room”. It never leaves the
room, because shouting does not travel through walls.
- 0.0.0.0 is the phrase “no name yet”, used by someone who has just walked in
and has not been introduced.
- 169.254.x.x is the name a person invents for themselves when nobody at the
door would give them a badge.
- 192.0.2.x is like the name “John Doe” in a legal form. It is deliberately
nobody.
Where this comparison breaks: reserved words in a language are enforced by
custom, and you can break the rule and be merely odd. These reserved address
blocks are enforced by software. Your operating system will refuse to route
127.x.x.x off the machine even if you order it to, and other people’s routers
will simply discard the traffic. The rule is mechanical, not social.
PLAIN24.4.3 a worked example#
- Type this on any machine and it will answer without touching a network:
ping -c 2 127.0.0.1
# 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.045 ms
- A time of about 0.05 milliseconds is not a fast network. It is no network.
The packet went down the stack and straight back up.
- Unplug your Ethernet cable and turn off Wi-Fi, and 127.0.0.1 still works.
That is the test that proves it never leaves the machine.
- Now the failure case. Take a laptop, plug it into a switch with no DHCP
server, and wait about twenty seconds.
ipconfig getifaddr en0
# 169.254.213.7
- That address was not given to the laptop. The laptop invented it, picked at
random from 169.254.0.0/16, after checking nobody else on the wire had it.
- Two laptops that both do this can talk to each other, and to nothing else.
There is no gateway, so nothing routes.
- Now the carrier case. If your router’s outside address is 100.64.9.31, you
are not on the internet directly. Your provider has put you behind their own
translation. That is carrier-grade NAT, and section 24.9 covers it.
- The reader’s own hops do not show 100.64.x.x. They show RFC 1918 addresses
instead. That is a different but equally common carrier choice, and it is
discussed honestly in section 24.9.
PLAIN24.4.4 what is really happening inside#
- For loopback, the operating system’s network stack checks the destination
before anything reaches a driver. If the destination is on the loopback
interface, the packet is handed straight back to the receive path.
- That is why loopback latency measures the speed of your kernel, not of any
wire, and why loopback has an enormous maximum packet size, typically 16384
bytes on macOS instead of the usual 1500.
- For link-local, the machine picks a random address in 169.254.1.0 to
169.254.254.255, then sends an ARP probe asking “does anyone own this”.
- If somebody answers, it picks another and tries again. If nobody answers
after a few tries, it keeps the address.
- That process is why the address appears about fifteen to twenty seconds after
the DHCP attempt fails, not instantly.
- For multicast, routers and switches maintain group membership. A machine
announces “I want group 239.1.1.1” and the network arranges for copies to
reach it. One sender, many receivers, one copy per link rather than per
receiver.
- For 255.255.255.255, routers never forward it. It reaches every machine on
the local segment and stops. That limit is deliberate; otherwise one packet
could reach the whole internet.
- This is exactly how DHCP starts. A machine with no address at all sends from
0.0.0.0 to 255.255.255.255, because it cannot address the server it has not
met yet.
TECHNICAL24.4.5 the engineer’s version#
- The full set of special-purpose IPv4 blocks, each with the document that
defines it:
| Prefix |
Purpose |
Defining RFC |
| 0.0.0.0/8 |
this network |
RFC 791 |
| 0.0.0.0/32 |
unspecified source |
RFC 1122 |
| 10.0.0.0/8 |
private |
RFC 1918 |
| 100.64.0.0/10 |
shared, for CGNAT |
RFC 6598 |
| 127.0.0.0/8 |
loopback |
RFC 1122 |
| 169.254.0.0/16 |
link-local |
RFC 3927 |
| 172.16.0.0/12 |
private |
RFC 1918 |
| 192.0.0.0/24 |
IETF protocol use |
RFC 6890 |
| 192.0.2.0/24 |
documentation, TEST-NET-1 |
RFC 5737 |
| 192.168.0.0/16 |
private |
RFC 1918 |
| 198.18.0.0/15 |
benchmark testing |
RFC 2544 |
| 198.51.100.0/24 |
documentation, TEST-NET-2 |
RFC 5737 |
| 203.0.113.0/24 |
documentation, TEST-NET-3 |
RFC 5737 |
| 224.0.0.0/4 |
multicast |
RFC 1112 |
| 240.0.0.0/4 |
reserved, future use |
RFC 1112 |
| 255.255.255.255/32 |
limited broadcast |
RFC 919, RFC 8190 |
- RFC 1122, “Requirements for Internet Hosts - Communication Layers”, October
1989, edited by Robert Braden, is what reserves all of 127.0.0.0/8 for
loopback, not just 127.0.0.1. That is 16,777,216 addresses spent on one idea.
- RFC 3927, “Dynamic Configuration of IPv4 Link-Local Addresses”, May 2005,
defines 169.254.0.0/16. Apple’s implementation is branded Bonjour, and
Microsoft’s is called APIPA, Automatic Private IP Addressing. Both implement
the same RFC.
- RFC 6598, “IANA-Reserved IPv4 Prefix for Shared Address Space”, April 2012,
is BCP 153. It reserves 100.64.0.0/10, which is 4,194,304 addresses, from
100.64.0.0 to 100.127.255.255. It exists because carriers were using RFC
1918 space for CGNAT and colliding with customers’ own networks.
- RFC 1112, “Host Extensions for IP Multicasting”, August 1989, by Steve
Deering, defines 224.0.0.0/4. Assignment inside it is governed by RFC 5771,
BCP 51. Notable addresses: 224.0.0.1 all hosts on this subnet, 224.0.0.2 all
routers, 224.0.0.5 and 224.0.0.6 for OSPF, 224.0.0.251 for mDNS.
- RFC 5737, January 2010, reserves the three documentation blocks. This chapter
deliberately does not use them, because the reader asked for their own real
addresses. Where an address here is invented rather than measured, it is
labelled as such.
- RFC 2544, March 1999, reserves 198.18.0.0/15 for device benchmarking; RFC
6815, November 2012, warns that this traffic must never leave the lab.
- 240.0.0.0/4 is 268 million addresses sitting unused since 1989. There have
been repeated IETF proposals to release it. It has not happened, because
every operating system, router and firewall on earth would need updating to
accept it, and the gain is roughly one year of global growth.
- 0.0.0.0/0 as a route means “everything”, the default route. 0.0.0.0 as a bind
address in a server means “listen on every local address”. Same digits,
entirely different meaning depending on the field it sits in.
- Observation:
netstat -rn on macOS shows the 127.0.0.0/8 route pointing at
lo0 and the default route pointing at 192.168.0.1 for the reader.
WORDS24.4.6 remember these#
- Loopback — the address that means this machine — 127.0.0.0/8 per RFC 1122,
handled entirely inside the kernel, never placed on a link.
- Link-local — the address a machine gives itself when nothing answers —
169.254.0.0/16 per RFC 3927, claimed by ARP probe, no gateway.
- Shared address space — the block providers use to number customers behind
their own NAT — 100.64.0.0/10 per RFC 6598, BCP 153.
- Multicast — one packet delivered to a group — 224.0.0.0/4 per RFC 1112, with
group membership managed by IGMP.
- Limited broadcast — everyone on this wire and no further —
255.255.255.255/32, never forwarded by a router.
- Unspecified address — I do not have an address yet — 0.0.0.0 as a source, as
used by a DHCP client before it is configured.
- TEST-NET — addresses reserved for writing examples — 192.0.2.0/24,
198.51.100.0/24 and 203.0.113.0/24 per RFC 5737.
24.5 Address exhaustion: why 4.29 billion was not enough#
PLAIN24.5.1 in simple words#
- There are 4,294,967,296 possible IPv4 addresses. There are more than 8
billion people, and far more than 8 billion devices.
- So even in the best case the numbers do not work. But the shortage arrived
much earlier than the raw count suggests.
- It arrived early because of how the addresses were handed out, not because
they were all in use.
- In the beginning, addresses were given out in three fixed sizes only: about
16 million, about 65 thousand, or 256.
- There was nothing in between. If your university needed 400 addresses, 256
was too few, so you got 65,536 and wasted 65,136 of them.
- Big early organizations were handed 16 million addresses each, often for a
few thousand machines.
- By 1992 people could see the end coming. Not just the end of addresses, but
the end of the routers, which were running out of memory to hold all the
separate routes.
- In 1993 the fixed sizes were abolished and replaced by the slash notation of
section 24.2. That let blocks be any size, which stopped most of the waste.
- Private addresses plus NAT arrived soon after, which let one public address
serve a whole household or office.
- Those two changes bought about twenty extra years. The free pool of unused
addresses still ran dry, starting in 2011.
PLAIN24.5.2 a picture in your head#
- Imagine a city where land is sold only in three plot sizes: a whole district,
a whole street, or a single house.
- A family needing two houses must buy a whole street, and leave the rest
empty, because there is no plot of two.
- A school needing thirty houses must also buy a street. So does a factory
needing sixty.
- Early buyers, arriving when land felt endless, took whole districts for a
handful of buildings.
- The city fills up not because it is full of people, but because it is full of
fences around empty ground.
- In 1993 the city changed the rules: you can now buy any number of plots you
actually need. That helped enormously, but the districts already sold stayed
sold.
Where this comparison breaks: land can be compulsorily bought back and
redeveloped. IPv4 blocks mostly cannot. Some early holders have sold blocks on
an open market, and some space has been returned, but there is no authority that
can take an allocation back by force. The fences from 1985 are still standing.
PLAIN24.5.3 a worked example#
- Here is the old class system, the one abolished in 1993.
| Class |
First bits |
Prefix |
Hosts each |
| A |
0 |
/8 |
16,777,214 |
| B |
10 |
/16 |
65,534 |
| C |
110 |
/24 |
254 |
| D |
1110 |
multicast |
not applicable |
| E |
1111 |
reserved |
not applicable |
- The class was decided by the leading bits of the address itself, so you could
tell the network size by looking at the first number.
- First number 1 to 126 meant class A. 128 to 191 meant class B. 192 to 223
meant class C.
- Check the reader’s own addresses against that. 192.168.0.1 begins with 192,
so it sat in the old class C range. 137.97.29.249 begins with 137, so class
B. 20.207.73.82 begins with 20, so class A.
- That last one is real history, not trivia. The 20.0.0.0/8 block, all 16.7
million addresses, was allocated in the 1980s to a single company. Microsoft
later held it, and today it fronts services including the GitHub endpoint the
reader was trying to reach.
- Now the waste. Suppose a company in 1990 needs 400 addresses.
- A class C gives 254. Not enough.
- A class B gives 65,534. So they get a class B, and 65,134 addresses sit idle
forever.
- With CIDR the same company gets a /23, which is 512 addresses, 510 usable.
Waste drops from 65,134 to 110.
- Multiply that saving across every allocation made after 1993 and you have the
reason the internet did not stop growing in 1996.
PLAIN24.5.4 what is really happening inside#
- Two separate crises were happening at once, and it helps to keep them apart.
- The first is address exhaustion: running out of numbers to give people.
- The second is routing table growth: the routers in the middle of the
internet were running out of memory to store one entry per network.
- Class B allocation was making both worse. Every class B handed out was one
more route every core router had to remember.
- CIDR fixed both. Smaller allocations meant less waste, and blocks handed to
one provider could be advertised as one summary route instead of hundreds.
- NAT then attacked the first problem from the other end: instead of finding
more addresses, it made one address serve many machines.
- The IANA free pool is the top of a three-level tree. IANA holds unallocated
space, gives large blocks to five regional registries, and those registries
give blocks to providers and companies.
- When people say the internet ran out in 2011, they mean the top level ran
dry. The registries kept issuing from their own stock for years afterwards,
under increasingly strict rules.
- Today, in most regions, new IPv4 space is obtained by buying it from an
existing holder on a transfer market, not by asking a registry.
TECHNICAL24.5.5 the engineer’s version#
- Total IPv4 space is 2 to the power 32, exactly 4,294,967,296. Subtracting the
special blocks of section 24.4, roughly 3.7 billion are usable as ordinary
public unicast addresses.
- The exhaustion timeline, with verified dates:
| Date |
Event |
| 31 January 2011 |
IANA gave last 2 free /8s |
| 3 February 2011 |
NRO declared pool depleted |
| 15 April 2011 |
APNIC hit final /8 policy |
| September 2012 |
RIPE NCC hit final /8 |
| 10 June 2014 |
LACNIC exhaustion |
| 24 September 2015 |
ARIN exhaustion |
| 2017 |
AFRINIC entered phase 1 |
| 25 November 2019 |
RIPE NCC fully out |
- The precision matters. On 31 January 2011 IANA allocated 39.0.0.0/8 and
106.0.0.0/8 to APNIC, which triggered the “final five” policy under which the
five remaining /8s were distributed one to each registry. The Number Resource
Organization made the formal announcement on 3 February 2011. So both dates
are correct, for different events.
- APNIC, serving Asia-Pacific including India, reached its final /8 first, on
15 April 2011, because demand there was highest. That is directly relevant to
the reader: an Indian ISP has been operating under severe IPv4 scarcity for
over a decade, which is the background to section 24.9.
- CIDR was specified in RFC 1518 and RFC 1519, both September 1993, and
deployed through 1994. RFC 4632, August 2006, BCP 122, is the current
specification.
- Classful addressing was formally deprecated by RFC 4632. Some textbooks and
certification syllabuses still teach classes; treat them as history that
explains why blocks look the way they do, not as current practice.
- The measures that bought time, in rough order of impact: CIDR from 1993, NAT
with RFC 1918 from 1994 to 1996, DHCP address recycling from RFC 2131 in
1997, and carrier-grade NAT from around 2010.
- Global BGP routing table size is the counter-measure to watch. It passed
roughly 100,000 routes around 2000 and is now well past 900,000 IPv4 routes.
Aggregation slowed the growth; it did not stop it.
- Transfer markets now set a real price for IPv4. Reported per-address prices
rose from a few dollars in 2011 into the mid-tens of dollars by the
mid-2020s, with real volatility. Treat any single quoted figure as
approximate and dated.
- Amazon Web Services began charging for every public IPv4 address on 1
February 2024, at 0.005 US dollars per address per hour. That is the
clearest signal that IPv4 became a priced commodity rather than a free
resource.
WORDS24.5.6 remember these#
- Address exhaustion — running out of numbers to hand out — depletion of
unallocated IPv4 unicast space at IANA and the regional registries.
- Classful addressing — the old fixed sizes A, B and C — the pre-1993 scheme
where the leading bits determined the prefix length; deprecated by RFC 4632.
- CIDR — letting blocks be any size — Classless Inter-Domain Routing, RFC 1518
and RFC 1519 in 1993, now RFC 4632.
- IANA — the body holding the master pool — Internet Assigned Numbers
Authority, operated under Public Technical Identifiers within ICANN.
- RIR — a regional address registry — one of AFRINIC, APNIC, ARIN, LACNIC and
RIPE NCC.
- Free pool — unallocated addresses still available — the stock a registry can
issue without a transfer.
- Transfer market — buying addresses from an existing holder — registry-
approved reassignment of allocated space, now the main source of IPv4.
24.6 NAT, explained completely#
PLAIN24.6.1 in simple words#
- You have one public address, from your provider. You have a laptop, a phone,
a television and a printer. All four want the internet at once.
- NAT is the trick that lets all four share the one address.
- NAT stands for Network Address Translation. The router rewrites addresses as
packets pass through it.
- Going out, the router takes your private source address and replaces it with
its own public one. The far end never sees your real address.
- Coming back, the router does the reverse. It puts your private address back
before delivering the reply to you.
- To do the reverse it must remember which reply belongs to which machine. So
it keeps a table.
- The table has one row per conversation. It is created when you start a
conversation and deleted when the conversation ends or goes quiet.
- The key trick is that the router also rewrites the port number, not just the
address. That is what allows many machines to share one address at once.
- Ports are section 24.7. For now, treat a port as a numbered slot on the
router, one per conversation.
- Nothing on the internet knows any of this happened. To the far end, it looks
like one machine with one address doing a lot of things.
PLAIN24.6.2 a picture in your head#
- Think of a hotel with one street address and one post room.
- A guest in room 214 writes a letter and asks for a reply.
- The post room will not put “Room 214” on the envelope. It writes the hotel’s
street address, and adds a reference number: “reply to reference 51022”.
- It notes in a ledger: reference 51022 belongs to room 214, and the letter went
to this particular company.
- The reply arrives addressed to the hotel, quoting reference 51022.
- The post room looks up 51022 in the ledger, sees room 214, writes that on the
envelope, and puts it in the guest’s pigeonhole.
- A thousand guests can write letters at once, because each gets a different
reference number.
- If a letter arrives quoting a reference that is not in the ledger, the post
room has no idea what to do with it. It goes in the bin.
Where this comparison breaks: a hotel post room can be told in advance “any
letter for the conference goes to room 214”, which is what port forwarding is.
But without that instruction, unexpected post is genuinely undeliverable, not
merely inconvenient. Also, the hotel ledger is permanent; a NAT table entry is
deleted after a timeout, typically a few minutes for a quiet UDP conversation,
which is why idle connections die and why applications send keep-alives.
PLAIN24.6.3 a worked example#
- Here is the reader’s own situation, with the one value we have to invent
clearly marked.
- Known from the reader’s session: the router is 192.168.0.1, and
github.com resolved to 20.207.73.82, and the connection was to port 443,
which is HTTPS.
- Not recorded in the session: the laptop’s own address and the router’s public
address. We will use 192.168.0.24 for the laptop, which is a plausible value
in the reader’s 192.168.0.0/24 network, and we mark the public address as an
example.
- The laptop opens a connection. The operating system picks a random unused
local port, say 52344.
- The packet leaving the laptop looks like this:
source 192.168.0.24:52344
destination 20.207.73.82:443
protocol TCP
- It reaches 192.168.0.1. The router rewrites the source and writes a row in
its table.
- The packet leaving the router looks like this:
source 203.0.113.45:61001 (example public address)
destination 20.207.73.82:443
protocol TCP
- And the table row it created:
| Internal |
External |
Destination |
| 192.168.0.24:52344 |
203.0.113.45:61001 |
20.207.73.82:443 |
- Now the full table with three devices in the flat, all talking at once. This
is what a real home router holds.
| Internal addr:port |
External port |
Dest addr:port |
Proto |
| 192.168.0.24:52344 |
61001 |
20.207.73.82:443 |
TCP |
| 192.168.0.24:52345 |
61002 |
20.207.73.82:443 |
TCP |
| 192.168.0.24:52346 |
61003 |
140.82.121.4:22 |
TCP |
| 192.168.0.31:49780 |
61004 |
1.1.1.1:53 |
UDP |
| 192.168.0.31:51201 |
61005 |
20.207.73.82:443 |
TCP |
| 192.168.0.57:60110 |
61006 |
17.253.144.10:123 |
UDP |
- Read row 1 and row 5 together. Two different machines, both talking to
20.207.73.82 on port 443, both leaving as the same public address. They are
told apart only by the external port, 61001 versus 61005.
- A reply arrives at the router addressed to 203.0.113.45 port 61005. The
router looks up 61005, finds 192.168.0.31:51201, rewrites the destination,
and forwards it inside.
- Now the crucial negative case. A packet arrives from the internet addressed
to 203.0.113.45 port 8080, and no row mentions 8080. The router has no idea
which of the three machines it is for. It drops it.
- That single drop is the whole of section 24.8.
PLAIN24.6.4 what is really happening inside#
- Rewriting the address is not just a copy. The router must also fix the
checksums.
- A checksum is a small number computed from the packet contents, used to catch
corruption. Change the address and the checksum no longer matches.
- So the router recomputes the IP header checksum, and also the TCP or UDP
checksum, because those are computed over the addresses as well.
- Good implementations do this incrementally: they adjust the old checksum by
the difference rather than recomputing from scratch, which is far faster.
- The table entry is created by the first packet of a conversation and removed
on a timer, or when the connection closes cleanly.
- For TCP, the router can watch the connection state. It sees the opening
handshake and the closing exchange, so it knows when a row is finished.
- For UDP, there is no handshake and no close. The router can only use a timer,
typically 30 to 300 seconds of silence.
- This is why a video call freezes if you pause it for a few minutes, and why
chat applications send a tiny packet every 20 to 30 seconds for no reason
other than keeping the NAT row alive.
- The table lives in memory and is finite. Cheap home routers hold a few
thousand rows. Fill it and new connections simply fail, often with no useful
error.
- The router also has to be careful about port collisions. If two internal
machines happen to pick the same source port to the same destination, the
router must allocate different external ports, which it does automatically.
TECHNICAL24.6.5 the engineer’s version#
- NAT was first described in RFC 1631, “The IP Network Address Translator”,
May 1994, by Kjeld Egevang and Paul Francis. It was explicitly proposed as a
short-term measure.
- Terminology was standardized in RFC 2663, August 1999. The current
description of the common case is RFC 3022, “Traditional IP Network Address
Translator”, January 2001, which obsoletes RFC 1631.
- RFC 3022 separates two things. Basic NAT translates addresses only.
NAPT, Network Address Port Translation, translates address and transport
identifier together. Home routers do NAPT.
- The industry name for NAPT is PAT, Port Address Translation, in Cisco
documentation, or NAT overload. Linux calls it masquerade. All four
words describe the same mechanism.
- The four kinds you must be able to name:
| Kind |
What it rewrites |
Typical use |
| Source NAT |
source addr on egress |
home router outbound |
| Destination NAT |
dest addr on ingress |
port forwarding |
| Static NAT |
one to one, both ways |
a public server |
| PAT / NAPT |
addr plus port, many to one |
every home router |
- The state a NAT keeps per flow is keyed on the 5-tuple: protocol, source
address, source port, destination address, destination port. That is what
makes rows unique even when several fields repeat.
- NAT behaviour is classified by RFC 4787, BCP 127, January 2007, for UDP, and
RFC 5382 for TCP. The mapping behaviours are endpoint-independent,
address-dependent, and address-and-port-dependent. Endpoint-independent
mapping is required by BCP 127 because it is the only behaviour that makes
peer-to-peer hole punching reliable.
- The older names cone NAT, restricted cone, port-restricted cone and symmetric
NAT come from RFC 3489, the original STUN document from 2003. That
classification was found too coarse and was deliberately replaced by the
RFC 4787 vocabulary. You will still see the old names in game-console
diagnostics, where “NAT type 3” means a restrictive NAT.
- Default timeouts, as a guide rather than a standard: established TCP flows
are often held 2 to 24 hours, TCP in the opening handshake around 4 minutes,
UDP 30 to 180 seconds, ICMP around 30 seconds. RFC 5382 requires at least
2 hours 4 minutes for established TCP; RFC 4787 requires at least 2 minutes
for UDP.
- Observation on Linux:
conntrack -L lists live NAT and connection tracking
rows, and cat /proc/sys/net/netfilter/nf_conntrack_max gives the table
size. On macOS the relevant tool is pfctl -s state. On a home router the
table is usually visible in the web interface under a name like “NAT
sessions” or “connection list”.
# Linux router: see the live translation table
sudo conntrack -L | head -3
# tcp 6 431999 ESTABLISHED src=192.168.0.24 dst=20.207.73.82
# sport=52344 dport=443 src=20.207.73.82 dst=203.0.113.45
# sport=443 dport=61001 [ASSURED]
WORDS24.6.6 remember these#
- NAT — rewriting addresses as packets cross a boundary — Network Address
Translation, RFC 2663 and RFC 3022.
- NAPT or PAT — rewriting address and port so many can share one — Network
Address Port Translation, the mechanism in every home router.
- Source NAT — changing where a packet says it came from — SNAT, applied on
egress, the outbound direction.
- Destination NAT — changing where a packet is going — DNAT, applied on
ingress; port forwarding is a DNAT rule.
- Static NAT — a fixed one-to-one mapping in both directions — a bidirectional
NAT binding, used to publish a server on a dedicated public address.
- NAT table — the router’s memory of who is talking to whom — the translation
state table, keyed on the 5-tuple.
- 5-tuple — the five facts that identify one conversation — protocol, source
address, source port, destination address, destination port.
- Masquerade — the Linux word for many-to-one source NAT — an iptables or
nftables target that uses the egress interface’s current address.
24.7 Ports: the trick that makes NAT work#
PLAIN24.7.1 in simple words#
- An address gets a packet to the right machine. A port gets it to the
right conversation on that machine.
- A port is just a number. It is 16 bits, so it runs from 0 to 65535.
- It is not a physical thing. There is no socket on the back of the computer
labelled 443. It is a number written in the packet header.
- Your machine may be running a web browser, a mail program, a music stream and
a code editor, all talking at once. Every one of those conversations has its
own port number.
- When data arrives, the operating system reads the port and hands the data to
the program that claimed that number.
- A server claims a fixed, well-known port so clients can find it. Web servers
with encryption claim 443. That is why the reader’s
curl said port 443.
- A client does not need a fixed number. It grabs any free one, uses it for
that one conversation, and releases it afterwards.
- Those temporary client numbers are called ephemeral ports, meaning
short-lived.
- NAT depends completely on this. Because the router can change the port as
well as the address, it can give every conversation a unique number even when
they all share one address.
- Without ports, one public address could carry exactly one conversation at a
time, and NAT would be useless.
PLAIN24.7.2 a picture in your head#
- Think of a large company with one street address and many departments.
- The street address gets the post to the building. “Attention: Accounts” gets
it to the right desk inside.
- Some departments have famous, published names. Everyone knows to write
“Attention: Sales” without asking. Those are the well-known ports.
- When Sales writes out to a supplier, it says “reply to case 52344”. That case
number is invented for this one exchange and forgotten afterwards. That is an
ephemeral port.
- Two letters can go to the same supplier on the same day from the same
building, and come back correctly, because the case numbers differ.
Where this comparison breaks: a company can invent unlimited case numbers. A
machine has exactly 65,536 port numbers per protocol per address, and no more.
That hard ceiling is a real engineering limit that busy servers and carrier NAT
boxes genuinely run into, and it is the subject of the technical block below.
PLAIN24.7.3 a worked example#
- Here is the full picture of the reader’s connection attempt, showing address
and port at every stage.
laptop home router github endpoint
192.168.0.24 192.168.0.1 20.207.73.82
| | |
| src 192.168.0.24:52344 |
| dst 20.207.73.82:443 |
|-------------------->| |
| | src 203.0.113.45:61001
| | dst 20.207.73.82:443 |
| |---------------------->|
| | |
| | src 20.207.73.82:443 |
| | dst 203.0.113.45:61001
| |<----------------------|
| src 20.207.73.82:443 |
| dst 192.168.0.24:52344 |
|<--------------------| |
- Note what stayed the same all the way through: the destination port 443. The
server’s port is never rewritten by your router.
- Note what changed: the source address and the source port, both rewritten
outbound and both restored inbound.
- Here are the port ranges and what each is for.
| Range |
Name |
Who uses it |
| 0 to 1023 |
System, well-known |
servers, needs privilege |
| 1024 to 49151 |
User, registered |
named services |
| 49152 to 65535 |
Dynamic, ephemeral |
clients, never assigned |
- Some well-known ports worth memorizing, several of which appear in the
reader’s own session:
| Port |
Service |
Note |
| 22 |
SSH |
git over SSH |
| 53 |
DNS |
the reader used 1.1.1.1 |
| 80 |
HTTP |
unencrypted web |
| 123 |
NTP |
clock sync |
| 443 |
HTTPS |
git over HTTPS, curl |
| 993 |
IMAPS |
encrypted mail fetch |
| 3306 |
MySQL |
database |
| 5432 |
PostgreSQL |
database |
- This table explains something from the reader’s own session directly. Git over
SSH uses port 22. Git over HTTPS uses port 443. They are different
conversations to possibly different machines, so one can fail while the other
works.
PLAIN24.7.4 what is really happening inside#
- The port numbers are not in the IP header. They are in the next header
inside, the TCP or UDP header.
- In both TCP and UDP, the source port is the first two bytes and the
destination port is the next two bytes. They are the very first thing in that
header, which makes them cheap for hardware to read.
- When your program asks to open a connection, it usually does not choose a
port. It asks the operating system for any free one.
- The operating system keeps a record of which ports are in use, picks a free
one from its ephemeral range, and marks it taken.
- Modern systems pick randomly within the range rather than counting upwards.
That is a deliberate security change, because predictable ports made certain
attacks easier.
- The combination that must be unique is not the port alone. It is the whole
5-tuple: protocol, both addresses, both ports.
- That is why a busy web server can have 200,000 connections open while only
listening on one port: every client is a different address or a different
client port.
- A server binding to a port below 1024 traditionally needs administrator
rights on Unix systems. That is a convention from the 1980s designed to stop
ordinary users impersonating system services.
- When the router rewrites a port, it must pick one that is not already used
for another conversation to the same destination. Its allocator does that
check on every new flow.
TECHNICAL24.7.5 the engineer’s version#
- Port numbers are 16-bit unsigned integers, 0 to 65535, defined separately for
each transport protocol. TCP port 443 and UDP port 443 are different
registry entries and different listening sockets.
- The three ranges are defined in RFC 6335, August 2011, which is BCP 165. The
official names are System Ports, User Ports and Dynamic Ports; the informal
names are Well Known, Registered and Private or Ephemeral.
- Operating systems do not agree on the ephemeral range, and this is an
implementation detail, not a standard:
| System |
Default ephemeral range |
| macOS and FreeBSD |
49152 to 65535 |
| Linux |
32768 to 60999 |
| Windows Vista onward |
49152 to 65535 |
| Windows XP and earlier |
1025 to 5000 |
- On Linux the range is readable and writable at
/proc/sys/net/ipv4/ip_local_port_range. On macOS it is
sysctl net.inet.ip.portrange.first and .last.
- Port 0 is reserved and must not be used on the wire. Binding to port 0 in a
socket API is a request for the kernel to allocate an ephemeral port, which
is a different meaning of the same number.
- The theoretical connection limit. For a single client address talking to a
single server address and port, the only free field is the client port, so
the ceiling is 65,536 minus reserved values, roughly 64,500 simultaneous
connections. If the operating system uses the standard ephemeral range only,
the practical ceiling is about 16,384 on macOS and about 28,000 on Linux.
- For NAT, the same arithmetic applies to the public address. One public
address can support roughly 64,500 simultaneous flows to any one destination
endpoint, but many times that across different destinations, because the
destination fields also vary.
- In carrier practice, providers plan on a sharing ratio rather than the
theoretical limit. Published deployments have used anywhere from 4 to over
100 subscribers per public address, with per-subscriber port quotas of a few
hundred to a few thousand. RFC 6888 requires the ability to set such a quota
precisely so one subscriber cannot exhaust the pool.
- Port exhaustion is a real production failure mode. Its symptoms are new
connections failing while existing ones work, and on Linux a rising count of
sockets in
TIME_WAIT, which holds a port for 2 times the maximum segment
lifetime, usually 60 seconds total.
- Observation commands:
lsof -i -nP | head # macOS: which program owns a port
netstat -an | grep 443 # all conversations on port 443
sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
ss -tan state time-wait | wc -l # Linux: count TIME_WAIT sockets
WORDS24.7.6 remember these#
- Port — a number identifying one conversation on a machine — a 16-bit field in
the TCP or UDP header, first four bytes of that header.
- Well-known port — a published number a server listens on — System Ports 0 to
1023, assigned by IANA under RFC 6335, BCP 165.
- Ephemeral port — a temporary number a client borrows — Dynamic Ports 49152 to
65535 by IANA, with operating system defaults that differ.
- Socket — one end of a conversation — the pairing of an address and a port,
plus a protocol, exposed as a file descriptor by the operating system.
- Port exhaustion — running out of conversation numbers — depletion of the
available ephemeral or NAT external port pool, causing new connections to
fail while old ones survive.
- TIME_WAIT — a closed connection still holding its number — the TCP state that
retains the 4-tuple for twice the maximum segment lifetime.
24.8 What NAT breaks#
PLAIN24.8.1 in simple words#
- NAT works beautifully in one direction and badly in the other.
- Outward is fine. You start the conversation, the router makes a table row,
replies find their way home.
- Inward is the problem. Nobody outside can start a conversation with you.
- When an unexpected packet arrives, the router looks in its table, finds
nothing, and has no way to guess which of your devices it was for. So it
drops it.
- This means you cannot run a server at home that other people reach, unless
you configure the router specially.
- That special configuration is called port forwarding: a permanent rule
saying “anything arriving on port 8080 goes to 192.168.0.24”.
- It also means two people both behind NAT cannot simply call each other.
Neither can start the conversation, because both are unreachable from
outside.
- Video calls, online games and file sharing all hit this. They solve it with
helper servers and a trick called hole punching.
- Some older protocols carry addresses inside their own messages. NAT rewrites
the header but not the message, so those protocols break in confusing ways.
- The internet was originally designed so that any machine could talk to any
other machine directly. NAT ended that. It is a workaround that became
permanent.
PLAIN24.8.2 a picture in your head#
- Go back to the hotel post room from section 24.6.
- A guest writes out and gets a reply. That works, because the ledger has the
reference number.
- Now imagine somebody outside wants to write to the guest first, without being
asked. They know the hotel address. They do not know the guest is there, and
they certainly do not know any reference number.
- Their letter arrives with nothing useful on it. The post room genuinely
cannot deliver it. There are four hundred rooms.
- Worse: two guests in two different hotels want to write to each other. Each
can write out. Neither can be written to. Their letters cross in the post and
both land in bins.
- The only fix is a third party. Both guests write to a shared friend who
already has a public, reachable address. The friend tells each one the other’s
hotel address and reference number, at the same moment, so both send first
and both ledgers get their rows.
Where this comparison breaks: this is where the comparison stops being a
comparison and becomes literally true. The shared friend is a STUN server, the
simultaneous sending is hole punching, and if it fails, the friend physically
relays every letter, which is a TURN server. The technical block names them.
PLAIN24.8.3 a worked example#
- Say the reader wants to run a small web server on the laptop at
192.168.0.24, listening on port 8080, and let a friend see it.
- The friend types the public address into a browser. The packet arrives at the
router addressed to port 8080.
- The router checks its table. There is no row for port 8080. It drops the
packet. The friend sees a connection timeout with no error message. Silence.
- The fix is a port forwarding rule on the router:
| Public port |
Internal address |
Internal port |
| 8080 |
192.168.0.24 |
8080 |
- That rule is a destination NAT entry, permanently installed rather than
created by traffic. Now the packet is rewritten and delivered.
- But note what you have just done: you have permanently allocated one public
port to one machine. You cannot forward port 8080 to two laptops.
- Now the peer-to-peer case. Two friends both behind home NAT want a video
call.
- Each contacts a public helper server and asks “what address and port do you
see me as”. The helper answers with the outside view, which is the router’s
public address and the chosen external port.
- Each sends that answer to the other, through a signalling channel that both
can already reach.
- Then both send a packet to the other at the same moment. Each outgoing packet
creates a table row in its own router. The incoming packet then matches a
row that already exists, so it is delivered.
- That is hole punching. Both sides must send first, which is why it needs
careful timing and a coordinator.
- If the routers are too restrictive for that to work, both sides give up and
send everything through a relay server instead. That works always, but costs
the relay operator bandwidth, and adds delay.
PLAIN24.8.4 what is really happening inside#
- The deep problem is that NAT breaks an assumption the internet was built on.
- The original assumption is that an address means the same thing everywhere.
The address you have is the address others use to reach you.
- Under NAT that is false. You have one address; the world sees another. There
is no way for your machine to know its own public address without asking
somebody outside.
- Any protocol that puts an address inside its own message, rather than only in
the header, is therefore broken by NAT.
- Old-style FTP does exactly that. In active mode the client sends its own
address and port as text inside a command, and asks the server to connect
back. Under NAT the address it sends is private and useless.
- Telephony signalling has the same shape. It negotiates media addresses inside
the message body, and those addresses are private.
- The workaround is an ALG, an Application Layer Gateway: the router
inspects the payload, finds the address written in text, and rewrites that
too.
- That is a genuinely ugly solution. The router now has to understand every
application protocol, and it breaks when the protocol changes or is
encrypted.
- Encryption killed the ALG approach for good. If the payload is encrypted, no
middle box can rewrite it. This is one reason modern protocols never put
addresses in the payload.
- There is a second cost that is easy to miss. NAT makes the network stateful.
A router that only forwards can be rebooted or replaced and traffic
continues. A router holding NAT state loses every conversation when it
restarts.
TECHNICAL24.8.5 the engineer’s version#
- The design principle NAT violates is stated in “End-to-End Arguments in
System Design” by Jerome Saltzer, David Reed and David Clark, presented in
1981 and published in ACM Transactions on Computer Systems in November 1984.
The argument is that functions should live at the endpoints, and the network
should stay simple.
- NAT puts per-conversation state in the middle of the network. That is
precisely what the end-to-end argument says not to do.
- The NAT traversal stack, with current documents:
| Protocol |
Job |
Current RFC |
| STUN |
discover your outside view |
RFC 8489, Feb 2020 |
| TURN |
relay when nothing else works |
RFC 8656, Feb 2020 |
| ICE |
try candidates, pick one |
RFC 8445, July 2018 |
- RFC 8489 obsoletes RFC 5389 from October 2008, which in turn replaced RFC
3489 from March 2003. RFC 8656 obsoletes RFC 5766 from February 2010. RFC
8445 obsoletes RFC 5245 from 2010.
- ICE gathers three kinds of candidate address: host candidates from local
interfaces, server-reflexive candidates learned from STUN, and relayed
candidates allocated on a TURN server. It then runs connectivity checks in
priority order and uses the best pair that works.
- In practice a WebRTC video call in a browser is running exactly this
machinery. Roughly speaking, most calls succeed with a direct or
server-reflexive path, and a minority fall back to TURN relay. The exact
fallback rate depends heavily on the network population being measured, so
treat any single published percentage with caution.
- Protocols historically needing an ALG: FTP in active mode, where RFC 959’s
PORT command carries an address as ASCII text; SIP, where addresses appear
in the SDP body; H.323; and some peer-to-peer file sharing protocols.
- IPsec is a specific casualty. Authentication Header protects the IP header
including addresses, so any NAT rewrite invalidates it. The workaround is
NAT Traversal, RFC 3947 and RFC 3948, January 2005, which wraps ESP inside
UDP on port 4500.
- UPnP IGD and NAT-PMP, and their successor Port Control Protocol in RFC 6887,
April 2013, let an internal device ask the router to open a mapping. They
work, and they are also a real security concern, since any program on the
network can open a hole without asking a human.
- The honest verdict, stated plainly: NAT is a workaround. RFC 1631 said so in
1994, calling it a short-term solution while a longer-term one was
developed. The longer-term solution was IPv6. Thirty years later the
short-term measure is still carrying most of the world’s traffic. Experts do
disagree about whether that is a tragedy or a pragmatic success; the
engineering costs listed above are not disputed by either side.
WORDS24.8.6 remember these#
- Port forwarding — a permanent rule sending one outside port to one inside
machine — a static destination NAT entry.
- Hole punching — both sides sending first so both NAT tables get a row — the
simultaneous-open technique used by ICE.
- STUN — asking a public server what address it sees you as — Session Traversal
Utilities for NAT, RFC 8489.
- TURN — routing everything through a public relay when nothing else works —
Traversal Using Relays around NAT, RFC 8656.
- ICE — trying every possible path and using the best one — Interactive
Connectivity Establishment, RFC 8445.
- ALG — a router that reads and rewrites inside the message — Application Layer
Gateway, needed by FTP and SIP, defeated by encryption.
- End-to-end principle — keep the clever parts at the edges — the design
argument of Saltzer, Reed and Clark, 1981 and 1984.
- Stateful — the box in the middle remembers your conversation — connection
state held outside the endpoints, lost on restart.
24.9 Carrier-grade NAT#
PLAIN24.9.1 in simple words#
- You already know that your home router shares one public address between all
your devices.
- Carrier-grade NAT is the same idea, one level up. Your internet provider
shares one public address between many customers.
- They do it for exactly the same reason you do. They have run out of public
addresses.
- So instead of giving your router a public address, they give it a private
one, and translate again at a big machine in their own network.
- Your traffic is now translated twice: once by your router, once by theirs.
The usual name for that is double NAT.
- From your side, nothing looks different for ordinary browsing. Pages load.
Video plays.
- From your side, several things become impossible or unreliable. You cannot
accept incoming connections at all, not even with port forwarding, because
the outer translation is not yours to configure.
- You also share a public address with strangers. If one of them misbehaves and
a website blocks that address, you are blocked too.
- Diagnosing faults becomes harder, because there is a machine in the path you
cannot see and cannot ask questions of.
- The reader’s own traceroute shows private addresses for five of the first six
hops. That is the fingerprint of a provider running a large private core,
and it is consistent with carrier-grade NAT.
PLAIN24.9.2 a picture in your head#
- Go back to the hotel one final time, and add a floor.
- Your flat is a hotel with extensions. Fine.
- Now the whole street is served by one switchboard, and your hotel’s “main
number” turns out not to be a real public number at all. It is an extension
on the street switchboard.
- Outsiders dialling the street switchboard reach an operator who has no idea
which hotel, let alone which room, they want.
- You can still call out. You always could. Calling in is now doubly
impossible.
- And if a neighbour on your street makes nuisance calls, the number that gets
barred is the street’s number, which is also yours.
Where this comparison breaks: a street switchboard would be an obvious,
visible thing. Carrier-grade NAT is invisible to customers. Providers rarely
announce it, there is no light on your router for it, and the only way to find
out is the test in section 24.13.
PLAIN24.9.3 a worked example#
- Here is the reader’s own first six hops again, exactly as recorded.
1 192.168.0.1
2 172.31.0.17
3 137.97.29.249
4 172.26.22.235
5 172.16.18.33 / 172.26.14.75 / 172.26.22.234
6 172.26.14.75 / 172.16.18.33
- Hop 1 is the reader’s own router, inside the flat, 192.168.0.1, private.
- Hop 2 is 172.31.0.17. Second octet 31, inside the 16 to 31 range of
172.16.0.0/12. Private. This is the provider’s first router, not the
reader’s.
- Hop 3 is 137.97.29.249. Not in any private block. Public.
- Hops 4, 5 and 6 are all in 172.16.0.0/12. Private again.
- So the pattern is: private, private, public, private, private, private.
- That is not a mistake and not a loop. It is what a provider network looks
like when most internal links are numbered from private space, but some
equipment has a public address on an interface.
- Now the honest part, and it matters more than anything else in this section.
- A traceroute shows the address of the interface that generated each reply. It
does not show what address your packet was carrying at that point.
- So the private addresses at hops 2, 4, 5 and 6 prove one thing: the
provider numbers those internal links from RFC 1918 space.
- They do not, on their own, prove that your traffic was translated to a
shared public address. That is strongly suggested, not proven.
- What would prove it is a two-line test, given in full in section 24.13:
compare the address on your router’s outside interface with the address a
public website reports. If they differ, there is a translation between you
and the internet that is not yours.
PLAIN24.9.4 what is really happening inside#
- A carrier-grade NAT is a large, expensive box, or a software function on a
large router, sitting between the provider’s access network and its public
edge.
- It holds the same kind of table as your home router, but with millions of
rows instead of thousands.
- Each customer is allocated a slice of the port space on a shared public
address. A common design gives each subscriber a block of a few thousand
ports.
- Giving each subscriber a contiguous block, rather than picking ports one at a
time, is a deliberate choice. It makes logging vastly cheaper: one log line
per subscriber per session instead of one per connection.
- Logging matters because law enforcement requests name an address, a port and
a time, and the provider must be able to say which customer that was.
- What your packet actually experiences, going out:
laptop 192.168.0.24
-> home router, source becomes the WAN address
-> provider access network (private numbering)
-> carrier NAT, source becomes a shared public address
-> provider public edge
-> the rest of the internet
- Coming back, the reverse happens, twice, and both tables must still hold the
row. If either times out, the connection dies.
- Because the outer table is not yours, you cannot create a permanent inbound
rule in it. Port forwarding on your own router still works for traffic that
reaches your router, but nothing from the internet reaches your router
unasked in the first place.
- Where hop 3 fits: a public address on a provider router interface tells you
that at least that interface is globally addressable. It marks a place where
the provider’s equipment touches public space. It does not by itself mark the
exact point where your source address was rewritten, and it would be
overclaiming to say that it does.
TECHNICAL24.9.5 the engineer’s version#
- Carrier-grade NAT is also called CGN, large-scale NAT or LSN. The
requirements document is RFC 6888, “Common Requirements for Carrier-Grade
NATs”, April 2013, which is BCP 127.
- RFC 6598, April 2012, BCP 153, reserves 100.64.0.0/10 as Shared Address Space
for exactly this purpose: numbering the link between the CGN and customer
premises equipment. Its existence is a direct admission that carriers were
already using RFC 1918 space and colliding with customers’ home networks.
- RFC 6264, June 2011, describes the incremental CGN approach for IPv6
transition. RFC 6598’s own justification is the collision problem.
- Key RFC 6888 requirements worth knowing: paired address pooling, meaning all
sessions from one internal address must use the same external address;
a configurable per-subscriber port limit; and a minimum 120-second delay
before an external port is reused.
- Deployment forms include NAT444, where there are three address realms and two
translations, and DS-Lite, RFC 6333, August 2011, which tunnels IPv4 over
IPv6 to a carrier translator called an AFTR. MAP-E and MAP-T, RFC 7597 and
RFC 7599, both July 2015, are stateless alternatives.
- What CGNAT costs the customer:
| Effect |
Consequence |
| No unsolicited inbound |
cannot host anything |
| Port forwarding useless |
your rule stops at you |
| Shared reputation |
blocked for a stranger |
| CAPTCHA and rate limits |
per-IP limits hit sooner |
| Harder diagnosis |
an invisible stateful hop |
| Game and call quality |
strict NAT, more TURN relaying |
| Geolocation errors |
mapped to the wrong city |
- The shared reputation problem is the one users notice most. Per-address rate
limiting, abuse blocklists and anti-fraud scoring all assume one address is
roughly one customer. Under CGNAT that assumption is simply false, and it can
put hundreds of households behind one score.
- Interpreting the reader’s trace precisely. Proven by the data: hops 2, 4, 5
and 6 are RFC 1918 addresses, so those provider interfaces are privately
numbered; hop 3 at 137.97.29.249 is a public address on a provider
interface. Suggested but not proven: that the reader’s own traffic is
subject to carrier-grade translation. Not shown at all: which specific device
performs any translation, or where exactly it sits.
- Hops 5 and 6 listing the same two addresses in different order,
172.16.18.33 and 172.26.14.75, is the signature of equal-cost multi-path
forwarding, where consecutive probes take different parallel links. It is
normal. Paris traceroute, published in 2006 by Brice Augustin and colleagues,
exists specifically to keep the flow identifier constant so that this
artefact disappears.
- Definitive detection, not inference: read the WAN address from the router’s
own status page or with a UPnP query, then compare it with what a public
reflector reports. Disagreement means an outer NAT. Both being equal and
public means no CGNAT.
# what the internet sees
curl -s https://api.ipify.org; echo
# an alternative that uses DNS instead of HTTP
dig +short myip.opendns.com @resolver1.opendns.com
# then compare with the WAN address shown by the router itself
WORDS24.9.6 remember these#
- Carrier-grade NAT — your provider sharing one public address between many
customers — CGN or LSN, specified for behaviour by RFC 6888, BCP 127.
- Double NAT — two translations between you and the internet — NAT444, three
address realms with a translation at each boundary.
- Shared address space — the block used between the carrier NAT and your router
— 100.64.0.0/10 per RFC 6598, BCP 153.
- Port block allocation — giving each customer a fixed slice of port numbers —
deterministic port assignment, which reduces logging volume enormously.
- Shared reputation — being punished for a stranger on the same address — the
collapse of the one-address-one-subscriber assumption used by abuse scoring.
- ECMP — several equally good parallel paths — equal-cost multi-path
forwarding, the reason one traceroute hop can show several addresses.
- DS-Lite — carrying IPv4 over an IPv6-only access network — Dual-Stack Lite,
RFC 6333, with translation at a carrier AFTR.
24.10 Reading the reader’s own first six hops as a story#
PLAIN24.10.1 in simple words#
- A traceroute is a list of the machines that handled your packet on the way
out, in order.
- It works by sending packets with a deliberately short lifespan. The first has
a lifespan of one hop, so the first router kills it and sends back a
complaint. The complaint reveals that router’s address.
- Then it sends one with a lifespan of two, and the second router complains.
And so on.
- So each line of a traceroute is one router saying “I am here, and your packet
died on my desk”.
- The reader’s first six hops tell a clear story: out of the flat, into the
provider, through the provider’s private core, with one public address
appearing in the middle.
- From hop 7 onwards the names change completely and the path enters
Microsoft’s own network, which is where GitHub lives.
- This section reads only the first six, because those six are entirely about
addressing, which is this chapter’s subject.
PLAIN24.10.2 a picture in your head#
- Imagine posting a letter with an instruction on the envelope: “after passing
through one sorting office, stop and send this envelope back to me with the
office’s stamp on it”.
- You get back an envelope stamped by your local office. Now you know the first
step of the route.
- Post another saying “stop after two offices”. Back it comes, stamped by the
regional depot. Now you know the second step.
- Repeat twenty times and you have mapped the whole postal route without ever
delivering a real letter.
- Some offices refuse to send anything back. Those steps come back blank. It
does not mean the office is broken; it means it does not answer surveys.
Where this comparison breaks: postal routes are stable, so twenty separate
letters follow the same path. Network paths are not. Each probe can take a
different parallel link, which is exactly why hops 5 and 6 of the reader’s trace
show several addresses each. A traceroute is a rough sketch made from twenty
different journeys, not a photograph of one.
PLAIN24.10.3 a worked example#
- Here is the reader’s own trace, hop by hop, classified.
| Hop |
Address |
Type |
| 1 |
192.168.0.1 |
private, 192.168.0.0/16 |
| 2 |
172.31.0.17 |
private, 172.16.0.0/12 |
| 3 |
137.97.29.249 |
public |
| 4 |
172.26.22.235 |
private, 172.16.0.0/12 |
| 5 |
172.16.18.33 and two more |
private, 172.16.0.0/12 |
| 6 |
172.26.14.75 and one more |
private, 172.16.0.0/12 |
- And what each one means.
| Hop |
What it means |
| 1 |
the reader’s own router |
| 2 |
the provider’s first router |
| 3 |
a provider public interface |
| 4 |
provider core, private |
| 5 |
parallel links, load balanced |
| 6 |
the same parallel links again |
- Hop 5 listed 172.16.18.33, 172.26.14.75 and 172.26.22.234. Hop 6 listed
172.26.14.75 and 172.16.18.33.
- The same addresses appear at two consecutive hops. That looks alarming and is
not. It is what happens when three probes for hop 5 and two probes for hop 6
each pick a different parallel link.
- Notice also that two different private blocks are in use: 172.16.x, 172.26.x
and 172.31.x. All three are inside 172.16.0.0/12. A large provider commonly
divides that /12 by region or by role.
- The shape of the path in one picture:
flat provider access provider core public
+--------+ +---------------+ +---------------+ +--------+
| laptop |-->| 192.168.0.1 |-->| 172.31.0.17 |-->| hop 7 |
| 192. | | hop 1 | | 172.26.x | | msn.net|
| 168.0.x| | private | | 172.16.18.33 | | public |
+--------+ +---------------+ | all private | +--------+
| 137.97.29.249 |
| one public |
+---------------+
PLAIN24.10.4 what is really happening inside#
- The lifespan number on the packet is called TTL, Time To Live. Every router
subtracts one before forwarding.
- When a router subtracts one and gets zero, it must discard the packet and
send back an ICMP time-exceeded message.
- That reply comes from whichever interface address the router chooses,
normally the one closest to you. That is why the addresses you see are the
routers’ inbound interfaces.
- It also means a private address in a trace is a router’s own interface, not
your packet’s source. This is the point that section 24.9 rested on.
- Not every router replies. Some are configured not to. Some rate-limit these
replies to a handful per second, which is why long traces show occasional
gaps in the middle.
- Silence at the end of a trace, which the reader saw at hops 13 to 20 as three
asterisks each, is normal and proves nothing on its own.
- The reason the reader’s trace still mattered is what it showed at the start,
not what it failed to show at the end: a provider with a large private core,
one public interface early on, and parallel links.
TECHNICAL24.10.5 the engineer’s version#
- Traceroute was written by Van Jacobson in 1987 at Lawrence Berkeley National
Laboratory. The behaviour it depends on, the ICMP time-exceeded reply, is in
RFC 792, September 1981.
- Classic Unix traceroute sends UDP datagrams to high, unlikely destination
ports, incrementing the TTL. macOS
traceroute does this by default and
needs no privilege for that mode.
- Windows
tracert sends ICMP echo requests instead. This matters, because
networks often treat ICMP and UDP differently, so the two tools can produce
different paths on the same network.
traceroute -I uses ICMP on macOS and requires root. traceroute -T on
Linux uses TCP SYN, which is often the only method that survives firewalls
that discard everything else.
- By default traceroute sends three probes per TTL value, which is why three
addresses can appear on one line and why unanswered hops print three
asterisks.
- Multiple addresses on one hop indicate ECMP load balancing, typically hashed
per flow on the 5-tuple. Classic traceroute varies the destination port
between probes, which changes the hash, which is why the probes diverge.
Paris traceroute, presented in 2006 by Brice Augustin and colleagues, holds
the flow identifier constant to avoid this.
- Reverse DNS is why hops 7 onward in the reader’s trace showed names such as
ae66-0.del01-96cbe-1b.ntwk.msn.net while hops 1 to 6 showed none. Private
addresses have no public reverse record, and many carriers do not publish
names for internal interfaces.
- The naming on those later hops is a Microsoft convention, not a standard.
The city codes are airport-style:
del01 Delhi, bom01 Mumbai, pnq20 and
pnq21 Pune. The role codes ibr, rwa and owr mean internal backbone,
regional wide-area and outer wide-area router respectively, again by that
operator’s convention. Interface prefixes ae, be and po all mean
several physical links bonded into one logical link; different vendors use
different words for the same idea.
- Useful invocations:
traceroute -n 20.207.73.82 # numeric only, no reverse DNS
traceroute -I -n 20.207.73.82 # ICMP probes, needs sudo on macOS
traceroute -q 1 -n 20.207.73.82 # one probe per hop, less noise
mtr -n 20.207.73.82 # continuous, shows loss per hop
- The strongest reading discipline: separate what a trace proves from what it
suggests. It proves which interfaces answered. It suggests, but never
proves, the forward path, and it says nothing at all about the reverse path,
which can be completely different.
WORDS24.10.6 remember these#
- Traceroute — a tool that lists the routers on the way — a TTL-incrementing
probe tool relying on ICMP time-exceeded replies, RFC 792.
- TTL — the countdown that stops packets looping forever — Time To Live, an
8-bit IPv4 header field decremented at each hop.
- ICMP time-exceeded — the complaint a router sends when a packet expires —
ICMP type 11, the message that makes traceroute possible.
- Hop — one router along the path — one decrement of TTL.
- Asterisk in a trace — no reply came back — an unanswered probe, commonly
caused by ICMP rate limiting or policy, not by a fault.
- Reverse DNS — turning an address back into a name — a PTR record lookup in
the in-addr.arpa zone.
24.11 Static and dynamic addresses, and how yours is chosen#
PLAIN24.11.1 in simple words#
- Nobody typed 192.168.0.x into the reader’s laptop. It was handed over
automatically.
- The thing that hands it over is called DHCP. Your laptop shouts “does anyone
have an address for me”, and the router answers.
- The router does not give the address away permanently. It lends it, for a
period called a lease.
- Before the lease runs out, your machine asks to keep it, and normally gets the
same one back. That is why your laptop’s address usually looks stable.
- The same thing happens one level up. Your router asks your provider for a
public address, and gets one on loan.
- That loan can end. When it does, you may get a different public address. This
is why home connections are said to have a dynamic address.
- A static address is one that never changes, arranged deliberately and
usually paid for.
- If you want to run something at home that people can find by name, and your
address keeps changing, you need a service that updates the name every time
the address moves. That is dynamic DNS.
- Businesses pay for static addresses because servers, mail and remote access
all break when the address moves.
PLAIN24.11.2 a picture in your head#
- Think of a library that lends reading-room desks rather than selling them.
- You arrive, ask for a desk, and are given number 24 for four hours.
- Nobody else gets desk 24 while your loan runs.
- Halfway through, at two hours, you are asked whether you want to keep it. You
say yes and the four hours restart. You keep the same desk.
- If you leave without saying anything, the desk goes back into the pool once
the four hours are up, and someone else may get it.
- A subscriber who pays extra gets a reserved desk with their name on it, every
day, guaranteed. That is a static address.
Where this comparison breaks: the library knows you by face. DHCP identifies you
by a hardware identifier your machine sends, and modern phones and laptops
deliberately randomize that identifier for privacy. So your own device may be
handed a different address on purpose, on a network it has used for years, and
that is a feature rather than a fault.
PLAIN24.11.3 a worked example#
- The four steps of DHCP, in order, with the names engineers use.
| Step |
Who sends |
Meaning |
| DISCOVER |
the laptop |
anyone out there |
| OFFER |
the router |
you can have this one |
| REQUEST |
the laptop |
yes, I take it |
| ACK |
the router |
confirmed, here are details |
- The first message goes from source 0.0.0.0 to destination
255.255.255.255, because the laptop has no address and does not know the
server’s address.
- The ACK carries more than an address. It typically carries the mask, the
gateway, the DNS servers and the lease time.
- For the reader that would be: address 192.168.0.x, mask 255.255.255.0,
gateway 192.168.0.1, and a DNS server.
- Note a detail from the reader’s own session: their DNS resolver was 1.1.1.1,
Cloudflare’s public resolver, not the router. So either the router was
configured to hand out 1.1.1.1, or the laptop was set manually and ignored
what DHCP offered. DHCP suggests; the operating system may override.
- On macOS you can see the whole lease, raw:
ipconfig getpacket en0
# yiaddr = 192.168.0.24
# subnet_mask (ip): 255.255.255.0
# router (ip_mult): {192.168.0.1}
# lease_time (uint32): 0x15180 (86400 seconds = 24 hours)
yiaddr is the field name in the protocol and means “your address”. It has
been called that since 1993.
- For the public side, many home connections in India and elsewhere use PPPoE:
the router logs in with a username and password, and the address is
negotiated as part of that session rather than by DHCP.
- With PPPoE, the address usually changes when the session drops and
reconnects, which is why rebooting a router often changes your public
address, and sometimes does not.
PLAIN24.11.4 what is really happening inside#
- A DHCP lease has three timers, not one.
- The full lease time is how long the address is valid.
- At half the lease time, the client tries to renew directly with the server
that gave it the address. This is called T1.
- At seven-eighths of the lease time, if renewal failed, the client broadcasts
to any server that will listen. This is called T2.
- If nothing answers by the end, the client must stop using the address. In
practice most operating systems then fall back to a link-local
169.254.x.x address, which is the symptom described in section 24.4.
- Because renewal starts at half the lease, a machine that stays switched on
keeps the same address indefinitely. Addresses only really move when a
machine is away long enough for the lease to expire and be reissued.
- On the public side with PPPoE, the address is negotiated by a sub-protocol
during session setup, not by DHCP at all. The provider’s access
concentrator picks an address from its pool and offers it.
- Providers vary in how sticky that is. Some effectively give the same address
for months. Some rotate it every 24 hours deliberately.
- Under carrier-grade NAT the question changes shape entirely. Your router’s
outside address may be stable while the public address the world sees changes
whenever the carrier NAT reassigns you.
TECHNICAL24.11.5 the engineer’s version#
- DHCP is RFC 2131, March 1997, with options in RFC 2132. It extends BOOTP from
RFC 951, September 1985, and reuses its packet format, which is why the field
is still called
yiaddr.
- The client sends from UDP port 68 to UDP port 67. The exchange is
DHCPDISCOVER, DHCPOFFER, DHCPREQUEST, DHCPACK, commonly abbreviated DORA.
- Renewal timers default to T1 at 0.5 of the lease and T2 at 0.875 of the
lease, per RFC 2131. Both can be set explicitly with options 58 and 59.
- Typical lease durations by deployment:
| Environment |
Typical lease |
| Home router |
24 hours |
| Corporate wired |
8 days |
| Public Wi-Fi, cafe |
1 to 2 hours |
| Conference network |
10 to 30 minutes |
- Client identity is normally the MAC address in the
chaddr field, optionally
overridden by option 61. Since Android 10 in 2019 and iOS 14 in 2020, and in
recent macOS releases on the desktop, devices rotate a randomized MAC per
network by default. Address reservations keyed on MAC therefore need the
randomization turned off for that network.
- A DHCP reservation, sometimes called static DHCP, pins one address to one
client identifier. It is not the same as a static address configured on the
host: the client still leases, it simply always receives the same value.
- PPPoE is RFC 2516, February 1999. It carries PPP over Ethernet; the address
is assigned during the IPCP negotiation phase of PPP, from RFC 1332. The
provider side is a BRAS or BNG, a broadband remote access server or broadband
network gateway.
- Dynamic DNS updates are standardized in RFC 2136, April 1997. Consumer
services predate and largely ignore it, using proprietary HTTP endpoints
instead; most home routers have built-in support for two or three of them.
Practical caveat: dynamic DNS is useless behind carrier-grade NAT, because
the name will resolve to an address that will not accept your inbound
traffic.
- Static addresses cost money for a reason that has nothing to do with
technology. They consume a scarce public address permanently, whereas dynamic
pools let a provider serve more subscribers than it has addresses, because
not all are online at once. That over-subscription is the whole economic
point.
- Observation commands:
ipconfig getpacket en0 # the full DHCP lease on macOS
ipconfig getoption en0 lease_time # just the lease duration
sudo ipconfig set en0 DHCP # force a fresh DHCP exchange
netstat -rn | grep default # the gateway the lease installed
WORDS24.11.6 remember these#
- DHCP — the system that hands out addresses automatically — Dynamic Host
Configuration Protocol, RFC 2131, UDP ports 67 and 68.
- Lease — a borrowed address with an expiry — a time-bounded binding, renewed
at T1 and rebound at T2.
- DORA — the four-step handshake — DISCOVER, OFFER, REQUEST, ACK.
- Static address — one that never changes — a manually configured or
permanently allocated address, usually a paid service.
- Dynamic address — one that can change — an address from a provider pool, held
only for the duration of a lease or session.
- Reservation — always getting the same address from DHCP — a static mapping
from client identifier to address inside the DHCP server.
- PPPoE — logging in to your broadband with a username and password — PPP over
Ethernet, RFC 2516, with addressing negotiated by IPCP.
- Dynamic DNS — a name that follows your changing address — automated updating
of an A record, standardized as RFC 2136, defeated by carrier-grade NAT.
24.12 IPv6 in brief#
PLAIN24.12.1 in simple words#
- IPv6 is the replacement for the addressing scheme this whole chapter has
described. It uses 128 bits instead of 32.
- Four times the bits does not mean four times the addresses. Each extra bit
doubles the count. So 128 bits gives about 340 undecillion addresses, a 3
followed by 38 digits.
- That is enough to give every grain of sand on earth its own network, with
room left over. The size is deliberate and slightly absurd, so that nobody
ever has to do this again.
- Because the numbers are so long, they are written in hexadecimal, which uses
the digits 0 to 9 and the letters a to f, in eight groups separated by
colons.
- There are two shortening rules, and only two, so the addresses stay
readable.
- IPv6 exists because IPv4 ran out, exactly as section 24.5 described.
- With enough addresses for everyone, NAT is no longer needed. Every device can
have its own real address again.
- The reader’s own machine reported IPv6 as
(none). That means their
connection offered no IPv6 at all, so every packet in this chapter’s story
travelled over IPv4, through the provider’s private core and its
translation.
- Chapter 34 covers IPv6 properly. This section is only enough to place it in
the story of addressing.
PLAIN24.12.2 a picture in your head#
- Think of telephone numbers being replaced by a scheme with room for every
person, object and appliance on the planet.
- The new numbers are longer, so nobody memorizes them. You rely on your
contacts list. In networking that contacts list is DNS.
- The old and the new cannot dial each other. A new-scheme phone cannot ring an
old-scheme phone at all.
- So during the change, every phone must be able to use both schemes. That is
dual stack.
- Nobody wants to be first, because being first costs money and buys nothing
until others follow. Everyone wants to be second.
Where this comparison breaks: phone numbers could be translated between schemes
by an exchange, and countries did exactly that when they lengthened numbers.
IPv4 and IPv6 are genuinely different protocols with different header layouts,
and translation between them is lossy and awkward. That incompatibility, not
laziness, is the main reason the change has taken three decades.
PLAIN24.12.3 a worked example#
- Full form, all 32 hex digits written out:
2001:0db8:0000:0000:0000:ff00:0042:8329
- Rule one: drop leading zeros inside each group. Not all zeros, only leading
ones.
2001:db8:0:0:0:ff00:42:8329
- Rule two: replace the longest run of all-zero groups with a double colon,
once and only once in an address.
2001:db8::ff00:42:8329
- Once only, because two double colons would be ambiguous. A reader could not
tell how many zero groups belonged to each.
- A second example, a link-local address of the kind macOS shows on every
interface:
fe80:0000:0000:0000:0204:61ff:fe9d:f156
fe80::204:61ff:fe9d:f156
- Note that
0204 became 204, losing only the leading zero, and that 61ff
was untouched because its zeros are not leading.
- Two special short ones:
| Meaning |
Full |
Short |
| Loopback |
0000: ... :0001 |
::1 |
| Unspecified |
0000: ... :0000 |
:: |
- The main address types, by their leading bits:
| Type |
Prefix |
Use |
| Global unicast |
2000::/3 |
routable on the internet |
| Link-local |
fe80::/10 |
this link only, always present |
| Unique local |
fc00::/7 |
private, like RFC 1918 |
| Multicast |
ff00::/8 |
groups |
| Documentation |
2001:db8::/32 |
books and manuals |
- Every IPv6 interface has a link-local address whether or not it has anything
else. That is required, not optional, and it is what neighbour discovery
runs over.
PLAIN24.12.4 what is really happening inside#
- IPv6 does not use DHCP by default. A machine can configure itself.
- It works like this. The machine sends a router solicitation on the link. A
router replies with a router advertisement carrying a prefix, usually 64
bits long.
- The machine takes that 64-bit prefix and invents its own 64-bit second half.
Joining them gives a complete address.
- That is called SLAAC, stateless address autoconfiguration. Stateless because
no server keeps a record of who has what.
- Originally the second half was derived from the hardware address, which meant
the same machine had a recognizable address on every network it visited. That
is a privacy disaster: you could be tracked across cafes and cities.
- So privacy addresses were added. The machine generates random second halves,
uses one for outgoing connections, and replaces it every day or so.
- This is why a machine with IPv6 usually shows several addresses at once on
one interface: a link-local one, a stable one, and one or more temporary
ones.
- During the transition most machines run both protocols side by side. When you
open a connection to a name that has both kinds of address, the machine races
them and uses whichever answers first.
- The reader’s machine had no IPv6 at all, so none of this applied. Every
attempt to reach 20.207.73.82 went over IPv4, and had no alternative path to
fall back on.
TECHNICAL24.12.5 the engineer’s version#
- IPv6 is specified in RFC 8200, July 2017, Internet Standard STD 86, which
obsoletes RFC 2460 from December 1998. The first specification was RFC 1883,
December 1995.
- The addressing architecture is RFC 4291, February 2006. The canonical text
representation is RFC 5952, August 2010.
- RFC 5952 states the rules as requirements, not preferences: leading zeros
must be suppressed;
:: must shorten the longest zero run; :: must not be
used for a single zero group; on a tie the leftmost run wins; hexadecimal
letters must be lowercase.
- Address space: 2 to the power 128, exactly
340,282,366,920,938,463,463,374,607,431,768,211,456. Global unicast is
currently allocated only out of 2000::/3, which is one eighth of the total,
leaving the rest untouched for the future.
- Unique local addresses are RFC 4193, October 2005. The block is fc00::/7, but
in practice only fd00::/8 is used, with 40 random bits chosen by the site so
that two organizations merging almost certainly do not collide. That random
collision-avoidance is the direct lesson learned from RFC 1918 overlap.
- SLAAC is RFC 4862, September 2007, using ICMPv6 Neighbor Discovery from RFC
4861. Temporary privacy addresses are RFC 8981, February 2021, which
obsoletes RFC 4941 from September 2007.
- Dual stack is RFC 4213, October 2005. Happy Eyeballs version 2, RFC 8305,
December 2017, is the algorithm that races an IPv6 and an IPv4 connection
attempt with a short head start for IPv6, and is why a broken IPv6 path no
longer stalls a browser for thirty seconds.
- Header differences that matter in practice: the IPv6 header is a fixed 40
bytes with no options inline and no header checksum; routers never fragment,
so path MTU discovery is mandatory; the minimum link MTU is 1280 bytes.
- Why thirty years:
| Reason |
Effect |
| No wire compatibility |
v6-only cannot reach v4-only |
| No first-mover benefit |
cost now, benefit later |
| NAT relieved pressure |
the crisis felt survivable |
| Equipment and staff cost |
every device and skill set |
| Dual stack doubles work |
two of everything to operate |
- Measured adoption is published live by Google as the share of its users
reaching it over IPv6. It crossed 10 percent in 2016 and has grown steadily
since; because that figure moves every month, look it up rather than trusting
a printed number, including this one.
- Observation on macOS:
ifconfig en0 inet6, netstat -rn -f inet6, and
ping6 -c1 ipv6.google.com. If the last of these fails and ifconfig shows
only an fe80:: address, you have link-local IPv6 only and no global
connectivity, which is exactly the reader’s situation reported as
IPv6: (none).
WORDS24.12.6 remember these#
- IPv6 — the 128-bit replacement for IPv4 — Internet Protocol version 6, RFC
8200, STD 86.
- Hextet — one group of four hex digits — a 16-bit field of an IPv6 address,
eight per address.
- Zero compression — the double colon shortcut —
:: replacing the longest run
of all-zero 16-bit fields, once per address, per RFC 5952.
- Global unicast — an address the internet can route to — currently allocated
from 2000::/3.
- Link-local — the address every IPv6 interface always has — fe80::/10, used by
neighbour discovery, never routed off the link.
- Unique local — IPv6’s version of a private address — fc00::/7, used as
fd00::/8 with 40 random bits, RFC 4193.
- SLAAC — a machine configuring its own address from a router hint — stateless
address autoconfiguration, RFC 4862.
- Privacy address — a temporary random address that changes daily — temporary
address extensions, RFC 8981.
- Dual stack — running both protocols at once — RFC 4213, with connection
racing by Happy Eyeballs, RFC 8305.
24.13 Practical: finding your own addresses on macOS#
PLAIN24.13.1 in simple words#
- Four facts describe your position on the network: your own address, your
mask, your gateway, and your public address.
- Your own address is what your machine is called on the local network.
- Your mask says how big that local network is.
- Your gateway is the router you hand everything else to. For the reader it is
192.168.0.1.
- Your public address is what the rest of the internet sees. It is usually
different from your own address, because of NAT.
- Getting all four takes about thirty seconds and four commands.
- Comparing two of them tells you instantly whether your provider is running
carrier-grade NAT.
PLAIN24.13.2 a picture in your head#
- Think of checking your own postal details before complaining that a parcel
never arrived.
- Your flat number is your local address. The building’s street number is your
public address. The porter is the gateway. The postcode area is the mask.
- If someone tells you the parcel was delivered to a street number you have
never heard of, then something in the middle is redirecting your post, and
you need to know that before you argue with anyone.
Where this comparison breaks: you can walk outside and read your building’s
street number. You cannot see your public address from inside your own machine
at all. You must ask a server on the internet to tell you what it sees. That is
not a convenience, it is a fundamental consequence of NAT.
PLAIN24.13.3 a worked example#
- The four commands, in order.
# 1. my own address on Wi-Fi
ipconfig getifaddr en0
# 192.168.0.24
# 2. my mask, and the address again, with more detail
ifconfig en0 | grep 'inet '
# inet 192.168.0.24 netmask 0xffffff00 broadcast 192.168.0.255
# 3. my gateway
netstat -rn -f inet | grep default
# default 192.168.0.1 UGScg en0
# 4. what the internet sees
curl -s https://api.ipify.org; echo
- Note that macOS prints the mask in hexadecimal.
0xffffff00 is
255.255.255.0, which is a /24, which matches section 24.2 exactly.
- Converting is easy:
ff is 255, 00 is 0. So 0xffffff00 reads as 255,
255, 255, 0.
- One command gives three of the four at once:
networksetup -getinfo "Wi-Fi"
# IP address: 192.168.0.24
# Subnet mask: 255.255.255.0
# Router: 192.168.0.1
- Now the carrier-grade NAT test. Take the public address from step 4. Then
open your router’s status page and read the address on its outside, or WAN,
interface.
- Decide as follows:
Is the router's WAN address in 100.64.0.0/10,
10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16 ?
|
+-- yes -> you are behind carrier-grade NAT.
|
+-- no --> is it the same as what curl reported ?
|
+-- yes -> a normal public address, no CGNAT
|
+-- no --> something translates in between:
CGNAT, or a proxy, or a VPN
- Do the VPN check first, because it produces the same symptom. The reader’s
machine showed several
utun interfaces; if one of them is active and
carrying the default route, the public address you see is the VPN’s, not your
provider’s.
ifconfig | grep -A2 '^utun' # are any tunnels up
netstat -rn -f inet | grep default # which interface is default
PLAIN24.13.4 what is really happening inside#
ipconfig getifaddr reads the address the operating system has stored for
that interface. No packets are sent. It is instant and works offline.
netstat -rn prints the routing table straight from the kernel. The line
marked default is the route used for anything not matching a more specific
entry.
curl https://api.ipify.org is completely different in kind. It makes a real
connection to a real server on the internet, and that server reports the
source address it saw.
- So that command measures what the world sees after every translation on the
path, including your router, any carrier NAT, and any VPN.
- The DNS-based alternative asks a resolver the same question over DNS rather
than HTTP. It is worth knowing because it works when HTTP is blocked but DNS
is not, and because it takes a different path.
- If those two methods disagree, that itself is information: something is
treating your web traffic and your DNS traffic differently.
- None of these commands can see the carrier NAT box itself. You infer it from
the difference between two numbers, which is the only tool you have from
inside.
TECHNICAL24.13.5 the engineer’s version#
- Command reference, macOS, with what each actually queries:
| Command |
Source of truth |
| ipconfig getifaddr en0 |
configd stored state |
| ifconfig en0 |
kernel interface list |
| netstat -rn -f inet |
kernel routing table |
| route -n get default |
kernel route lookup |
| ipconfig getpacket en0 |
the stored DHCP lease |
| networksetup -getinfo |
the system preference |
| curl to a reflector |
a live remote observation |
- The interface name is not always
en0. On many Macs en0 is Wi-Fi, but on
models with Ethernet it may be wired, with Wi-Fi on en1. Resolve it
properly rather than guessing:
networksetup -listallhardwareports
route -n get default | awk '/interface/{print $2}'
- Reflector services worth knowing, all returning plain text:
api.ipify.org, ifconfig.me, icanhazip.com. Prefer HTTPS. The DNS
method, dig +short myip.opendns.com @resolver1.opendns.com, avoids HTTP
entirely.
- To force IPv4 or IPv6 explicitly, use
curl -4 and curl -6. On a dual
stack host these can legitimately return different addresses, and a machine
reporting IPv6: (none) as the reader’s did will simply fail on curl -6.
- For a fuller picture,
scutil --nwi prints macOS network information
including which interfaces are considered usable for IPv4 and IPv6, and
arp -an shows the neighbours your machine has actually spoken to on the
local segment, which will include 192.168.0.1.
- If the WAN address is in 100.64.0.0/10, the diagnosis is certain and needs no
further evidence: RFC 6598 space exists only for the link between a carrier
NAT and customer equipment.
- If the WAN address is RFC 1918 space, as the reader’s hop 2 at 172.31.0.17
suggests may be the case here, the diagnosis is very likely but not certain,
because a modem in bridge or router mode can also produce that pattern
locally.
- Practical consequence to check next: if you are behind carrier-grade NAT,
stop trying to fix inbound problems with port forwarding, and ask the
provider for a public address, or use an outbound-initiated tunnel service
instead.
WORDS24.13.6 remember these#
- Gateway — the router you hand outbound traffic to — the next hop of the
default route, 0.0.0.0/0.
- Default route — where anything unmatched goes — the least specific routing
table entry, always losing to any longer prefix match.
- WAN address — the address on your router’s outside — the address the provider
assigned to the customer equipment, by DHCP or PPPoE.
- Reflector — a server that tells you how you look from outside — an HTTP or
DNS service echoing the observed source address.
- Hexadecimal netmask — the
0xffffff00 form macOS prints — the same 32-bit
mask written in base 16, two digits per octet.
- scutil — the macOS tool for network state — the System Configuration
framework utility,
scutil --nwi for reachability information.
24.98 Common wrong ideas#
- Wrong: an IP address identifies a person. Right: it identifies a network
interface at a moment in time. Under NAT it identifies a whole household; under
carrier-grade NAT it can identify hundreds of households at once.
- Wrong: an IP address identifies a device. Right: it identifies one interface.
One machine can hold many addresses at once across Wi-Fi, Ethernet, loopback
and every VPN tunnel, and the reader’s macOS session showed several
utun
interfaces doing exactly that.
- Wrong: private addresses are more secure. Right: they are not routable, which
is different from being protected. Anything on your own network reaches them
freely, and most real attacks arrive through connections you started, which
NAT permits by design.
- Wrong: NAT is a firewall. Right: NAT drops unsolicited inbound traffic as a
side effect of not knowing where to send it. A firewall makes deliberate
policy decisions, inspects traffic and can be audited. Relying on NAT for
security means relying on an accident.
- Wrong: changing your IP address hides you. Right: it changes one weak
identifier. Cookies, browser fingerprints, logins and DNS queries all survive
the change, and under carrier-grade NAT your address was never uniquely yours
to begin with.
- Wrong: 172.16.0.0/12 means everything starting 172.16. Right: it covers
172.16.0.0 through 172.31.255.255, which is why the reader’s hops at
172.31.0.17, 172.26.22.235 and 172.16.18.33 are all private.
- Wrong: private addresses in a traceroute prove you are behind carrier-grade
NAT. Right: they prove those router interfaces are privately numbered. The
proof of carrier-grade NAT is comparing your router’s WAN address with what a
public reflector reports.
- Wrong: my router’s address 192.168.0.1 clashes with my neighbour’s. Right: it
cannot, because private addresses are never carried on the public internet.
The two networks never meet.
- Wrong: a hop showing three addresses is an error or a loop. Right: it is
equal-cost multi-path load balancing across parallel links, which is exactly
what the reader’s hops 5 and 6 show.
- Wrong: IPv6 is just IPv4 with longer addresses, so switching is easy. Right:
it is a separate protocol with a different header, and an IPv6-only host
cannot reach an IPv4-only host at all. That incompatibility is why the
transition has taken three decades.
24.99 Chapter summary in 20 lines#
- An IPv4 address is 32 bits labelling one network interface, not a device and
not a person.
- Written as four decimal octets, giving 2 to the power 32, exactly
4,294,967,296 possible addresses.
- 192.168.0.1 is 11000000 10101000 00000000 00000001 in binary, and 3232235521
as a single integer.
- Every address splits into a network part and a host part; the subnet mask
says where, and CIDR notation writes the mask as a count of bits.
- For 192.168.0.0/24 the network is 192.168.0.0, the broadcast 192.168.0.255,
the usable range 192.168.0.1 to 192.168.0.254, and the host count 254.
- RFC 1918, February 1996, BCP 5, reserves 10.0.0.0/8, 172.16.0.0/12 and
192.168.0.0/16 for private use.
- 172.16.0.0/12 runs from 172.16.0.0 to 172.31.255.255, so the reader’s hops at
172.31.0.17, 172.26.x and 172.16.18.33 are all private addresses.
- Private addresses never travel on the public internet, which is why every
home can use 192.168.0.1 with no conflict.
- Other reserved blocks include 127.0.0.0/8 loopback, 169.254.0.0/16
link-local, 100.64.0.0/10 shared space for carrier NAT, and 224.0.0.0/4
multicast.
- The IANA free pool was emptied on 31 January 2011 and declared depleted on 3
February 2011; APNIC, serving India, hit its final block on 15 April 2011.
- Classful addressing wasted enormous space by offering only three block
sizes; CIDR replaced it in 1993 and is now RFC 4632.
- NAT rewrites the source address on the way out and restores it on the way
back, using a table keyed on the 5-tuple.
- What home routers actually run is PAT, also called NAPT or NAT overload,
which rewrites the port as well as the address.
- A port is a 16-bit number identifying one conversation, ranged 0 to 1023
well-known, 1024 to 49151 registered, 49152 to 65535 ephemeral per RFC 6335.
- Ports are what let one public address carry tens of thousands of
simultaneous conversations; without them NAT would be pointless.
- NAT breaks inbound connections, needs port forwarding for servers, and forces
peer-to-peer software to use STUN, TURN and ICE with hole punching.
- NAT was proposed in RFC 1631 in 1994 as a short-term measure; it is honestly
a workaround, not a design, and it violates the end-to-end principle.
- Carrier-grade NAT applies the same trick at the provider, costing you inbound
connections, a shared reputation and much harder diagnosis.
- The reader’s first six hops read private, private, public, private, private,
private, which proves the provider numbers its core from RFC 1918 space and
strongly suggests, without proving, carrier-grade translation.
- IPv6 with 128 bits removes the shortage entirely, but the reader’s machine
reported IPv6 as none, so every packet in this story travelled the crowded
IPv4 path; Chapter 34 takes IPv6 further.