Created
December 4, 2012 11:28
-
-
Save citrin/4202877 to your computer and use it in GitHub Desktop.
Convert IPv4 range to list of CIDR prefixes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <arpa/inet.h> | |
#include <assert.h> | |
#include <err.h> | |
#include <inttypes.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <strings.h> | |
#define IPv4_BITS 32 | |
static inline int min(int a, int b) | |
{ | |
return (a < b ? a : b); | |
} | |
static void | |
print_cidr(const char *start_ip, const char *end_ip) | |
{ | |
struct in_addr ip; | |
uint32_t start, end; | |
int zero_bits, bits; | |
if (!inet_aton(start_ip, &ip)) | |
err(1, "inet_aton() for %s failed", start_ip); | |
start = ntohl(ip.s_addr); | |
if (!inet_aton(end_ip, &ip)) | |
err(1, "inet_aton() for %s failed", end_ip); | |
end = ntohl(ip.s_addr); | |
if(start > end) | |
errx(1, "bad IP order: %s - %s", start_ip, end_ip); | |
while (start <= end) { | |
/* trailing zeros in IP determine max possible | |
* prefix size for this IP | |
*/ | |
zero_bits = start == 0 ? IPv4_BITS : ffs(start) - 1; | |
/* ip count in this prefix: 2^bits */ | |
bits = min(fls(end - start + 1) - 1, zero_bits); | |
ip.s_addr = htonl(start); | |
printf("%s/%d\n", inet_ntoa(ip), IPv4_BITS - bits); | |
start += 1 << bits; | |
} | |
return; | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
/* check, that IP address fits into int */ | |
assert(sizeof(int) >= sizeof(uint32_t)); | |
printf("CIDR ranges for 192.168.0.1-192.168.255.254:\n"); | |
print_cidr("192.168.0.1", "192.168.255.254"); | |
printf("\n"); | |
printf("CIDR ranges for 0.0.0.1-255.255.255.254:\n"); | |
print_cidr("0.0.0.1", "255.255.255.254"); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment