IP Addressing & Subnets - Understanding CIDR, Masks and Network Math

Status: Active
Last Updated: 2026-08-14
Category: Networking - Phase 1: Network Fundamentals
Prerequisites: tcp-ip-fundamentals
Time: 3-4 hours
Tags: networking, subnetting, cidr, ipv4, ipv6, vlsm, addressing

Summary

Everything about IP addresses you need to design, read, and debug real networks: binary math behind subnet masks, CIDR notation, public vs private space, calculating networks/broadcasts/host counts by hand, VLSM for splitting subnets, planning address space for a homelab or small business, and IPv6 prefixes in practice. This is the lesson that turns "192.168.1.x works somehow" into "here is our addressing plan for the next five years."

๐ŸŽฏ What You'll Learn

By the end of this guide, you'll understand:

Prerequisites: TCP/IP fundamentals (tcp-ip-fundamentals)
Time Investment: 3-4 hours + practice until the math becomes reflex


Table of Contents

  1. One Address, Two Meanings
  2. Binary Refresher (The Only Part You Need)
  3. Subnet Masks and Prefix Lengths
  4. The Four Questions (Network Math by Hand)
  5. CIDR Cheat Table
  6. Public vs Private vs Reserved Space
  7. Subnetting: Splitting a Network
  8. VLSM: Different Sizes for Different Needs
  9. A Real Addressing Plan
  10. IPv6 Prefixes in Practice
  11. Hands-On Exercises
  12. Common Gotchas
  13. Next Steps

๐Ÿ”— Related


One Address, Two Meanings

An IP address never travels alone โ€” it always carries an implicit or explicit mask that splits it:

192.168.1.50/24
                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ network โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”Œโ”€ host โ”€โ”
11000000 . 10101000 . 00000001 . โ”‚โ”‚00110010
   192    .   168    .     1     . โ”‚โ”‚   50
                                  โ†‘
                        mask = 255.255.255.0 (/24)

Two machines can talk directly (no router) only if their network portions are identical. That single sentence explains most home networking behavior:

# Same network โ†’ ARP + direct delivery
192.168.1.50  โ†”  192.168.1.87      โœ“ direct

# Different network โ†’ must go through the gateway
192.168.1.50  โ†”  10.0.0.5          โœ— needs a router

Your machine makes this decision for every single packet: "is the destination in one of my local networks? Then deliver directly via ARP. Otherwise hand it to the default gateway." You saw this in ip route show in the previous lesson.


Binary Refresher (The Only Part You Need)

You don't need general binary arithmetic โ€” just how one byte (8 bits) maps to 0โ€“255:

Bit position 128 64 32 16 8 4 2 1
Value if set 128 64 32 16 8 4 2 1

A byte is just which positions are switched on:

192 = 11000000  โ†’ 128 + 64            = 192
168 = 10101000  โ†’ 128 + 32 + 8        = 168
  1 = 00000001  โ†’ 1                   = 1
 50 = 00110010  โ†’ 32 + 16 + 2         = 50
255 = 11111111  โ†’ 128+64+32+16+8+4+2+1 = 255

And the reverse โ€” decimal to bits โ€” is subtracting powers of two from largest to smallest:

50 โ†’ 32 fits (18 left), 16 fits (2 left), 2 fits (0 left)
   โ†’ 00110010

Practice this until 172 instantly reads as 10101100. Every subnetting calculation in this lesson is just counting these bits.


Subnet Masks and Prefix Lengths

A subnet mask marks where the network portion ends. It's always a contiguous run of 1s from the left, then all 0s:

/24  = 11111111.11111111.11111111.00000000  = 255.255.255.0
/26  = 11111111.11111111.11111111.11000000  = 255.255.255.192

If someone hands you 255.255.255.240, count the 1s: twenty-eight โ†’ /28.

โš ๏ธ Masks like 255.0.255.0 are invalid โ€” the 1s must be contiguous. Some old systems accepted them; modern kernels reject them. If you ever see one in a config, it's a typo or sabotage.

Converting Both Directions

Prefix โ†’ Mask:  fill 1s from the left, count to prefix, rest 0s.
  /20 โ†’ 11111111.11111111.11110000.00000000 โ†’ 255.255.240.0

Mask โ†’ Prefix:  count the 255 octets ร—8, then count 1s in the odd octet.
  255.255.255.252 โ†’ 8+8+8+2 = /30

You never have to do this under time pressure forever โ€” every OS will tell you (ip -brief addr) โ€” but reading /27 fluently is a daily skill when working with cloud VPCs, Kubernetes CNI config, and firewall rules.


The Four Questions

Given any address/prefix, there are four things you almost always want to know:

  1. What network is it on? (network address)
  2. What's the broadcast address?
  3. Which IPs can I actually give to hosts?
  4. How many hosts fit?

The Method

For prefix length P:

Worked Example: 192.168.1.130/26

/26 โ†’ last octet mask = 192 โ†’ block size = 256โˆ’192 = 64

Networks in the last octet step by 64:  0, 64, 128, 192

130 falls in the 128-block:
  Network:    192.168.1.128
  Broadcast:  192.168.1.191        (128 + 64 โˆ’ 1)
  Hosts:      192.168.1.129 โ€“ 190  (62 usable)
  Count:      2^6 โˆ’ 2 = 62

Verify yourself โ€” 130 is indeed between 129 and 190. This four-line procedure answers every subnetting exam question and, more importantly, every real-world "why can't these two machines talk" question.

Why โˆ’2?

The all-zeros host bits form the network address (identifies the network itself โ€” routing tables point here), and all-ones form the broadcast (delivered to every host in the subnet). Neither can belong to a machine.

Modern footnote: on point-to-point links (/31, per RFC 3021) both addresses are usable because there's no broadcast domain of consequence. Linux happily uses 10.0.0.4/31 on WAN links. But for LANs, stick to โˆ’2.


CIDR Cheat Table

Memorize this table or tape it to your monitor. It compresses everything above:

CIDR Mask Block size Usable hosts Typical use
/8 255.0.0.0 256 in 1st octet 16,777,214 Huge ISP/corp (10.0.0.0/8)
/12 255.240.0.0 โ€” 1,048,574 Docker's 172.17 range
/16 255.255.0.0 256 in 3rd octet 65,534 Large site (192.168.0.0/16)
/20 255.255.240.0 16 in 3rd octet 4,094 Cloud VPC
/22 255.255.252.0 4 in 3rd octet 1,022 Medium office
/23 255.255.254.0 2 in 3rd octet 510 Small office
/24 255.255.255.0 1 in 4th octet 254 Classic LAN โ€” memorize cold
/25 255.255.255.128 128 126 Half a /24
/26 255.255.255.192 64 62 Quarter of a /24
/27 255.255.255.224 32 30 Eighth of a /24
/28 255.255.255.240 16 14 DMZ / small VLAN
/29 255.255.255.248 8 6 Tiny cluster
/30 255.255.255.252 4 2 Point-to-point link
/31 255.255.255.254 2 2* Modern p2p (RFC 3021)
/32 255.255.255.255 1 1 Single host route

Pattern worth seeing: each +1 to the prefix halves the size. /24=254, /25=126, /26=62, /27=30, /28=14, /29=6, /30=2. Halving chain โ€” no multiplication needed.


Public vs Private vs Reserved Space

Not all 4.3 billion IPv4 addresses are yours to use. IANA partitions them:

Range Class Size Routable on internet? Who uses it
0.0.0.0/8 Reserved 16.7M No "Unspecified"/default routes
10.0.0.0/8 Private 16.7M No Corporations, big labs, cloud VPCs
100.64.0.0/10 CGNAT 4.2M No Carrier NAT (some ISPs hand these to you!)
127.0.0.0/8 Loopback 16.7M No Localhost
169.254.0.0/16 Link-local 65k No DHCP failure fallback, mDNS-ish
172.16.0.0/12 Private 1M No Cloud VPCs (AWS default), Docker
192.0.2.0/24 Docs (TEST-NET-1) 256 No Documentation examples
192.88.99.0/24 Reserved 256 No Legacy 6to4 relay
192.168.0.0/16 Private 65k No Home networks everywhere
198.18.0.0/15 Benchmarking 131k No Perf testing
198.51.100.0/24 Docs (TEST-NET-2) 256 No Documentation examples
203.0.113.0/24 Docs (TEST-NET-3) 256 No Documentation examples
224.0.0.0/4 Multicast 268M Special mDNS (224.0.0.251), OSPF (224.0.0.5)
240.0.0.0/4 Reserved 268M No Future use

Notes that matter in practice:

Check Your Own Public IP

curl -4 ifconfig.me && echo
curl -6 ifconfig.me && echo
ip route get 1.1.1.1        # shows which src IP + interface would be used

Compare against ip addr: if they differ, you're behind NAT (you are, unless you're running BGP).


Subnetting: Splitting a Network

Now the skill itself: taking one network and cutting it into pieces.

Example: Split 192.168.1.0/24 into 4 equal subnets

Need 4 subnets โ†’ 2 extra bits (2ยฒ = 4). New prefix = /24 + 2 = /26.

Subnet 1:  192.168.1.0/26     hosts .1 โ€“ .62     broadcast .63
Subnet 2:  192.168.1.64/26    hosts .65 โ€“ .126   broadcast .127
Subnet 3:  192.168.1.128/26   hosts .129 โ€“ .190  broadcast .191
Subnet 4:  192.168.1.192/26   hosts .193 โ€“ .254  broadcast .255

Each subnet gets 62 usable hosts. Notice the pattern: subnets start at multiples of the block size (64), and each new subnet begins immediately after the previous broadcast.

The General Procedure

To carve N subnets out of X/Y:

  1. Extra bits needed: ceil(logโ‚‚ N)
  2. New prefix: Y + extra bits
  3. Subnet boundaries land on multiples of the new block size
  4. Apply the four questions to each piece

Reverse Problem: "I need a subnet for 100 hosts"

Hosts needed H โ†’ find smallest n where 2โฟ โˆ’ 2 โ‰ฅ H โ†’ prefix = 32 โˆ’ n.

100 hosts โ†’ 2โทโˆ’2 = 126 โ‰ฅ 100 โ†’ 7 host bits โ†’ /25 (128-block)
500 hosts โ†’ 2โนโˆ’2 = 510 โ‰ฅ 500 โ†’ 9 host bits โ†’ /23
  2 hosts โ†’ /30 or /31 (router-to-router links)
 14 hosts โ†’ /28 (classic DMZ size)

Cloud providers ask exactly this question in their VPC wizards ("subnets must be /16โ€“/28"), so this direction is the practically common one.


VLSM: Different Sizes for Different Needs

Equal splitting wastes space: a guest Wi-Fi doesn't need 254 addresses when a DMZ needs 60 and point-to-point links need 2. Variable Length Subnet Masks let each subnet have its own size.

Task: From 192.168.10.0/24, allocate

Rule: allocate largest first. Sorting descending prevents overlap chaos:

Sales       needs โ‰ฅ101 โ†’ /25 (126)  โ†’ 192.168.10.0/25     .1โ€“.126
Servers     needs โ‰ฅ52  โ†’ /26 (62)   โ†’ 192.168.10.128/26   .129โ€“.190
Management  needs โ‰ฅ22  โ†’ /27 (30)   โ†’ 192.168.10.192/27   .193โ€“.222
IoT         needs โ‰ฅ12  โ†’ /28 (14)   โ†’ 192.168.10.224/28   .225โ€“.238
Link A      needs โ‰ฅ2   โ†’ /30        โ†’ 192.168.10.240/30   .241โ€“.242
Link B      needs โ‰ฅ2   โ†’ /30        โ†’ 192.168.10.244/30   .245โ€“.246
                                          (spare: .248/29 free for growth)

