function print_prefix(prefix, count, status) { printf "%-20s%-10s%s\n", prefix, count, status } function d2b(d, b) { while(d) { b=d%2b d=int(d/2) } return b } function ip2dec(prefix) { split(prefix, splitted_prefix, ".") b1 = splitted_prefix[1] * 256^3 b2 = splitted_prefix[2] * 256^2 b3 = splitted_prefix[3] * 256 b4 = splitted_prefix[4] return b1 + b2 + b3 + b4 } function dec2ip(dec_prefix) { b1 = int(dec_prefix/256^3) % 256 b2 = int(dec_prefix/256^2) % 256 b3 = int(dec_prefix/256) % 256 b4 = int(dec_prefix) % 256 return b1 "." b2 "." b3 "." b4 } function compute_prefix(prefix, count, status) { split(prefix, bytes, ".") # Everything in 151.216.0.0/13 is reserved for temporary assignments if(bytes[1] == 151 && bytes[2] >= 216 && bytes[2] <= 223) { return } # Everything in 185.0.0.0/15 is reserved for IXP assignments if(bytes[1] == 185 && bytes[2] <= 1) { return } for(i = 4; i >= 0; i--) { if(bytes[i] != 0) { bin = d2b(bytes[i]) idx = match(bin, /0*$/) host_bytes = 1 substr(bin, idx, 9 - idx) split(host_bytes, msb, "") max_count = 2^(length(msb) - 1) * 256 ^ (4 - i) if(max_count > count) { max_count = count } cidr = 32 - log(max_count)/log(2) remainder = count - max_count if(cidr <= 24) { print_prefix(prefix "/" cidr, max_count, status) count_alloc = count_alloc + 2^(24-cidr) } if(remainder > 0) { new_prefix = dec2ip(ip2dec(prefix) + max_count) compute_prefix(new_prefix, remainder, status) } return } } } BEGIN { FS = "|" print_prefix("Prefix", "Addresses", "Status") count_alloc = 0 } $3 == "ipv4" && $7 ~ /(reserved|available)/ && $5 >= 256 { compute_prefix($4, $5, $7) } END { print "Number of /24 available for future allocation: " count_alloc }