IP Addressing & Subnetting

Networking enables communication by forwarding data through interconnected devices (hops) until it reaches its destination. The first step in this process is identifying the sender and receiver using their unique addresses.

Address

Every network device has two key identifiers:
Physical Address (e.g., MAC address) – Uniquely identifies the device on a local network.
Logical Address (e.g., IP address) – Enables routing across interconnected networks.
This blog explores IP addressing and subnetting, covering:

  • How to assign network addresses based on host requirements.
  • Techniques to efficiently divide networks into subnets.

Physical address: MAC address

  • A MAC address is a hardware addr assigned to network interface card (NIC) by the manufacturer.
  • It is also known as a LAN address or link-layer address.
  • It is fixed and unchangeable, similar to SSN.
  • Format: AA:AA:AA:AA:AA:AA (48 bits, represented as 6 groups of 2 hexadecimal digits.Each group is 8 bit(1byte)).
  • Role: Used at the data link layer (Layer 2) of the OSI model to identify devices on the same local network.
  • ARP (Address Resolution Protocol): Resolves an IP address to a MAC address on the network layer (Layer 3).

Logical address: IP address

  • An IP (Internet Protocol) address is a logical address assigned to a device for communication.
    Two versions:
  • IPv4: 32 bits, represented as 4 octets (e.g., 192.168.1.1). Each octet is 8 bits.
  • IPv6: 128 bits, represented as 8 groups of 4 hexadecimal digits (e.g., 2001:0db8:85a3:0000:0000:8a2e:0370:7334). Each group is 16 bits.
    Role: Used at the network layer of the OSI model to route data between devices across networks.

Hostname

A hostname is a human-readable name assigned to a device (e.g., www.example.com).
DNS (Domain Name System): Resolves hostnames to IP addresses at the application layer bassed on UDP, 53 port.

Comprise of IP address

Ipv4 address = network portion + host portion
Through ip address + subnet mask(aka netmask) to determine its network(aka subnet)
For every octec:
10000000:128, 01000000:64

1
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |

IP addressing

Now most of time use CIDR

Private IP

Class Range CIDR Notation Netmask Hosts Usecase
A 10.0.0.0~10.255.255.255 10.0.0.0/8 255.0.0.0 2²⁴ - 2(32-8=24) Very large network
B 172.16.0.0~172.31.255.255 172.16.0.0/12 255.240.0.0 2²⁰ - 2 Medium network
C 192.168.0.0~192.168.255.255 192.168.0.0/16 255.255.0.0 2^16-2=65,534 Small network

Question1: for class B, why end of range is 172.31.255.255?

Answer1: For classB, /12, use 8+4 within second octet, use first octet and half second octet. For second octet in binary:11110000(240),255-240=15 left in host option, start 16+15=31

Public IP

Class Octet Range CIDR Netmask Hosts Usecase Network Size
A 1.0.0.0 - 126.0.0.0 /8 255.0.0.0 16,777,214 (2²⁴-2) Very large networks 126 (2⁷-2) networks
B 128.0.0.0 - 191.255.0.0 /16 255.255.0.0 65,534 (2¹⁶-2) Medium networks 16,384 (2¹⁴-2) networks
C 192.0.0.0 - 223.255.255.0 /24 255.255.255.0 254 (2⁸-2) Small networks 2,097,152 (2²¹-2) networks
D 224.0.0.0 - 239.255.255.255 N/A N/A Multicast Multicast groups N/A
E 240.0.0.0 - 254.255.255.255 N/A N/A Reserved Future use N/A
  • network size=number of subnets

Question2: why number of hosts -2 ?

Answer2: except all 0 reserved and all 255 broadcast address

Question3: which class we should use?

Answer3: For family or only need to assign IP for few devices, use class C, use small part of subnet. class C have more subnet, but less host address can allocate.

Question4: why network size 2^21 for class C, same questions for class A&B?

Answer4: Fixed leading bits:
Class A: 0xxxxxxx (8-1=7)
Class B: 10xxxxxx (16-2=14)
Class C: 110xxxxx (24-3=21)

Question5: CIDR block 172.16.0.0/21. How many usable host addresses are available per subnet, and what is the subnet mask?