Every allocation lands cleanly on its own boundary; nothing overlaps; 8 addresses remain for expansion. Draw it as a ruler and it's obvious why largest-first matters โ€” try allocating the /30s first and watch the /25 no longer fit anywhere clean.

Verify With Tooling

# ipcalc shows everything about any prefix (apt install ipcalc)
ipcalc 192.168.10.128/26
# Address:    192.168.10.128
# Network:    192.168.10.128/26
# HostMin:    192.168.10.129
# HostMax:    192.168.10.190
# Broadcast:  192.168.10.191
# Hosts/Net:  62

# sipcalc does IPv4 + IPv6; python has it built in:
python3 - <<'EOF'
import ipaddress
for net in ["192.168.10.0/25","192.168.10.128/26","192.168.10.192/27",
            "192.168.10.224/28","192.168.10.240/30","192.168.10.244/30"]:
    n = ipaddress.ip_network(net)
    print(f"{str(n):22} {n.num_addresses:>4} addrs  {list(n.hosts())[0]} โ€“ {list(n.hosts())[-1]}")
EOF

Use tools for verification, not for thinking โ€” the hand method stays fast enough and catches config typos that blind trust in calculators misses.


A Real Addressing Plan

Here's the plan we'll reuse across the firewall, Traefik, and Pi-hole lessons. A small self-hosted environment on 10.10.0.0/16 private space (room to grow far beyond a /24):

10.10.0.0/16  โ€” overall allocation (routed nowhere directly)

VLAN 10  10.10.10.0/24    Management   (switches, hypervisors, iDRAC/iLO)
                          GW 10.10.10.1   ~254 hosts
VLAN 20  10.10.20.0/24    Servers      (Docker hosts, VMs, storage)
                          GW 10.10.20.1   static .10-.99, DHCP pool .100-.199
VLAN 30  10.10.30.0/24    Users/Wired  (workstations)
                          GW 10.10.30.1   DHCP .50-.250
VLAN 40  10.10.40.0/24    Wi-Fi trusted (laptops, phones)
                          GW 10.10.40.1   DHCP .50-.250
VLAN 50  10.10.50.0/24    IoT/Guest    (cameras, TVs, visitors)
                          GW 10.10.50.1   DHCP .50-.250, heavily firewalled
VLAN 60  10.10.60.0/24    DMZ          (anything internet-reachable)
                          GW 10.10.60.1   static .10-.49

Conventions baked into the plan:

Write your plan down before assigning addresses. "Whatever the DHCP gave me" is not an addressing plan; it's tomorrow's 3 AM troubleshooting session. Document it alongside DNS records once you reach local-dns-records and pihole-setup.


IPv6 Prefixes in Practice

IPv6 subnetting follows the same logic with different conventions:

2001:db8:abcd:0012::/64
โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜โ””โ”€โ”€โ”ฌโ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  routed to you  your     interface IDs (64 bits,
  by your ISP    subnet   usually SLAAC/randomized)

Key differences from v4 habits:

  1. The standard subnet is /64 โ€” not because you need 18 quintillion hosts, but because SLAAC autoconfiguration requires it. Don't subnet smaller than /64 on LANs even though the math allows it.
  2. ISPs typically delegate a /56 (256 subnets) or /48 to homes/businesses. Your router subdivides it, one /64 per VLAN/VSSID.
  3. No mask games โ€” you don't do VLSM inside your delegation; you burn whole /64s profligately. There are enough.
  4. Link-local fe80::/10 exists on every interface regardless; it's for neighbor discovery and local protocols only.
ip -6 route show
# 2001:db8:abcd:12::/64 dev eth0 proto kernel metric 256
# fe80::/64 dev eth0 proto kernel metric 256
# default via fe80::1 dev eth0 proto ra metric 1024   โ† learned from Router Advertisement

