Computer Networks

The Network Layer

IP Addressing and Subnetting

The dots are for readability. The address is one

JrCodex·7 min read

Jr Codex Computer Networks Notes

Level: Intermediate Prerequisites: Module 2, Chapter 4: Switching, ARP and VLANs Time to complete: ~25 minutes


Table of Contents

  1. The Structure of an Address
  2. Subnet Masks
  3. CIDR Notation
  4. Network, Broadcast and Usable Addresses
  5. Subnetting
  6. Special Address Ranges
  7. Summary & Next Steps

1. The Structure of an Address

32 Bits, Written for Humans
─────────────────────────────────────────
  192.168.1.10

  Four DOTTED-DECIMAL octets, each 0-255:

    192      168      1        10
    11000000 10101000 00000001 00001010

  The dots are for readability. The address is one
  32-bit number, and every operation on it is
  bitwise.
─────────────────────────────────────────
THE KEY IDEA
─────────────────────────────────────────
  An IP address has TWO PARTS:

    NETWORK portion   which network
    HOST portion      which machine on it

    192.168.1  .  10
    └ network ┘  └host┘

  This split is what makes routing possible. A
  router stores ONE entry for a whole network,
  covering millions of hosts — instead of one entry
  per machine, which Module 2, Chapter 3 showed is
  why MAC addresses cannot be routed.
─────────────────────────────────────────

2. Subnet Masks

The Question the Mask Answers
─────────────────────────────────────────
  WHERE does the network portion end?

  The address alone does not say. The SUBNET MASK
  does: 1 bits mark the network portion, 0 bits
  mark the host portion.

    address  192.168.1.10
             11000000.10101000.00000001.00001010
    mask     255.255.255.0
             11111111.11111111.11111111.00000000
             └────── network ──────┘ └─ host ─┘
─────────────────────────────────────────
Extracting the Network — a bitwise AND
─────────────────────────────────────────
    address  11000000.10101000.00000001.00001010
    mask     11111111.11111111.11111111.00000000
    AND      ────────────────────────────────────
    network  11000000.10101000.00000001.00000000
             = 192.168.1.0
─────────────────────────────────────────
def to_int(ip):   return int.from_bytes(bytes(int(o) for o in ip.split('.')), 'big')
def to_ip(n):     return '.'.join(str(b) for b in n.to_bytes(4, 'big'))
 
def network_address(ip, prefix):
    mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF     # `prefix` ones, then zeros
    return to_ip(to_int(ip) & mask)
 
print(network_address("192.168.1.10",  24))   # 192.168.1.0
print(network_address("192.168.1.10",  16))   # 192.168.0.0
print(network_address("10.45.200.17",  20))   # 10.45.192.0   ← not an octet boundary
THE DECISION EVERY HOST MAKES
─────────────────────────────────────────
  Before sending any packet:

    Is the DESTINATION's network the same as MINE?

    SAME     ──► deliver DIRECTLY. ARP for the
                 destination (Module 2, Chapter 4).
    DIFFERENT ──► send to the DEFAULT GATEWAY. ARP
                 for the router.

  That comparison — mask both addresses, compare
  the results — happens for every single packet
  your machine sends.
─────────────────────────────────────────

3. CIDR Notation

The Shorthand
─────────────────────────────────────────
  192.168.1.0/24

  The /24 is the PREFIX LENGTH — how many leading
  bits are the network portion.

    /24  = 255.255.255.0
    /16  = 255.255.0.0
    /8   = 255.0.0.0
    /26  = 255.255.255.192
    /30  = 255.255.255.252
─────────────────────────────────────────
Why CIDR Replaced Classes
─────────────────────────────────────────
  The old scheme fixed the split at octet
  boundaries:

    Class A  /8   16,777,214 hosts
    Class B  /16      65,534 hosts
    Class C  /24         254 hosts

  An organisation needing 300 addresses had to
  take a Class B — 65,534 addresses, of which
  65,234 were WASTED and unusable by anyone else.

  CIDR (Classless Inter-Domain Routing) allows ANY
  prefix length, so that organisation gets a /23
  — 510 addresses. This is the main reason IPv4
  lasted as long as it did.
─────────────────────────────────────────
Prefix Length and Size
─────────────────────────────────────────
  addresses = 2^(32 - prefix)

    /24  ──►    256 addresses (254 usable)
    /25  ──►    128
    /26  ──►     64
    /28  ──►     16
    /30  ──►      4 (2 usable — point-to-point
                     links)
    /31  ──►      2 (both usable — a special case
                     for links)
    /32  ──►      1 (a single host)

  Each extra bit of prefix HALVES the network.
─────────────────────────────────────────

4. Network, Broadcast and Usable Addresses

Two Addresses Are Reserved
─────────────────────────────────────────
  For 192.168.1.0/24:

    NETWORK ADDRESS    192.168.1.0
      all host bits 0. Names the network itself.
      Cannot be assigned to a device.

    BROADCAST ADDRESS  192.168.1.255
      all host bits 1. Reaches every host on this
      network.
      Cannot be assigned to a device.

    USABLE             192.168.1.1 - 192.168.1.254
      254 addresses = 2^8 - 2
