IP Addressing & Subnetting

Why This Matters

Your manager asks you to set up a new network segment for the development team. They need 50 IP addresses, isolated from the production network. "Just pick a subnet," they say.

If you do not understand subnetting, you might pick a range that overlaps with production, causing routing chaos. Or you might allocate a /24 (254 hosts) when you only need 50, wasting addresses. Or worse, you might pick a /28 (14 hosts) and run out of IPs in a week.

IP addressing and subnetting are foundational skills for anyone who manages servers. Every time you configure a network interface, set up a firewall rule, troubleshoot connectivity, or plan a network, you need to understand how IP addresses work, what a subnet mask means, and how to calculate network boundaries.

This chapter teaches you the math (it is simpler than you think) and the practical skills to work with IP addresses confidently.


Try This Right Now

# See your IP addresses and subnet masks
ip addr show

# Example output (look for "inet" lines):
# inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0

# That /24 is the subnet mask in CIDR notation
# Let's decode it:
# 192.168.1.100 = your IP address
# /24           = subnet mask (255.255.255.0)
# brd 192.168.1.255 = broadcast address

# See your default gateway (the router)
ip route show default

# Check another machine's IP
ping -c 1 google.com

By the end of this chapter, you will understand every number in that output.


IPv4 Addresses: The Basics

An IPv4 address is a 32-bit number, written as four octets (bytes) separated by dots. Each octet ranges from 0 to 255.

    192  .  168  .    1  .  100
      |       |       |      |
  Octet 1  Octet 2  Octet 3  Octet 4

Binary Representation

Computers do not see 192.168.1.100. They see 32 bits:

  192       168         1       100
 11000000  10101000  00000001  01100100

 Full binary: 11000000.10101000.00000001.01100100

To convert a decimal octet to binary, use powers of 2:

 Bit position:    128   64   32   16    8    4    2    1
                  ---   ---  ---  ---  ---  ---  ---  ---

 192 in binary:    1     1    0    0    0    0    0    0
                  128 + 64 = 192  ✓

 168 in binary:    1     0    1    0    1    0    0    0
                  128 + 32 + 8 = 168  ✓

 100 in binary:    0     1    1    0    0    1    0    0
                   64 + 32 + 4 = 100  ✓

Think About It: Why do octets max out at 255? Because 8 bits can represent values from 0 (00000000) to 255 (11111111). And 128+64+32+16+8+4+2+1 = 255.


Network and Host Portions

Every IP address has two parts:

  1. Network portion -- Identifies which network this address belongs to
  2. Host portion -- Identifies the specific device on that network

The subnet mask tells you where the dividing line is.

IP Address:     192.168.1.100
Subnet Mask:    255.255.255.0

Binary:
  IP:    11000000.10101000.00000001.01100100
  Mask:  11111111.11111111.11111111.00000000
         |<--- Network portion --->|<-Host->|

  Network: 192.168.1.0     (the "street")
  Host:    0.0.0.100        (the "house number")

Rule: Where the subnet mask has a 1-bit, that part of the address is the network portion. Where the mask has a 0-bit, that part is the host portion.


Subnet Masks and CIDR Notation

Subnet masks can be written in two ways:

Dotted Decimal Notation

255.255.255.0     = 24 bits of network, 8 bits of host
255.255.0.0       = 16 bits of network, 16 bits of host
255.0.0.0         = 8 bits of network, 24 bits of host
255.255.255.128   = 25 bits of network, 7 bits of host
255.255.255.192   = 26 bits of network, 6 bits of host

CIDR (Classless Inter-Domain Routing) Notation

CIDR notation appends the number of network bits after a slash:

192.168.1.100/24     same as  255.255.255.0
10.0.0.1/16          same as  255.255.0.0
172.16.0.1/12        same as  255.240.0.0
192.168.1.100/26     same as  255.255.255.192

CIDR notation is simpler and is what you will see in ip addr show output, config files, and modern documentation.

Common Subnet Masks Reference

+------+-------------------+-------+--------------------+
| CIDR | Subnet Mask       | Hosts | Common Use         |
+------+-------------------+-------+--------------------+
| /8   | 255.0.0.0         | 16M   | Class A networks   |
| /12  | 255.240.0.0       | 1M    | Large private nets |
| /16  | 255.255.0.0       | 65534 | Class B networks   |
| /20  | 255.255.240.0     | 4094  | Large subnets      |
| /22  | 255.255.252.0     | 1022  | Medium subnets     |
| /24  | 255.255.255.0     | 254   | Most common LAN    |
| /25  | 255.255.255.128   | 126   | Split /24 in half  |
| /26  | 255.255.255.192   | 62    | Quarter of /24     |
| /27  | 255.255.255.224   | 30    | Small subnet       |
| /28  | 255.255.255.240   | 14    | Very small subnet  |
| /29  | 255.255.255.248   | 6     | Point-to-point     |
| /30  | 255.255.255.252   | 2     | Router links       |
| /32  | 255.255.255.255   | 1     | Single host        |
+------+-------------------+-------+--------------------+