Answer5:

  1. Usable Host addresses per subnet
    Total IPs in subnet = 2^(32-21) = 2^11=2048, this is host count/subnet.
    Usable hosts = 2048-2=2046 (Subtract 2 for the network ID (172.16.0.0) and broadcast (172.16.7.255))
  2. Subnet Mask
    /21 -> binary: 11111111.11111111.11111000.00000000 (8+8+5)-> 255.255.248.0 This mask.
  3. IP range
    why 7 in third octet? network 248 in third
    255-248=7 left for host portion(248 is network portion): 0+7=7
    First IP in subnet: 172.16.0.0(reserved)
    First usable Host: 172.16.0.1(Network address + 1)
    Last usable Host: 172.16.7.254 (Broadcast address - 1)
    Broadcast: 172.16.7.255

Question6: given class C network, I want to divide network into 3 subnets, each with up to 50 hosts, what netmask I can use? 255.255.255.50 is good?

Answer6:
First, binary of last octet: 00110010. It is not a valid subnet mask(see table as below). A subnet mask should consists of contiguous 1s followed by contiguous 0s in binary form. Valid subnet masks for class C eg:
255.255.255.0 (/24) default one
255.255.255.128 (/25) borrow1
255.255.255.192 (/26) borrow 2=>128+64
valid CIDR prefix from /0 ~/32

Valid Subnet Mask

CIDR Subnet Mask Usable Hosts Notes
/8 255.0.0.0 16,777,214 Class A equivalent
/16 255.255.0.0 65,534 Class B equivalent
/24 255.255.255.0 254 Class C equivalent
/25 255.255.255.128 126
/26 255.255.255.192 62
/27 255.255.255.224 30
/28 255.255.255.240 14
/29 255.255.255.248 6
/30 255.255.255.252 2 Common for WAN links
/31 255.255.255.254 N/A Point-to-Point only
/32 255.255.255.255 1 (Single host) Loopback/management

How to do Subnetting

Important Equation

  • Number of subnet = 2^n, where n is number of borrowed bits(extra bits taken from the host portion to create subnets).
  • Usable host=2^n -2, where n is host bit.

Fixed length subnet masking(FLSM)

Used to expected host number. Although subnetting can improve the efficient use of IP address resources by dividing a large network into smaller segments, it still leads to significant IP address wastage. Despite implementing subnetting, each divided subnet has the same number of usable hosts. In practice, this results in some subnets experiencing high host utilization while others suffer from low utilization.

How it works

eg.192.168.100.0/24, divide 4 subnets.
Recap Formula: number of subnet = 2^n, where n is number of borrowed bits(extra bits taken from the host portion to create subnets)
if borrow1, /25, 2^1=2, no enough!
if borrow2, /26, 2^2=4, OK! host bit=32-26=6bit, 2^6=64 network address
4 Subnets:
192.168.100.0/26, 192.168.100.64/26, 192.168.100.128/26, 192.168.100.192/26 (increase by 64 OR can say 00, 01, 10, 11)

Variable length subnet masking(VLSM)

Optimize 1st method.
This VLSM follow Longest Prefix Match (LPM) rule. When a router has multiple matching routes for a destination IP, it always selects the most specific route, which means the longest prefix (or the smallest subnet).

How it works

If a router has these routes in its routing table:
10.0.0.0/8 → General route for 10.x.x.x
10.1.0.0/16 → More specific for 10.1.x.x
10.1.2.0/24 → Even more specific for 10.1.2.x
10.1.2.128/25 → Most specific (smallest subnet)
If a packet arrives for 10.1.2.130, the router will choose 10.1.2.128/25 because it is the longest prefix match (i.e., it covers fewer IPs, making it more specific).

Question7: 192.168.100.0/24, divide 3 subnets,1.A subnet:40 devices, 2.B subnet:12 devices, 3.C subnets 75 devices,

Answer7: Use VLSM to better assign IP and not waste unse subnets.

