Topic Overview
IP Addressing (IPv4/IPv6)
Master IP addressing: IPv4 (32-bit) and IPv6 (128-bit) addresses, address classes, CIDR notation, and subnetting.
IP addressing is fundamental to networking. Every device on a network needs a unique IP address to communicate. IPv4 uses 32-bit addresses (4.3 billion addresses), while IPv6 uses 128-bit addresses (340 undecillion addresses) to solve IPv4 exhaustion.
IPv4 Addressing
Structure
IPv4 addresses are 32-bit numbers, typically written as four decimal numbers (0-255) separated by dots:
192.168.1.100
Binary representation:
192.168.1.100 = 11000000.10101000.00000001.01100100
Address Classes (Historical)
Originally, IPv4 addresses were divided into classes:
| Class | Range | Default Subnet Mask | Use Case |
|---|---|---|---|
| A | 1.0.0.0 - 126.255.255.255 | 255.0.0.0 (/8) | Large networks |
| B | 128.0.0.0 - 191.255.255.255 | 255.255.0.0 (/16) | Medium networks |
| C | 192.0.0.0 - 223.255.255.255 | 255.255.255.0 (/24) | Small networks |
| D | 224.0.0.0 - 239.255.255.255 | N/A | Multicast |
| E | 240.0.0.0 - 255.255.255.255 | N/A | Reserved |
Note: Classful addressing is obsolete. Modern networks use CIDR (Classless Inter-Domain Routing).
CIDR Notation
CIDR (Classless Inter-Domain Routing) uses a slash notation to specify the network prefix:
192.168.1.0/24
- 192.168.1.0: Network address
- /24: Subnet mask (24 bits for network, 8 bits for hosts)
- Subnet mask: 255.255.255.0 (in dotted decimal)
Special IPv4 Addresses
- 0.0.0.0/0: Default route (all networks)
- 127.0.0.1: Loopback (localhost)
- 169.254.0.0/16: Link-local (APIPA, auto-assigned when DHCP fails)
- 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16: Private addresses (RFC 1918)
- 255.255.255.255: Broadcast address
IPv6 Addressing
Structure
IPv6 addresses are 128-bit numbers, written as eight groups of four hexadecimal digits:
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Shortened form:
2001:db8:85a3::8a2e:370:7334 (:: replaces consecutive zeros)
IPv6 Address Types
-
Unicast: Single interface address
- Global Unicast: Public routable addresses (2000::/3)
- Link-Local: FE80::/10 (similar to 169.254.x.x in IPv4)
- Unique Local: FC00::/7 (similar to private addresses)
-
Multicast: Multiple interfaces (FF00::/8)
-
Anycast: Nearest interface with the address
IPv6 Benefits
- Larger address space: 2^128 addresses vs 2^32
- Simplified header: Fixed 40-byte header (vs variable IPv4)
- Built-in security: IPSec support
- Better multicast: Native multicast support
- Stateless autoconfiguration: Devices can configure themselves
Subnetting
Subnetting divides a network into smaller subnetworks.
Calculating Subnets
Example: 192.168.1.0/24 → /26 (4 subnets)
Original: 192.168.1.0/24
Network: 192.168.1.0
Mask: 255.255.255.0
Hosts: 256 (254 usable)
Subnet 1: 192.168.1.0/26
Network: 192.168.1.0
Broadcast: 192.168.1.63
Hosts: 64 (62 usable)
Range: 192.168.1.1 - 192.168.1.62
Subnet 2: 192.168.1.64/26
Network: 192.168.1.64
Broadcast: 192.168.1.127
Hosts: 64 (62 usable)
Range: 192.168.1.65 - 192.168.1.126
Subnet 3: 192.168.1.128/26
Network: 192.168.1.128
Broadcast: 192.168.1.191
Hosts: 64 (62 usable)
Range: 192.168.1.129 - 192.168.1.190
Subnet 4: 192.168.1.192/26
Network: 192.168.1.192
Broadcast: 192.168.1.255
Hosts: 64 (62 usable)
Range: 192.168.1.193 - 192.168.1.254
Subnet Calculation Formula
Number of subnets = 2^(subnet_bits - network_bits)
Hosts per subnet = 2^(32 - subnet_bits) - 2
(-2 for network and broadcast addresses)
Examples
IPv4 Subnetting Example
def calculate_subnet(ip, cidr, new_cidr):
"""
Calculate subnet details for 192.168.1.0/24 → /26
"""
import ipaddress
network = ipaddress.IPv4Network(f"{ip}/{cidr}", strict=False)
subnets = list(network.subnets(new_prefix=new_cidr))
for i, subnet in enumerate(subnets, 1):
print(f"Subnet {i}:")
print(f" Network: {subnet.network_address}")
print(f" Broadcast: {subnet.broadcast_address}")
print(f" Hosts: {subnet.num_addresses} ({subnet.num_addresses - 2} usable)")
print(f" Range: {subnet.network_address + 1} - {subnet.broadcast_address - 1}")
print()
# Usage
calculate_subnet("192.168.1.0", 24, 26)
Output:
Subnet 1:
Network: 192.168.1.0
Broadcast: 192.168.1.63
Hosts: 64 (62 usable)
Range: 192.168.1.1 - 192.168.1.62
Subnet 2:
Network: 192.168.1.64
Broadcast: 192.168.1.127
Hosts: 64 (62 usable)
Range: 192.168.1.65 - 192.168.1.126
...
IPv6 Address Configuration
import ipaddress
# IPv6 address parsing
addr = ipaddress.IPv6Address("2001:db8::1")
print(f"Compressed: {addr.compressed}")
print(f"Exploded: {addr.exploded}")
# IPv6 network
network = ipaddress.IPv6Network("2001:db8::/64")
print(f"Network: {network.network_address}")
print(f"Hosts: {network.num_addresses}")
# Subnetting IPv6
subnets = list(network.subnets(new_prefix=66))
print(f"Number of /66 subnets: {len(subnets)}")
Network Address Calculation
def get_network_info(ip_with_cidr):
"""Get network, broadcast, and host range"""
import ipaddress
network = ipaddress.IPv4Network(ip_with_cidr, strict=False)
return {
"network": str(network.network_address),
"broadcast": str(network.broadcast_address),
"netmask": str(network.netmask),
"hosts": network.num_addresses - 2,
"first_host": str(network.network_address + 1),
"last_host": str(network.broadcast_address - 1)
}
# Example
info = get_network_info("192.168.1.100/24")
print(info)
# {
# "network": "192.168.1.0",
# "broadcast": "192.168.1.255",
# "netmask": "255.255.255.0",
# "hosts": 254,
# "first_host": "192.168.1.1",
# "last_host": "192.168.1.254"
# }
Common Pitfalls
- Confusing network vs host address: Network address has all host bits as 0, broadcast has all host bits as 1. Fix: Always calculate network and broadcast addresses
- Forgetting to subtract 2: Network and broadcast addresses aren't usable hosts. Fix: Usable hosts = 2^n - 2
- Mixing up CIDR notation: /24 means 24 network bits, not 24 host bits. Fix: Remember CIDR = network prefix length
- IPv4 exhaustion: Running out of IPv4 addresses. Fix: Use NAT, IPv6, or proper subnetting
- Private vs public addresses: Using private addresses on public internet. Fix: Understand RFC 1918 private ranges
- Subnet mask calculation errors: Incorrect binary math. Fix: Use subnet calculators or libraries
- IPv6 adoption: Not understanding IPv6 format and benefits. Fix: Learn hexadecimal and IPv6 address types
Interview Questions
Beginner
Q: What is the difference between IPv4 and IPv6? Explain the address format and size.
A:
IPv4:
- Size: 32 bits (4 bytes)
- Format: Dotted decimal (192.168.1.1)
- Address space: 2^32 = 4.3 billion addresses
- Header: Variable length (20-60 bytes)
- Example:
192.168.1.100
IPv6:
- Size: 128 bits (16 bytes)
- Format: Hexadecimal groups (2001:db8::1)
- Address space: 2^128 = 340 undecillion addresses
- Header: Fixed 40 bytes
- Example:
2001:0db8:85a3:0000:0000:8a2e:0370:7334or2001:db8:85a3::8a2e:370:7334
Key Differences:
- Address space: IPv6 has vastly more addresses
- Format: IPv4 uses decimal, IPv6 uses hexadecimal
- Header: IPv6 has simplified, fixed-length header
- Security: IPv6 has built-in IPSec support
- Configuration: IPv6 supports stateless autoconfiguration
Intermediate
Q: Given the network 192.168.1.0/24, how would you subnet it to create 8 subnets? What are the network addresses, broadcast addresses, and usable host ranges?
A:
Original Network: 192.168.1.0/24
- Network bits: 24
- Host bits: 8
- Total addresses: 256
- Usable hosts: 254
To create 8 subnets:
- Need 3 additional bits (2^3 = 8 subnets)
- New prefix: /27 (24 + 3)
- Hosts per subnet: 2^(32-27) - 2 = 32 - 2 = 30 usable hosts
Subnet Breakdown:
| Subnet | Network | Broadcast | Usable Range |
|---|---|---|---|
| 1 | 192.168.1.0/27 | 192.168.1.31 | 192.168.1.1 - 192.168.1.30 |
| 2 | 192.168.1.32/27 | 192.168.1.63 | 192.168.1.33 - 192.168.1.62 |
| 3 | 192.168.1.64/27 | 192.168.1.95 | 192.168.1.65 - 192.168.1.94 |
| 4 | 192.168.1.96/27 | 192.168.1.127 | 192.168.1.97 - 192.168.1.126 |
| 5 | 192.168.1.128/27 | 192.168.1.159 | 192.168.1.129 - 192.168.1.158 |
| 6 | 192.168.1.160/27 | 192.168.1.191 | 192.168.1.161 - 192.168.1.190 |
| 7 | 192.168.1.192/27 | 192.168.1.223 | 192.168.1.193 - 192.168.1.222 |
| 8 | 192.168.1.224/27 | 192.168.1.255 | 192.168.1.225 - 192.168.1.254 |
Calculation:
- Subnet size = 256 / 8 = 32 addresses per subnet
- First subnet: 192.168.1.0 - 192.168.1.31
- Each subsequent subnet starts at +32
Senior
Q: Design an IP address allocation system for a cloud provider that needs to allocate subnets to customers efficiently. How do you handle IPv4 exhaustion, subnet allocation, and address tracking?
A:
class IPAllocationSystem {
private ipv4Pool: IPv4Pool;
private ipv6Pool: IPv6Pool;
private allocations: Map<string, Allocation>;
constructor() {
// Reserve management networks
this.ipv4Pool = new IPv4Pool("10.0.0.0/8");
this.ipv6Pool = new IPv6Pool("2001:db8::/32");
// Pre-allocate management subnets
this.reserveManagementNetworks();
}
// 1. Efficient Subnet Allocation
async allocateSubnet(customerId: string, size: number, version: 'v4' | 'v6'): Promise<Allocation> {
const pool = version === 'v4' ? this.ipv4Pool : this.ipv6Pool;
// Find smallest available subnet that fits
const subnet = await pool.findSmallestFit(size);
if (!subnet) {
// IPv4 exhaustion: use NAT or IPv6
if (version === 'v4') {
return this.allocateWithNAT(customerId, size);
}
throw new Error("Address pool exhausted");
}
// Allocate and track
const allocation = {
customerId,
subnet,
version,
allocatedAt: Date.now(),
status: 'active'
};
this.allocations.set(customerId, allocation);
pool.markAllocated(subnet);
return allocation;
}
// 2. IPv4 Exhaustion Handling
async allocateWithNAT(customerId: string, size: number): Promise<Allocation> {
// Option 1: Use private IPs with NAT
const privateSubnet = await this.ipv4Pool.allocatePrivate(size);
// Option 2: Allocate IPv6 instead
const ipv6Subnet = await this.ipv6Pool.allocate(size);
return {
customerId,
ipv4: privateSubnet, // Private IPs
ipv6: ipv6Subnet, // Public IPv6
nat: true,
version: 'dual-stack'
};
}
// 3. Subnet Reclamation
async deallocateSubnet(customerId: string): Promise<void> {
const allocation = this.allocations.get(customerId);
if (!allocation) return;
// Mark as available after grace period
const pool = allocation.version === 'v4' ? this.ipv4Pool : this.ipv6Pool;
pool.markAvailable(allocation.subnet, { gracePeriod: 24 * 60 * 60 * 1000 }); // 24 hours
this.allocations.delete(customerId);
}
// 4. Address Tracking
class IPv4Pool {
private available: Set<string>;
private allocated: Map<string, AllocationInfo>;
async findSmallestFit(size: number): Promise<Subnet | null> {
// Use binary tree or trie for efficient search
// Find smallest subnet that can accommodate 'size' hosts
const requiredCIDR = this.calculateCIDR(size);
// Search available subnets
for (const subnet of this.available) {
if (this.canFit(subnet, requiredCIDR)) {
return this.splitSubnet(subnet, requiredCIDR);
}
}
return null;
}
calculateCIDR(hosts: number): number {
// Calculate CIDR needed for 'hosts' addresses
// Add 2 for network and broadcast
const bits = Math.ceil(Math.log2(hosts + 2));
return 32 - bits;
}
}
// 5. IPv6 Migration Strategy
async migrateToIPv6(customerId: string): Promise<Allocation> {
const existing = this.allocations.get(customerId);
// Allocate IPv6 while keeping IPv4
const ipv6Subnet = await this.ipv6Pool.allocate(existing.size);
return {
...existing,
ipv6: ipv6Subnet,
version: 'dual-stack',
migration: 'in-progress'
};
}
}
Features:
- Efficient allocation: Use data structures (trie, binary tree) for fast subnet search
- IPv4 exhaustion: NAT with private IPs, IPv6 allocation, dual-stack
- Subnet reclamation: Grace period before reusing addresses
- Address tracking: Database of all allocations with metadata
- CIDR calculation: Automatic CIDR calculation based on host requirements
- Monitoring: Track pool utilization, allocation rates, exhaustion predictions
Key Takeaways
- IPv4: 32-bit addresses (4.3 billion), dotted decimal format, CIDR notation for subnetting
- IPv6: 128-bit addresses (340 undecillion), hexadecimal format, built-in security and autoconfiguration
- CIDR notation: /n specifies network prefix length (e.g., /24 = 24 network bits)
- Subnetting: Divide networks into smaller subnets using additional network bits
- Network vs broadcast: Network address (all host bits 0), broadcast (all host bits 1) are not usable
- Usable hosts: 2^n - 2 (subtract network and broadcast addresses)
- Private addresses: RFC 1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) for internal use
- IPv4 exhaustion: Use NAT, IPv6, or efficient subnet allocation to manage limited addresses
- Subnet calculation: Number of subnets = 2^(subnet_bits - network_bits), hosts = 2^(32 - subnet_bits) - 2