IP Subnetting: the critical facts
Everything you need to read, plan and troubleshoot subnets — IPv4 and IPv6.
What is a subnet?
An IP network is split into subnets so routers know which addresses live together on one link. The prefix length (the /24 in 192.168.1.0/24) says how many leading bits of the address identify the network; the remaining bits identify hosts inside it. Fewer network bits = bigger subnet; more network bits = more, smaller subnets.
IPv4 essentials
- 32-bit addresses, written as four decimal octets (
192.168.1.10). - Each subnet reserves two addresses: the lowest (network address) and the highest (broadcast). Usable hosts = 2host bits − 2.
- Exceptions: a
/31has 2 usable addresses (point-to-point links, RFC 3021) and a/32is a single host route. - The wildcard mask is the inverted netmask — used in Cisco ACLs and OSPF statements.
IPv4 CIDR table
| CIDR | Netmask | Total IPs | Usable hosts | Typical use |
|---|---|---|---|---|
/32 | 255.255.255.255 | 1 | 1 | Host route / loopback |
/31 | 255.255.255.254 | 2 | 2 | Point-to-point link |
/30 | 255.255.255.252 | 4 | 2 | Legacy point-to-point |
/29 | 255.255.255.248 | 8 | 6 | Small DMZ / static block from ISP |
/28 | 255.255.255.240 | 16 | 14 | Small office |
/27 | 255.255.255.224 | 32 | 30 | Branch site |
/26 | 255.255.255.192 | 64 | 62 | Department VLAN |
/25 | 255.255.255.128 | 128 | 126 | Larger VLAN |
/24 | 255.255.255.0 | 256 | 254 | The classic LAN |
/23 | 255.255.254.0 | 512 | 510 | Two /24s merged (watch broadcast volume) |
/22 | 255.255.252.0 | 1,024 | 1,022 | Campus VLAN / large DHCP scope |
/20 | 255.255.240.0 | 4,096 | 4,094 | Site aggregate |
/16 | 255.255.0.0 | 65,536 | 65,534 | Organisation aggregate |
/8 | 255.0.0.0 | 16,777,216 | 16,777,214 | 10.0.0.0/8 private space |
Reserved & special IPv4 ranges (memorise these)
| Range | Purpose |
|---|---|
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 | Private addressing (RFC 1918) — never routed on the internet |
100.64.0.0/10 | Carrier-grade NAT (RFC 6598) — seen on ISP connections without a real public IP |
127.0.0.0/8 | Loopback (localhost) |
169.254.0.0/16 | Link-local / APIPA — a device showing this failed to get DHCP |
192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 | Documentation ranges (safe for examples) |
224.0.0.0/4 | Multicast |
240.0.0.0/4 | Reserved / experimental |
Subnetting by hand: a 60-second method
- Take the prefix, e.g.
/27. Host bits = 32 − 27 = 5, so the block size is 25 = 32. - Subnets start at multiples of the block size in the "interesting" octet: .0, .32, .64, .96, .128 …
- Your address falls in the block at or below it:
10.1.1.70/27→ network10.1.1.64, broadcast10.1.1.95, hosts.65–.94.
Use the calculator to verify your working.
IPv6 essentials
- 128-bit addresses, eight groups of 16-bit hex (
2001:0db8:0000:0000:0000:0000:0000:0001). - Compression rules: leading zeros in a group drop (
0db8→db8), and one run of all-zero groups collapses to::(only once per address). - There is no broadcast in IPv6 — multicast does that job — and no "usable hosts minus 2" rule.
- A LAN is a /64. Always. SLAAC (auto-addressing) only works on /64s. Don't try to "save space" by using longer prefixes on host networks.
- Routing/point-to-point links commonly use
/127; loopbacks/128. - Sites typically receive a
/48(65,536 /64 subnets) or a/56(256 /64s, typical residential) from their provider. Subnet by carving the bits between your allocation and /64.
Anatomy of a global unicast address
A typical address splits into three parts. Everything you do when "subnetting IPv6" happens in the middle one:
| Global routing prefix | Subnet ID | Interface ID | |
|---|---|---|---|
| Example | 2001:db8:acad | 00ff | 0000:0000:0000:0001 |
| Bits | 48 (from your provider) | 16 (yours to plan) | 64 (identifies the host) |
| Who controls it | ISP / RIR | You | The device (SLAAC) or you (static/DHCPv6) |
With a /48 allocation you get a 16-bit Subnet ID — 65,536 LANs — and you never think about host counts again: every LAN holds 264 addresses regardless.
Subnet on the nibble
Each hex digit is 4 bits — a nibble. Subnet on nibble boundaries (/48 → /52 → /56 → /60 → /64) and prefixes stay readable: each step changes exactly one hex digit, so you can see subnet membership at a glance and delegate reverse DNS (ip6.arpa) cleanly. A /54 "works" but makes humans and DNS miserable.
| Inside a /48 | You get | Each is |
|---|---|---|
split to /52 | 16 blocks | 4,096 /64s — e.g. one per region or building |
split to /56 | 256 blocks | 256 /64s — e.g. one per site or customer |
split to /60 | 4,096 blocks | 16 /64s — e.g. one per small office |
split to /64 | 65,536 LANs | one VLAN each |
Try it live: put 2001:db8::/48 into the calculator and use "Split this subnet".
A worked /48 plan
A common convention: spend the first nibble of the Subnet ID on function, the rest on instance:
| Prefix | Use |
|---|---|
2001:db8:acad:0000::/64 | Network infrastructure (loopbacks, management) |
2001:db8:acad:1xx::/64 | Staff VLANs (101 = site 1, 102 = site 2…) |
2001:db8:acad:2xx::/64 | Servers / DMZ |
2001:db8:acad:3xx::/64 | Guest / IoT |
2001:db8:acad:fxx::/64 | Labs and testing |
Hex digits in prefixes can encode meaning (site number, VLAN id) — something IPv4 never had room for. Many shops simply put the VLAN number in the subnet ID: VLAN 20 → …:20::/64.
How hosts get addresses (and why /64 is sacred)
- SLAAC (stateless autoconfig): the router advertises the /64 prefix; hosts build their own interface ID. This is the default for most devices and only works on a /64.
- Interface IDs were classically EUI-64 (the MAC with
ff:feinserted in the middle and one bit flipped) — recognisable byff:fein the middle of the IID. Modern OSes use random/opaque IDs instead (RFC 7217 stable + RFC 4941 temporary privacy addresses). - Several addresses per interface is normal: a link-local (
fe80::…), a stable global address, and one or more short-lived privacy addresses used for outbound connections. Don't "fix" it. - DHCPv6 exists (managed addressing + options), but Android does not support it — any BYOD network must run SLAAC (usually with RDNSS for DNS).
- Routers are found via Router Advertisements, not DHCP — the default gateway is the router's link-local address, which is why a route print shows a gateway starting with
fe80::.
IPv6 subnetting facts & myths
- All 264 addresses in a LAN are usable. There's no network or broadcast address to subtract. (The all-zero interface ID —
2001:db8:1:1::— is the Subnet-Router anycast address; leave it to routers.) - There is no ARP. Neighbour Discovery (NDP) uses multicast — a host resolves a neighbour via its solicited-node group (
ff02::1:ffxx:xxxx), so it doesn't interrupt every machine on the LAN the way ARP broadcasts do. - "We'll NAT IPv6" is a habit to unlearn. Every device gets a globally unique address; security comes from the firewall, not address translation. Stateful "allow established, deny inbound" gives the same protection NAT appeared to give.
- A /64 cannot be port-scanned. At a million probes per second, sweeping one /64 takes roughly 585,000 years — attackers harvest addresses from DNS and logs instead, so DNS hygiene matters more, not less.
- Don't subnet between /64 and /127. A /112 or /120 breaks SLAAC and confuses NDP-related features; the only sanctioned long prefixes are
/127(point-to-point, RFC 6164) and/128(loopbacks). - The smallest allocation routed in the global table is a /48 — if you plan to multihome with provider-independent space, that's what you request from APNIC.
- ULA and global addresses coexist fine. A common design: ULA (
fd…/48, generated with a random 40-bit ID per RFC 4193 — don't just usefd00::/48) for stable internal services, plus provider space for internet traffic. Hosts pick the right source address automatically (RFC 6724). - Documentation prefixes:
2001:db8::/32and the newer3fff::/20(RFC 9637, 2024) — safe for examples, never route them. - Multicast scope is built into the address:
ff02::…= this link only,ff05::…= this site. Well-known groups:ff02::1all nodes,ff02::2all routers,ff02::5/::6OSPFv3,ff02::1:2DHCPv6 relays. - Dual-stack means two networks to secure. If IPv6 is live but unmanaged, a rogue Router Advertisement can hijack traffic — enable RA Guard on switches, or manage IPv6 deliberately.
IPv6 prefix table
| Prefix | Contains | Typical use |
|---|---|---|
/32 | 65,536 /48s | ISP / LIR allocation |
/48 | 65,536 /64s | One site / customer |
/56 | 256 /64s | Residential / small-business delegation |
/64 | 18.4 quintillion addresses | One LAN / VLAN |
/127 | 2 addresses | Router-to-router link (RFC 6164) |
/128 | 1 address | Host route / loopback |
Recognising IPv6 address types at a glance
| Starts with | Type | Meaning |
|---|---|---|
2xxx: / 3xxx: | Global unicast (2000::/3) | Public, internet-routable |
fe80: | Link-local (fe80::/10) | Every IPv6 interface has one; valid only on its own link — this is what next-hops and neighbours use |
fd (or fc) | Unique local, ULA (fc00::/7) | The IPv6 analogue of RFC 1918 private space |
ff | Multicast (ff00::/8) | ff02::1 = all nodes, ff02::2 = all routers on link |
::1 | Loopback | localhost |
2001:db8: | Documentation (RFC 3849) | Examples only — never configure in production |
::ffff:a.b.c.d | IPv4-mapped | An IPv4 address represented inside the IPv6 API |
Public vs private IP — and "what is my IP?"
Devices on a typical network hold a private address (RFC 1918 for IPv4, ULA for IPv6) and reach the internet through NAT, which rewrites traffic to your router's public address. That public address is what websites — including the "Your public IP" panel on this site — see. If the panel shows an address starting with 100.64–100.127, your ISP is using carrier-grade NAT and you don't have a dedicated public IPv4 address. IPv6 usually skips NAT entirely: your device's global unicast address is public (firewalled, not translated).
Common pitfalls checklist
- Overlapping subnets across VPN sites — renumber or NAT; routers can't disambiguate.
- Gateway outside the subnet — a host with
10.1.2.20/25can't use gateway10.1.2.129(that's the other half of the /24). - Assigning the network or broadcast address to a host (IPv4) — instant connectivity failure.
- DHCP scope wider than the subnet, or two scopes overlapping — intermittent duplicate-IP chaos.
- IPv6 is on by default on modern OSes — if you don't manage it, you may have an unmanaged parallel network. Plan it, don't disable it.
Regular Expressions: the practical guide
A working reference for regex — the pattern language for finding, validating and extracting text. Written for the JavaScript flavour, which is what the Regex tester on this site runs.
How matching works
- A regex is a pattern plus optional flags. The engine tries to match starting at position 0; if that fails it slides one character right and tries again.
- The leftmost match wins, and by default you get only the first one — add the
gflag to find them all. - You typically use it to test ("does this match?"), extract (pull out captured groups) or replace text.
Literals vs metacharacters
Letters and digits match themselves. These characters are special and must be escaped with a backslash to match them literally: . ^ $ * + ? ( ) [ ] { } | \. For example, a literal dot is \. — bare . means "any character".
Metacharacter cheat-sheet
| Token | Matches |
|---|---|
. | Any character except newline (also newlines with the s flag) |
\d / \D | A digit [0-9] / a non-digit |
\w / \W | A word char [A-Za-z0-9_] / a non-word char |
\s / \S | Whitespace (space, tab, newline) / non-whitespace |
[abc] | Any one of a, b or c |
[^abc] | Any character except a, b or c |
[a-z] | Any character in the range a–z |
| | Alternation — "this or that" |
Character classes
Square brackets [...] match exactly one character from the set inside. Ranges use a hyphen ([0-9a-f] = a hex digit), and a leading ^ negates the set ([^"] = any character that isn't a quote). Inside a class most metacharacters lose their power — . is a literal dot — but to include a literal ] escape it, and put a literal - first or last so it isn't read as a range.
Anchors and boundaries
| Token | Asserts |
|---|---|
^ | Start of the string (or start of a line with the m flag) |
$ | End of the string (or end of a line with the m flag) |
\b | A word boundary — the edge between a \w and a non-\w |
\B | Not a word boundary |
Anchors match a position, not a character. To validate that a whole value matches (not just part of it), wrap the pattern in ^…$.
Quantifiers
| Token | Repeats the preceding item |
|---|---|
* | 0 or more times |
+ | 1 or more times |
? | 0 or 1 time (makes it optional) |
{3} | Exactly 3 times |
{2,} | 2 or more times |
{2,4} | Between 2 and 4 times |
? to make them lazy (smallest match). On the text <a><b>, the pattern <.*> matches the whole thing, but <.*?> matches just <a>.
Groups, capturing and backreferences
(...)— a capturing group: remembers what it matched as group 1, 2, 3… (the tester lists these under each match).(?:...)— a non-capturing group: groups things (for a quantifier or alternation) without using up a group number.(?<year>...)— a named group: capture by name instead of number.\1— a backreference: match the same text an earlier group captured.(\w)\1finds a doubled letter (the "ee" in "feed").
Alternation
cat|dog matches "cat" or "dog". Scope it with a group: gr(a|e)y matches "gray" or "grey" (and captures the a/e); gr(?:a|e)y does the same without capturing.
Flags
| Flag | Effect |
|---|---|
g | Global — find every match, not just the first |
i | Case-insensitive |
m | Multiline — ^ and $ match at every line break |
s | Dotall — . also matches newlines |
u | Unicode mode (needed for \p{…} property escapes and astral characters) |
In the tester, tick the g/i/m/s boxes. In code the flags trail the pattern: /\d+/gi.
Lookahead and lookbehind
These are zero-width assertions — they check what comes next or before, without consuming those characters.
| Token | Asserts the match is… |
|---|---|
(?=...) | followed by … (positive lookahead) |
(?!...) | not followed by … (negative lookahead) |
(?<=...) | preceded by … (positive lookbehind) |
(?<!...) | not preceded by … (negative lookbehind) |
Example: \d+(?= USD) matches just the number in "50 USD"; (?<=\$)\d+ matches just the digits in "$50".
Worked examples
| Pattern | Matches |
|---|---|
^\d{4}-\d{2}-\d{2}$ | An ISO date like 2026-06-26 (the whole string) |
\b\d{1,3}(?:\.\d{1,3}){3}\b | An IPv4-shaped address (shape only — doesn't enforce 0–255) |
[\w.+-]+@[\w-]+\.[\w.-]+ | A basic email address |
#?[0-9a-fA-F]{6}\b | A hex colour such as #1a2b3c |
https?://[^\s]+ | An http/https URL up to the first space |
(\w+)\s+\1\b | An accidentally repeated word ("the the") |
Validation regexes for email, URL or IP are always approximations — great for catching typos, not for guaranteeing correctness. For strict checks, use a real parser/validator.
Common gotchas
- Forgetting to escape the dot.
3.14also matches "3x14"; write3\.14. - Greedy by surprise.
".*"over"a" and "b"grabs everything from the first quote to the last — use the lazy".*?". - Missing anchors. Without
^…$, a "validation" pattern will happily match a valid fragment inside junk. - Catastrophic backtracking. Nested quantifiers like
(a+)+on long input can hang the engine — keep patterns simple and anchored. - ASCII-only shorthands. In JavaScript,
\wand\dare ASCII by default, so accented letters and non-Latin digits won't match without theuflag and Unicode property escapes.
Build and test any of these live in the Regex tester on the Utilities page.