The "Hosts" column is calculated as: 2^(host bits) - 2. The subtraction of 2 accounts for the network address (all host bits = 0) and the broadcast address (all host bits = 1), neither of which can be assigned to a device.


Calculating Subnets: Step by Step

This is the skill that matters most. Given an IP address and a CIDR prefix, you need to be able to calculate:

  1. The network address (first address in the range)
  2. The broadcast address (last address in the range)
  3. The usable host range (first usable to last usable)
  4. The number of usable hosts

Example 1: 192.168.1.100/24

Step 1: Identify the mask
  /24 = 24 network bits, 8 host bits
  Subnet mask: 255.255.255.0

Step 2: Calculate the network address
  AND the IP address with the subnet mask:

  IP:    192.168.  1.100    = 11000000.10101000.00000001.01100100
  Mask:  255.255.255.  0    = 11111111.11111111.11111111.00000000
  ---------------------------------------------------------
  Network: 192.168.1.  0    = 11000000.10101000.00000001.00000000

  Network address: 192.168.1.0

Step 3: Calculate the broadcast address
  Set all host bits to 1:

  Network: 192.168.  1.  0  = 11000000.10101000.00000001.00000000
  Host bits flipped to 1:    11000000.10101000.00000001.11111111
  Broadcast: 192.168.1.255

Step 4: Usable host range
  First usable: 192.168.1.1   (network address + 1)
  Last usable:  192.168.1.254 (broadcast address - 1)
  Total usable: 2^8 - 2 = 254 hosts

Example 2: 10.0.50.75/20

This is a less intuitive example where the subnet boundary falls in the middle of an octet.

Step 1: Identify the mask
  /20 = 20 network bits, 12 host bits
  Subnet mask: 255.255.240.0

  Why 240? The third octet has 4 network bits and 4 host bits:
  11110000 = 128+64+32+16 = 240

Step 2: Calculate the network address
  IP:    10.  0. 50. 75    = 00001010.00000000.00110010.01001011
  Mask: 255.255.240.  0    = 11111111.11111111.11110000.00000000
  ---------------------------------------------------------
  Network: 10.0. 48.  0    = 00001010.00000000.00110000.00000000

  Key: 50 AND 240:
    50  = 00110010
    240 = 11110000
    AND = 00110000 = 48

  Network address: 10.0.48.0

Step 3: Calculate the broadcast address
  Set all 12 host bits to 1:
  Network: 00001010.00000000.00110000.00000000
  Bcast:   00001010.00000000.00111111.11111111
           10.0.63.255

  Key: 48 OR 15 (since 4 host bits in the third octet: 00001111 = 15):
    48 + 15 = 63

  Broadcast address: 10.0.63.255

Step 4: Usable host range
  First usable: 10.0.48.1
  Last usable:  10.0.63.254
  Total usable: 2^12 - 2 = 4094 hosts

Example 3: 172.16.5.130/26

Step 1: Identify the mask
  /26 = 26 network bits, 6 host bits
  Subnet mask: 255.255.255.192

  Fourth octet: 11000000 = 192
  Subnets in the last octet: 256/64 = 4 subnets
  (Block size = 2^6 = 64)

Step 2: Find which subnet block 130 falls in
  Block size = 64
  Subnet boundaries: 0, 64, 128, 192
  130 falls in the 128 block (128 <= 130 < 192)

  Network address: 172.16.5.128

Step 3: Broadcast address
  Next subnet starts at 192, so broadcast = 192 - 1 = 191
  Broadcast address: 172.16.5.191

Step 4: Usable host range
  First usable: 172.16.5.129
  Last usable:  172.16.5.190
  Total usable: 2^6 - 2 = 62 hosts

The Block Size Shortcut

For subnets within the last octet, the block size method is fastest:

Block size = 256 - subnet mask value in the relevant octet

/25:  256 - 128 = 128  (blocks: 0, 128)
/26:  256 - 192 = 64   (blocks: 0, 64, 128, 192)
/27:  256 - 224 = 32   (blocks: 0, 32, 64, 96, 128, 160, 192, 224)
/28:  256 - 240 = 16   (blocks: 0, 16, 32, 48, ... 240)
/29:  256 - 248 = 8    (blocks: 0, 8, 16, 24, ... 248)
/30:  256 - 252 = 4    (blocks: 0, 4, 8, 12, ... 252)