1 Method guess CIDR with Mask based on host requirements(Need familiar to 2^n value):

  1. Step: sorted host requirements in descending order: C,A,B
  2. Step: calculate subnet size
    Recap Formula: Usable host=2^n -2, where n is host bit.
    SubnetC -> 75 hosts needed -> host bits= 7(2^7-2=126 hosts) -> CIDR /25(32-7=25) -> subnet mask: 255.255.255.128(25=8+8+8+1) borrow 1 bit -> Final CIDR 192.168.100.0/25 -> Usable IP range[192.168.100.1~192.168.100.126(0+126)] (reversed:192.168.100.0, broadcast:192.168.100.127, last octet borrow 1 (128-2))
    Now used 127, so starting from 128 for next one …

SubnetA -> 40 hosts needed -> host bits= 7(2^6-2=62 hosts) -> CIDR /25(32-6=26) -> subnet mask: 255.255.255.192(25=8+8+8+2) borrow 2 bit -> Final CIDR 192.168.100.128/26 -> Usable IP range[192.168.100.129~192.168.100.190(128+62)] (reversed:192.168.100.128, broadcast:192.168.191, last octet borrow 2)
Now used 191, so starting from 192 for next one …

SubnetB -> 12 hosts needed -> host bits= 7(2^4-2=14 hosts) -> CIDR /28(32-4=28) -> subnet mask: 255.255.255.240(28=8+8+8+4) borrow 4 bit -> Final CIDR 192.168.100.192/28 -> Usable IP range[192.168.100.193~192.168.100.206(192+14)] (reversed:192.168.100.192, broadcast:192.168.100.207, last octet borrow 4)

2 Method Jigsaw Puzzle
/24, so still 8 is host bit, 2^8-2=256-2=254 network address can be assigned in total. but now only have 127 in total(40+75+12). That is why need to use VLSM.

Special IP

  1. 0.0.0.0/0 – The Default Route
    Definition: The IP address 0.0.0.0/0 represents the default route in a network, meaning it matches all IP addresses. Traffic destination is any external network
    Usage:
    Routing: It is used in routing tables to direct traffic to a default gateway when no specific match is found.
    DHCP (Dynamic Host Configuration Protocol): A device requesting an IP address from a DHCP server may initially use 0.0.0.0 before obtaining an assigned IP.
    Listening on All Interfaces: Some network services use 0.0.0.0 to listen for incoming connections on all available network interfaces.

  2. Loopback Address (127.0.0.0/8)
    Definition: The loopback address range (127.0.0.0/8), with 127.0.0.1 being the most commonly used, allows a device to communicate with itself.
    Usage:
    Self-Testing: Useful for network and application testing without external network access.
    Local Services: Some applications use loopback to provide services within the same machine (e.g., a local web server running on 127.0.0.1).
    Prevents External Traffic: Traffic sent to 127.0.0.1 never leaves the local device, ensuring security and isolation.

Question8: if routing table add 0.0.0.0/0, what that means?

Answer8:
0.0.0.0/0 covers all IPv4 addresses that are not explicitly defined in other routing table entries.
This route is used when no specific match is found for a destination IP address.
Typically, it is used to route traffic to a gateway (next hop), such as a router or firewall, that connects to the internet.
Common Use Cases:
Internet Access:
If the default route points to a router’s IP (e.g., 192.168.1.1), all unknown traffic goes through it to reach external networks.
VPN or Tunneling:
If a VPN adds 0.0.0.0/0, all internet-bound traffic is routed through the VPN.
Cloud Networking:
Cloud providers (AWS, Azure, GCP) often use 0.0.0.0/0 to direct outbound traffic to an internet gateway or NAT instance.

Validate IP

Approch

Check for IPv4

  • form must be x1.x2.x3.x4, each xi is in range[0-255]
  • each xi must not have leading 0 unlese it is exactly ‘0’
  • octet must be separated by dots

Check for IPv6

  • form must be x1:x2:x3:x4:x5:x6:x7:x8, each xi have [1-4]number of hexadecimal string
  • each xi can contain [0-9],lowercase&upercase of a-fA-F
  • leading zero is allow, but empty components not allow