python3 -c "import ipaddress; print(ipaddress.ip_network('2001:db8::/32').subnets(new_prefix=64).__next__())"
# 2001:db8::/64

The same Python ipaddress module handles v6 calculations โ€” useful since hex math is worse for humans than decimal.


Hands-On Exercises

Do these on paper first, verify after:

# 1. Four questions, no calculator:
#    a) 172.16.55.77/20  โ†’ network? broadcast? usable range? count?
#    b) 10.1.1.199/26    โ†’ same four
#    c) 192.168.100.240/28 โ†’ same four
# Answers below (no peeking):
#    a) 172.16.48.0/20 ยท bcast 172.16.63.255 ยท .48.1โ€“.63.254 ยท 4094
#    b) 10.1.1.192/26  ยท bcast 10.1.1.255    ยท .193โ€“.254    ยท 62
#    c) 192.168.100.240/28 ยท bcast .255      ยท .241โ€“.254    ยท 14

# 2. Can these pairs talk directly? (same network?)
python3 - <<'EOF'
import ipaddress
pairs = [("192.168.1.50/24","192.168.1.87/24"),
         ("192.168.1.50/24","192.168.2.87/24"),
         ("10.10.20.5/24","10.10.21.5/24"),
         ("172.16.5.9/22","172.16.7.200/22")]
for a,b in pairs:
    print(a, "<->", b, ":",
          "DIRECT" if ipaddress.ip_interface(a).network == ipaddress.ip_interface(b).network
          else "NEEDS ROUTER")
EOF

# 3. Carve 192.168.50.0/24 into: 60, 60, 30, 12, 2 hosts. Largest-first.
#    Answer: .0/26, .64/26, .128/27, .160/28, .176/30 โ€” with room left.

# 4. Confirm your own box's understanding matches reality:
ip -brief addr; ip route show; ipcalc $(ip -brief addr show eth0 | awk '{print $3}')

Speed goal: question set 1 should take under 90 seconds total. That's the level of fluency where subnet stops being a chore.


Common Gotchas

Mistake Symptom Fix
Wrong mask on one end (/25 vs /24) "Works sometimes" โ€” some destinations direct, others via gateway, asymmetric weirdness Compare masks on both hosts; ping + ip route get
Static IP inside DHCP pool Random "IP conflict" storms hours later Reserve static ranges outside pools (or DHCP reservations)
Using documentation IPs (192.0.2.x) for real Things break mysteriously when VPN routes appear Use 10.x/172.16/192.168 space internally
Overlapping subnets after VPN connect Traffic black-holes toward one branch office Plan non-overlapping allocations before any site-to-site VPN
Assuming /24 means "last octet changes" Confusion with /23, /25 boundaries mid-octet Always compute the block size, don't pattern-match
Forgetting gateway .1 isn't magic Renumbered network, scripts still hardcode old gw Config management / document the convention
IPv6 /64 split into smaller LANs SLAAC breaks; devices self-assign wrong addresses Keep /64 minimum for any LAN segment
Double-counting network+broadcast in cloud consoles AWS "subnet too small" errors Remember cloud reserves 5 addresses per subnet, not 2

The deepest one deserves emphasis: overlapping subnets across sites is the classic multi-location failure. Site A uses 192.168.1.0/24, Site B uses the same, then a WireGuard tunnel connects them โ€” now 192.168.1.1 means two different machines depending on who answers first. Preventing this costs ten minutes of planning in this lesson; fixing it costs a weekend of renumbering later.


Next Steps

Addressing is the vocabulary; now learn the directory service that makes names work:

  1. dns-fundamentals โ€” how names become the addresses you now fully understand
  2. network-troubleshooting โ€” apply today's math to real breakage
  3. nat-port-forwarding โ€” what happens when private-space networks meet the public internet

๐Ÿ”— Related

Choose Theme

Your selection is saved locally.

Neural Cacophony
Aperture v2
Flux v1
Mosaic Chaos
Nexus v1
Nexus Zest
Prism v2
Synapse