─────────────────────────────────────────
def subnet_info(ip, prefix):
    mask    = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF
    net     = to_int(ip) & mask
    bcast   = net | (~mask & 0xFFFFFFFF)
    total   = 2 ** (32 - prefix)
    return {
        "network":   to_ip(net),
        "broadcast": to_ip(bcast),
        "first":     to_ip(net + 1)   if total > 2 else to_ip(net),
        "last":      to_ip(bcast - 1) if total > 2 else to_ip(bcast),
        "usable":    max(total - 2, 0) if total > 2 else total,
    }
 
print(subnet_info("192.168.1.10", 24))
# {'network': '192.168.1.0', 'broadcast': '192.168.1.255',
#  'first': '192.168.1.1', 'last': '192.168.1.254', 'usable': 254}
 
print(subnet_info("10.0.5.130", 26))
# {'network': '10.0.5.128', 'broadcast': '10.0.5.191',
#  'first': '10.0.5.129', 'last': '10.0.5.190', 'usable': 62}

5. Subnetting

The Task
─────────────────────────────────────────
  You have 192.168.1.0/24 and need FOUR separate
  networks — one per department, each its own
  broadcast domain (Module 2, Chapter 4).

  Borrow HOST bits to make more NETWORK bits.

    4 subnets = 2² ──► borrow 2 bits
    /24 + 2 = /26

  Each /26 has 2^(32-26) = 64 addresses, 62 usable.
─────────────────────────────────────────
The Four Subnets
─────────────────────────────────────────
  192.168.1.0/26     .0    - .63    usable .1  -.62
  192.168.1.64/26    .64   - .127   usable .65 -.126
  192.168.1.128/26   .128  - .191   usable .129-.190
  192.168.1.192/26   .192  - .255   usable .193-.254

  The BLOCK SIZE is 64 — so subnets start at
  multiples of 64. That pattern holds generally:
  block size = 2^(32 - prefix), and networks always
  begin at a multiple of it.
─────────────────────────────────────────
def subnets(base_ip, old_prefix, new_prefix):
    """Split a network into equal subnets."""
    start = to_int(base_ip) & ((0xFFFFFFFF << (32 - old_prefix)) & 0xFFFFFFFF)
    block = 2 ** (32 - new_prefix)
    count = 2 ** (new_prefix - old_prefix)
    return [f"{to_ip(start + i * block)}/{new_prefix}" for i in range(count)]
 
print(subnets("192.168.1.0", 24, 26))
# ['192.168.1.0/26', '192.168.1.64/26', '192.168.1.128/26', '192.168.1.192/26']
VLSM — Variable Length Subnet Masking
─────────────────────────────────────────
  Equal subnets waste space when needs differ.
  VLSM lets you size each one.

  Requirements: 100 hosts, 50 hosts, 20 hosts, and
  two point-to-point links.

  ALLOCATE LARGEST FIRST:
    100 hosts ──► /25 (126 usable) 192.168.1.0/25
     50 hosts ──► /26  (62 usable) 192.168.1.128/26
     20 hosts ──► /27  (30 usable) 192.168.1.192/27
     link      ──► /30   (2 usable) 192.168.1.224/30
     link      ──► /30   (2 usable) 192.168.1.228/30

  Largest first is essential — allocating a small
  subnet in the middle of the space fragments it so
  a large one no longer fits on its required
  boundary.
─────────────────────────────────────────

6. Special Address Ranges

Ranges Worth Memorising
─────────────────────────────────────────
  PRIVATE (RFC 1918) — not routable on the
  internet; used behind NAT (Chapter 5)
    10.0.0.0/8         16,777,216 addresses
    172.16.0.0/12       1,048,576
    192.168.0.0/16         65,536

  LOOPBACK
    127.0.0.0/8        127.0.0.1 = this machine

  LINK-LOCAL (APIPA)
    169.254.0.0/16     self-assigned when DHCP
                       FAILS
    ── seeing this address means DHCP did not
       answer (Chapter 5)

  MULTICAST
    224.0.0.0/4        one-to-many groups

  DOCUMENTATION — safe to use in examples
    192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24

  DEFAULT ROUTE
    0.0.0.0/0          "everything" — Chapter 3
─────────────────────────────────────────
The Diagnostic Worth Knowing Now
─────────────────────────────────────────
  A machine with a 169.254.x.x address has NOT
  received a DHCP lease.

  It assigned itself a link-local address because
  no DHCP server replied. So the problem is DHCP,
  the cable, or the VLAN — not routing, not DNS,
  not the application.

  This one recognition saves a great deal of
  diagnostic time.
─────────────────────────────────────────

7. Summary & Next Steps

Key Takeaways

  • An IP address splits into a network portion and a host portion, and that hierarchy is what lets one routing entry cover millions of hosts.
  • The subnet mask defines where the split falls, and every host masks both its own and the destination address to decide between direct delivery and the gateway.
  • CIDR replaced fixed classes with arbitrary prefix lengths, which stopped the enormous address waste that classful allocation caused.
  • Subnets always begin at a multiple of their block size, and VLSM requires allocating the largest subnet first to avoid fragmenting the space.

Concept Check

  1. Given 10.20.30.45/20, compute the network address, the broadcast address and the usable range.
  2. Why does every host perform a bitwise AND before sending each packet?
  3. A machine has the address 169.254.12.9. What has failed, and what have you ruled out?

Next Chapter

Chapter 2: IPv4, IPv6 and Address Exhaustion


Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index | Back to Computer Networks Index