1
2
3
4
5
6
7
8
9
def validIPAddress(self, queryIP: str) -> str:
ipv4_pattern=r'^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$'
ipv6_pattern=r'^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$'
if re.match(ipv4_pattern, queryIP):
return "IPv4"
elif re.match(ipv6_pattern, queryIP):
return "IPv6"
else:
return "Neither"

Explanation

Whole IP address must perfectly follow rules, so use ^ and $ as start with and end with.
{m,n} and {N} means occur [m,n] ranges and Ntimes
() means group, group them+{times}
[] means choice range.eg.25[0-5] matches numbers 250-255.2[0-4][0-9] matches numbers 200-249.1[0-9][0-9] matches numbers 100-199.[1-9][0-9] matches numbers 10-99 (no leading zero).[0-9] matches numbers 0-9 (only single digit)

Usecase - extract IP from log

use re.finditer to handle large volume of input

1
2
3
4
5
6
7
8
9
10
11
12
13
192.168.1.1 - - [01/Jan/2022:00:00:01 +0000] "GET / HTTP/1.1" 200 1234
10.0.0.1 - - [01/Jan/2022:00:00:02 +0000] "GET /about HTTP/1.1" 200 5678
192.168.1.1 - - [01/Jan/2022:00:00:03 +0000] "GET /contact HTTP/1.1" 200 9101
10.0.0.2 - - [01/Jan/2022:00:00:04 +0000] "GET / HTTP/1.1" 200 1121
192.168.1.1 - - [01/Jan/2022:00:00:05 +0000] "GET /about HTTP/1.1" 200 3141
172.16.0.1 - - [01/Jan/2022:00:00:07 +0000] "GET / HTTP/1.1" 200
172.16.0.1 - - [01/Jan/2022:00:00:07 +0000] "GET / HTTP/1.1" 200 7181
10.0.0.1 - - [01/Jan/2022:00:00:06 +0000] "GET /contact HTTP/1.1" 200 5161
172.16.0.1 - - [01/Jan/2022:00:00:07 +0000] "GET / HTTP/1.1" 200 7181
172.16.0.2 - - [01/Jan/2022:00:00:07 +0000] "GET / HTTP/1.1" 200 7181
172.16.0.2 - - [01/Jan/2022:00:00:07 +0000] "GET / HTTP/1.1" 200 6181
192.168.1.1 - - [01/Jan/2022:00:00:01 +0000] "GET / HTTP/1.1" 200 5134
172.16.0.1 - - [01/Jan/2022:00:00:07 +0000] "GET / HTTP/1.1" 200 5181
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import re
from collections import defaultdict
def findmost3ip(log, rank):
"""
250-255,200-249,100-199,10-99,0-9
"""
ipv4_pattern=r'\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b'
visit = defaultdict(int)
with open(log, 'r') as file:
for line in file:
# Find all IP matches in the current line
for match in re.finditer(ipv4_pattern, line):
full_ip = match.group() # Extract the complete IP
visit[full_ip] += 1
# sort list of tuple[(ip, count)]
top_ips = sorted(visit.items(), key=lambda x: x[1], reverse=True)[:3]
# top3 allows IP at same rank
res = set()
for top in top_ips:
if len(res)<rank:
res.add(top)
return list(res)

Appendix

n 2ⁿ (Power of 2) log₂(n) (Exact)
0 1 log₂(1) = 0
1 2 log₂(2) = 1
2 4 log₂(4) = 2
3 8 log₂(8) = 3
4 16 log₂(16) = 4
5 32 log₂(32) = 5
6 64 log₂(64) = 6
7 128 log₂(128) = 7
8 256 log₂(256) = 8
9 512 log₂(512) = 9
10 1,024 log₂(1024) = 10
11 2,048 log₂(2048) = 11
12 4,096 log₂(4096) = 12
13 8,192 log₂(8192) = 13
14 16,384 log₂(16384) = 14
15 32,768 log₂(32768) = 15
16 65,536 log₂(65536) = 16
17 131,072 log₂(131072) = 17
18 262,144 log₂(262144) = 18
19 524,288 log₂(524288) = 19
20 1,048,576 log₂(1048576) = 20
Author: Yu
Link: https://yurihe.github.io/2025/04/02/5.ip/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.