// SPDX-License-Identifier: GPL-2.0 /* * iptool.c - Simple IP subnet calculator * * Takes an IPv4 address and a prefix length, then calculates: * - IP class * - Network address * - Broadcast address * - Total hosts * - Usable hosts * - Usable IP range */ #include #include #include #define PROGRAM_NAME "iptool" static uint32_t ip_to_u32(const char *ip_str) { int o1, o2, o3, o4; if (sscanf(ip_str, "%d.%d.%d.%d", &o1, &o2, &o3, &o4) != 4) { fprintf(stderr, "Invalid IP format: %s\n", ip_str); exit(1); } if (o1 < 0 || o1 > 255 || o2 < 0 || o2 > 255 || o3 < 0 || o3 > 255 || o4 < 0 || o4 > 255) { fprintf(stderr, "IP octet out of range: %s\n", ip_str); exit(1); } return (o1 << 24) | (o2 << 16) | (o3 << 8) | o4; } static uint32_t netmask_from_prefix(int prefix) { return prefix ? 0xFFFFFFFFU << (32 - prefix) : 0; } static uint32_t network_addr(uint32_t ip, uint32_t netmask) { return ip & netmask; } static uint32_t broadcast_addr(uint32_t ip, uint32_t netmask) { return (ip & netmask) | ~netmask; } static uint32_t total_hosts(int prefix) { return 1U << (32 - prefix); } static uint32_t usable_hosts(int prefix) { uint32_t th = total_hosts(prefix); return (th <= 2) ? 0 : th - 2; } static char ip_class(uint32_t ip) { uint8_t first_octet = ip >> 24; if (first_octet <= 127) return 'A'; if (first_octet <= 191) return 'B'; if (first_octet <= 223) return 'C'; if (first_octet <= 239) return 'D'; return 'E'; } static void print_ip(uint32_t ip) { printf("%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); } int main(int argc, char *argv[]) { uint32_t ip, netmask, network, broadcast; int prefix; uint32_t total, usable; if (argc < 3) { fprintf(stderr, "Usage: %s \n", PROGRAM_NAME); return 1; } ip = ip_to_u32(argv[1]); prefix = atoi(argv[2]); if (prefix < 0 || prefix > 32) { fprintf(stderr, "Prefix must be 0-32\n"); return 1; } netmask = netmask_from_prefix(prefix); network = network_addr(ip, netmask); broadcast = broadcast_addr(ip, netmask); total = total_hosts(prefix); usable = usable_hosts(prefix); printf("IP Class: %c\n", ip_class(ip)); printf("Network: "); print_ip(network); printf("\n"); printf("Broadcast: "); print_ip(broadcast); printf("\n"); printf("Total hosts: %u\n", total); printf("Usable hosts: %u\n", usable); if (usable > 0) { printf("Usable IP range: "); print_ip(network + 1); printf(" - "); print_ip(broadcast - 1); printf("\n"); } else { printf("No usable IPs in this subnet\n"); } return 0; }