networking · intermediate · ~25 min
Bitmask construction; integer overflow guards in shifts.
Decide whether an IPv4 address falls inside a CIDR block — the inner loop of every firewall and cloud security group.
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.
network, ip: IPv4 addresses as uint32_t in host byte order.prefix_bits: the CIDR prefix length, 0..32.Return 1 if the top prefix_bits of ip and network match, else 0. A prefix_bits outside [0, 32] returns 0.
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)
prefix_bits == 0: the mask is 0, so every IP matches.prefix_bits == 32: exact match required.uint32_t by 32 (undefined behaviour) — special-case prefix_bits == 0.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.
network and ip as host-order uint32_t; prefix_bits in [0, 32].
1 if ip is inside network/prefix_bits, else 0; an out-of-range prefix returns 0.
Closed-form bit math; special-case prefix_bits==0 to avoid the shift-by-32 UB.
#include <stdint.h>
int cidr_contains(uint32_t network, int prefix_bits, uint32_t ip) { /* TODO */ return 0; }
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).
prefix 0 → mask is 0, every IP matches. prefix 32 → exact match.
O(1).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.