X Xerobit

Subnet Mask Explained — How Subnetting and Network Masks Work

A subnet mask separates the network portion from the host portion of an IP address. Here's how subnet masks work, how to read CIDR notation, and how to calculate usable hosts...

Mian Ali Khalid · · 6 min read
Use the tool
Subnet / CIDR Calculator
Calculate IPv4 subnets — network, broadcast, usable range, wildcard mask. Input CIDR (/24) or dotted mask (255.255.255.0). Binary visualization.
Open Subnet / CIDR Calculator →

A subnet mask is a 32-bit number that identifies which part of an IP address is the network and which part is the host. It’s how routers know whether two IP addresses are on the same network or need routing between networks.

Use the Subnet Calculator to calculate subnet ranges, usable hosts, and network details.

How subnet masks work

Every IPv4 address and subnet mask is 32 bits. The mask uses 1s for the network portion and 0s for the host portion:

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 ─┘

AND operation reveals the network address:

IP:      11000000.10101000.00000001.01100100  (192.168.1.100)
Mask:    11111111.11111111.11111111.00000000  (255.255.255.0)
AND:     11000000.10101000.00000001.00000000  (192.168.1.0)

The network is 192.168.1.0. Any IP from 192.168.1.1 to 192.168.1.254 is on this network.

Common subnet masks

CIDRSubnet MaskNetwork bitsHost bitsUsable hosts
/8255.0.0.082416,777,214
/16255.255.0.0161665,534
/24255.255.255.0248254
/25255.255.255.128257126
/26255.255.255.19226662
/27255.255.255.22427530
/28255.255.255.24028414
/29255.255.255.2482936
/30255.255.255.2523022
/32255.255.255.2553201 (host only)

Usable hosts formula: 2^(host bits) - 2

The -2 subtracts the network address (all 0s) and broadcast address (all 1s), which can’t be assigned to hosts.

CIDR notation

CIDR (Classless Inter-Domain Routing) notation combines the IP address and prefix length:

192.168.1.0/24
         └── /24 means 24 bits are the network portion

/24 is equivalent to subnet mask 255.255.255.0.

The prefix length equals the number of consecutive 1-bits in the subnet mask:

255.255.255.0   = 11111111.11111111.11111111.00000000 = 24 ones → /24
255.255.255.128 = 11111111.11111111.11111111.10000000 = 25 ones → /25
255.255.0.0     = 11111111.11111111.00000000.00000000 = 16 ones → /16

Subnet components

For 192.168.1.0/24:

Network address: 192.168.1.0 — identifies the subnet Broadcast address: 192.168.1.255 — sends to all hosts in subnet First usable host: 192.168.1.1 Last usable host: 192.168.1.254 Usable hosts: 254 (256 - 2 for network and broadcast)

Calculating subnet ranges

For 10.0.0.0/26:

  • Prefix = 26, so host bits = 32 - 26 = 6
  • Hosts per subnet = 2^6 = 64
  • Usable = 64 - 2 = 62
Network address:   10.0.0.0
First host:        10.0.0.1
Last host:         10.0.0.62
Broadcast:         10.0.0.63

For 172.16.5.0/25:

  • Host bits = 32 - 25 = 7
  • Hosts per subnet = 128
  • Usable = 126
Network address:   172.16.5.0
First host:        172.16.5.1
Last host:         172.16.5.126
Broadcast:         172.16.5.127

Subnetting: dividing a network

Divide 192.168.1.0/24 into 4 equal subnets:

4 subnets requires 2 additional bits (2^2 = 4). Prefix extends from /24 to /26:

Subnet 1: 192.168.1.0/26   (hosts: .1 – .62)
Subnet 2: 192.168.1.64/26  (hosts: .65 – .126)
Subnet 3: 192.168.1.128/26 (hosts: .129 – .190)
Subnet 4: 192.168.1.192/26 (hosts: .193 – .254)

Each subnet has 62 usable hosts.

Checking if two IPs are on the same subnet

import ipaddress

def same_subnet(ip1, ip2, prefix_len):
    network1 = ipaddress.ip_interface(f'{ip1}/{prefix_len}').network
    network2 = ipaddress.ip_interface(f'{ip2}/{prefix_len}').network
    return network1 == network2

print(same_subnet('192.168.1.50', '192.168.1.100', 24))  # True
print(same_subnet('192.168.1.50', '192.168.2.100', 24))  # False

# Is IP in subnet?
network = ipaddress.ip_network('192.168.1.0/24')
ip = ipaddress.ip_address('192.168.1.100')
print(ip in network)  # True
// Simple subnet check with bitwise operations:
function ipToInt(ip) {
  return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet), 0) >>> 0;
}

function sameSubnet(ip1, ip2, mask) {
  const maskInt = ipToInt(mask);
  return (ipToInt(ip1) & maskInt) === (ipToInt(ip2) & maskInt);
}

console.log(sameSubnet('192.168.1.50', '192.168.1.100', '255.255.255.0'));  // true
console.log(sameSubnet('192.168.1.50', '192.168.2.100', '255.255.255.0'));  // false

Cloud networking subnets

AWS, Azure, and GCP use VPC (Virtual Private Cloud) with subnets:

VPC: 10.0.0.0/16 (65,534 IPs)

Subnets:
  Public subnet:  10.0.1.0/24  (254 hosts, internet-facing)
  Private subnet: 10.0.2.0/24  (254 hosts, internal only)
  DB subnet:      10.0.3.0/24  (254 hosts, database tier)

AWS reserves 5 IPs per subnet: first 4 and last 1:

  • 10.0.1.0 — Network address
  • 10.0.1.1 — VPC router
  • 10.0.1.2 — AWS DNS
  • 10.0.1.3 — Future use
  • 10.0.1.255 — Broadcast

So a /24 subnet in AWS gives 251 usable IPs (256 - 5), not 254.


Related posts

Related tool

Subnet / CIDR Calculator

Calculate IPv4 subnets — network, broadcast, usable range, wildcard mask. Input CIDR (/24) or dotted mask (255.255.255.0). Binary visualization.

Written by Mian Ali Khalid. Part of the Dev Productivity pillar.