C: network, broadcast, and host count of a CIDR block

An IPv4 address is a 32-bit number written as four bytes. CIDR notation such as 172.16.5.130/20 states that the first 20 bits are the network prefix. The mask has 20 leading ones. ANDing the address with the mask gives the first address of the block, the network address.

C
#include <stdint.h>
#include <stdio.h>

static void print_ip(const char *label, uint32_t ip) {
  printf("%s %u.%u.%u.%u\n", label, (unsigned)(ip >> 24), (unsigned)((ip >> 16) & 255u),
         (unsigned)((ip >> 8) & 255u), (unsigned)(ip & 255u));
}

int main(void) {
  unsigned a, b, c, d;
  int prefix;
  sscanf("172.16.5.130/20", "%u.%u.%u.%u/%d", &a, &b, &c, &d, &prefix);

  uint32_t ip = (a << 24) | (b << 16) | (c << 8) | d;
  uint32_t mask = prefix == 0 ? 0u : 0xFFFFFFFFu << (32 - prefix);
  uint32_t network = ip & mask;
  uint32_t broadcast = network | ~mask;

  print_ip("mask     ", mask);
  print_ip("network  ", network);
  print_ip("broadcast", broadcast);
  printf("hosts     %u\n", (unsigned)((1u << (32 - prefix)) - 2u));
  return 0;
}
Read the full lesson