networking · intermediate · ~25 min

Does an IPv4 CIDR block contain an address?

Bitmask construction; integer overflow guards in shifts.

Challenge

Decide whether an IPv4 address falls inside a CIDR block — the inner loop of every firewall and cloud security group.

Task

Implement int cidr_contains(uint32_t network, int prefix_bits, uint32_t ip) that returns 1 if ip is inside network/prefix_bits, else 0.

Input

  • network, ip: IPv4 addresses as uint32_t in host byte order.
  • prefix_bits: the CIDR prefix length, 0..32.

Output

Return 1 if the top prefix_bits of ip and network match, else 0. A prefix_bits outside [0, 32] returns 0.

Example

cidr_contains(0xC0A80100, 24, 0xC0A8017F)  ->  1   (in 192.168.1.0/24)
cidr_contains(0xC0A80100, 24, 0xC0A80200)  ->  0   (outside)
cidr_contains(0x0A000000,  8, 0x0AFFFFFF)  ->  1   (in 10.0.0.0/8)
cidr_contains(0x00000000,  0, 0xFFFFFFFF)  ->  1   (/0 matches everything)
cidr_contains(0xC0A80101, 32, 0xC0A80101)  ->  1   (/32 exact)
cidr_contains(0xC0A80101, 32, 0xC0A80102)  ->  0   (/32 mismatch)

Edge cases

  • prefix_bits == 0: the mask is 0, so every IP matches.
  • prefix_bits == 32: exact match required.
  • Beware shifting a uint32_t by 32 (undefined behaviour) — special-case prefix_bits == 0.

Rules

  • Closed-form bit math; no loops needed.

Why this matters

Every firewall, every cloud security group, every IP allowlist relies on CIDR-membership checks. This is the inner loop of iptables, nftables, and your AWS VPC ACL evaluator.

Input format

network and ip as host-order uint32_t; prefix_bits in [0, 32].

Output format

1 if ip is inside network/prefix_bits, else 0; an out-of-range prefix returns 0.

Constraints

Closed-form bit math; special-case prefix_bits==0 to avoid the shift-by-32 UB.

Starter code

#include <stdint.h>
int cidr_contains(uint32_t network, int prefix_bits, uint32_t ip) { /* TODO */ return 0; }

Common mistakes

Computing the mask with (1<<prefix)-1 then shifting — wrong by an off-by-one; shifting a uint32_t by 32 (undefined behaviour in C); not handling prefix==0 (matches everything).

Edge cases to handle

prefix 0 → mask is 0, every IP matches. prefix 32 → exact match.

Complexity

O(1).

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.