To find which subnet an address belongs to: find the largest block boundary that is less than or equal to the host octet value.

Think About It: Your company has 200 employees who need IP addresses. What is the smallest subnet that can accommodate them all? (Answer: /24 gives 254 hosts. /25 gives only 126 -- not enough.)


Private Address Ranges (RFC 1918)

Not all IP addresses are routable on the public internet. RFC 1918 defines three ranges reserved for private use:

+-------------------+-----------------+------------------+
| Range             | CIDR            | Addresses        |
+-------------------+-----------------+------------------+
| 10.0.0.0 -        | 10.0.0.0/8      | 16,777,214       |
| 10.255.255.255    |                 |                  |
+-------------------+-----------------+------------------+
| 172.16.0.0 -       | 172.16.0.0/12   | 1,048,574        |
| 172.31.255.255    |                 |                  |
+-------------------+-----------------+------------------+
| 192.168.0.0 -      | 192.168.0.0/16  | 65,534           |
| 192.168.255.255   |                 |                  |
+-------------------+-----------------+------------------+

Why these exist: There are not enough IPv4 addresses for every device on earth to have a public one. Private addresses can be reused on different private networks. A router using NAT (Network Address Translation) translates private addresses to a public address when traffic leaves the local network.

Other Special Address Ranges

RangePurpose
127.0.0.0/8Loopback (localhost)
169.254.0.0/16Link-local (APIPA, used when DHCP fails)
224.0.0.0/4Multicast
240.0.0.0/4Reserved (historically "Class E")
0.0.0.0/0Default route (means "any address")
255.255.255.255Limited broadcast
# Verify your loopback interface
ip addr show lo

# Output:
# inet 127.0.0.1/8 scope host lo

# The /8 means the entire 127.x.x.x range is loopback
ping -c 1 127.42.42.42
# It works! Any 127.x.x.x address loops back to your machine.

Hands-On: Subnetting with Linux Tools

Linux provides tools to verify your subnet calculations:

Using ipcalc

# Install ipcalc
# Debian/Ubuntu
sudo apt install ipcalc

# Fedora/RHEL
sudo dnf install ipcalc

# Use it
ipcalc 192.168.1.100/24

Sample output:

Address:   192.168.1.100        11000000.10101000.00000001. 01100100
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.1.0/24       11000000.10101000.00000001. 00000000
HostMin:   192.168.1.1          11000000.10101000.00000001. 00000001
HostMax:   192.168.1.254        11000000.10101000.00000001. 11111110
Broadcast: 192.168.1.255        11000000.10101000.00000001. 11111111
Hosts/Net: 254                   Class C, Private Internet

Try it with more complex subnets:

ipcalc 10.0.50.75/20
ipcalc 172.16.5.130/26
ipcalc 192.168.10.0/28

Distro Note: There are two different tools named ipcalc. The version in Debian/Ubuntu (ipcalc) and the version in Fedora/RHEL (ipcalc) have slightly different output formats but both do the same calculation. Some systems also have sipcalc with more detailed output.

Using Python for Quick Calculations

python3 -c "
import ipaddress
net = ipaddress.ip_network('192.168.1.100/26', strict=False)
print(f'Network:   {net.network_address}')
print(f'Netmask:   {net.netmask}')
print(f'Broadcast: {net.broadcast_address}')
print(f'First:     {net.network_address + 1}')
print(f'Last:      {net.broadcast_address - 1}')
print(f'Hosts:     {net.num_addresses - 2}')
"

Output:

Network:   192.168.1.64
Netmask:   255.255.255.192
Broadcast: 192.168.1.127
First:     192.168.1.65
Last:      192.168.1.126
Hosts:     62

IPv6: A Brief Overview

IPv4 has approximately 4.3 billion addresses (2^32). That is not enough -- we ran out of new IPv4 allocations years ago. IPv6 solves this with 128-bit addresses, providing approximately 340 undecillion addresses (2^128).

IPv6 Address Format

An IPv6 address is written as eight groups of four hexadecimal digits, separated by colons:

Full:       2001:0db8:85a3:0000:0000:8a2e:0370:7334
Shortened:  2001:db8:85a3::8a2e:370:7334

Shortening rules:

  1. Drop leading zeros in each group: 0db8 becomes db8
  2. Replace consecutive all-zero groups with :: (only once per address)

Special IPv6 Addresses

AddressPurpose
::1Loopback (like 127.0.0.1)
::Unspecified (like 0.0.0.0)
fe80::/10Link-local (auto-configured on every interface)
fc00::/7Unique local (like RFC 1918 private)
2000::/3Global unicast (public internet)
ff00::/8Multicast

IPv6 on Linux

# See IPv6 addresses
ip -6 addr show

# Ping an IPv6 address
ping -6 ::1

# Ping a host via IPv6
ping -6 google.com

# See IPv6 routes
ip -6 route show

# See IPv6 neighbors (like ARP for IPv6)
ip -6 neigh show

IPv6 Subnetting

IPv6 subnetting follows the same principles as IPv4 but with larger numbers. The standard allocation for a single LAN is /64, which provides 2^64 host addresses per subnet -- more than enough for any conceivable LAN.

A typical IPv6 allocation:

  ISP gives you:     2001:db8:abcd::/48     (65,536 /64 subnets)
  You create subnets: 2001:db8:abcd:0001::/64  (subnet 1)
                      2001:db8:abcd:0002::/64  (subnet 2)
                      ...
                      2001:db8:abcd:ffff::/64  (subnet 65535)

Think About It: With IPv6 giving every LAN 2^64 host addresses, is subnetting for host conservation still relevant? (In IPv6, subnetting is about network organization and routing, not address conservation.)


Debug This

You configure a server with IP 192.168.1.200/28 and a gateway of 192.168.1.1. The server cannot reach the gateway. Why?

Diagnosis:

Let us calculate the subnet for 192.168.1.200/28:

/28 = block size of 16
Subnet boundaries: 0, 16, 32, 48, ..., 192, 208, ...
200 falls in the 192 block

Network:   192.168.1.192
Broadcast: 192.168.1.207
Range:     192.168.1.193 - 192.168.1.206

The gateway 192.168.1.1 is in the 192.168.1.0/28 subnet (range 1-14). The server at 192.168.1.200 is in the 192.168.1.192/28 subnet. They are on different subnets.

The server will try to ARP for the gateway but will never get a response because the gateway is not on the same Layer 2 network segment (assuming the subnetting is enforced by the network).

Fix: Either change the server's IP to something in the same /28 as the gateway (e.g., 192.168.1.2/28), or change the subnet mask to include both addresses (e.g., use /24 instead of /28).


What Just Happened?

+------------------------------------------------------------------+
|                        CHAPTER RECAP                              |
+------------------------------------------------------------------+
|                                                                   |
|  IPv4: 32-bit address, written as four octets (0-255).           |
|                                                                   |
|  Every IP has a NETWORK portion and a HOST portion.              |
|  The SUBNET MASK defines the boundary.                           |
|                                                                   |
|  CIDR notation: /24 = 24 network bits, 8 host bits.             |
|                                                                   |
|  To calculate a subnet:                                          |
|    1. Find the block size (256 - mask octet value)               |
|    2. Network = largest block boundary <= host value             |
|    3. Broadcast = next boundary - 1                              |
|    4. Usable hosts = block size - 2                              |
|                                                                   |
|  Private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16     |
|                                                                   |
|  IPv6: 128-bit addresses, written in hex with colons.            |
|  Standard LAN subnet: /64                                        |
|                                                                   |
|  Use ipcalc or Python's ipaddress module to verify.              |
|                                                                   |
+------------------------------------------------------------------+

Try This

  1. Manual Calculation: Without using any tools, calculate the network address, broadcast address, and usable host range for each of these:

    • 10.10.10.50/24
    • 172.16.100.200/20
    • 192.168.5.67/27
    • 10.0.0.1/30

    Then verify your answers with ipcalc.

  2. Network Planning: You need to design a network with four subnets:

    • Engineering: 100 hosts
    • Sales: 50 hosts
    • Management: 20 hosts
    • Guest Wi-Fi: 30 hosts

    Starting with 10.1.0.0, assign the smallest appropriate subnet to each department. Document the network address, usable range, and broadcast for each.

  3. Your Network: Run ip addr show and ip route show. Identify your IP address, subnet mask, network address, broadcast address, and gateway. Calculate how many hosts your subnet can support.

  4. IPv6 Exploration: Run ip -6 addr show on your system. What IPv6 addresses are configured? Are they link-local (fe80::) or global? What is their prefix length?

  5. Bonus Challenge: Write a bash script that takes an IP address and CIDR prefix as arguments and outputs the network address, broadcast address, first host, last host, and number of usable hosts. (Hint: use bitwise operations in bash with $(( )) or call Python's ipaddress module.)