From 71e6651c01362841443ded86c459772f1dbe59b6 Mon Sep 17 00:00:00 2001 From: bolvan <k@vodka.home.kg> Date: Wed, 10 Apr 2019 12:05:49 +0300 Subject: [PATCH] ip2net cosmetic fixes --- ip2net/ip2net.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/ip2net/ip2net.c b/ip2net/ip2net.c index 63c2dae..b2c6816 100644 --- a/ip2net/ip2net.c +++ b/ip2net/ip2net.c @@ -12,6 +12,10 @@ // minimum subnet fill percent is PCTMULT/PCTDIV (for example 3/4) #define PCTMULT 3 #define PCTDIV 4 +// subnet search range in "zero bit count" +// means search start from /(32-ZCT_MAX) to /(32-ZCT_MIN) +#define ZCT_MAX 10 +#define ZCT_MIN 2 typedef unsigned int uint; typedef unsigned char uchar; @@ -33,7 +37,7 @@ uint mask_from_bitcount(uint zct) // make presorted array unique. return number of unique items. // 1,1,2,3,3,0,0,0 (ct=8) => 1,2,3,0 (ct=4) -uint unique_uint(uint *pu,uint ct) +uint unique(uint *pu,uint ct) { uint i,j,u; for(i=j=0 ; j<ct ; i++) @@ -85,37 +89,36 @@ int main() } gnu_quicksort(iplist,ipct,sizeof(*iplist),ucmp,NULL); - ipct = unique_uint(iplist,ipct); + ipct = unique(iplist,ipct); while(pos<ipct) { - uchar subnet_ok=0; uint mask,ip_start,ip_end,ip_ct,subnet_ct,pos_end; - for(zct=10, pos_end=pos+1 ; zct>=2 ; zct--) + + // find largest possible network with enough ip coverage + for(zct=ZCT_MAX ; zct>=ZCT_MIN ; zct--) { mask = mask_from_bitcount(zct); ip_start = iplist[pos] & mask; subnet_ct = ~mask+1; - if (iplist[pos]>(ip_start+subnet_ct*(PCTDIV-PCTMULT)/PCTDIV)) continue; + if (iplist[pos]>(ip_start+subnet_ct*(PCTDIV-PCTMULT)/PCTDIV)) + continue; // ip is higher than (1-PCT). definitely coverage is not enough. skip searching ip_end = ip_start | ~mask; - for(p=pos, ip_ct=0 ; p<ipct && iplist[p]<=ip_end; p++) ip_ct++; + for(p=pos, ip_ct=0 ; p<ipct && iplist[p]<=ip_end; p++) ip_ct++; // count ips within subnet range if (ip_ct>=(subnet_ct*PCTMULT/PCTDIV)) { - subnet_ok=1; - pos_end = p; - break; + // network found + pos_end = p; + break; } } - if (!subnet_ok) zct=0,ip_start=iplist[pos]; + if (zct<ZCT_MIN) zct=0, ip_start=iplist[pos], pos_end=pos+1; // network not found, use single ip u1 = ip_start>>24; u2 = (ip_start>>16) & 0xFF; u3 = (ip_start>>8) & 0xFF; u4 = ip_start & 0xFF; - if (zct) - printf("%u.%u.%u.%u/%u\n",u1,u2,u3,u4,32-zct); - else - printf("%u.%u.%u.%u\n",u1,u2,u3,u4); + printf(zct ? "%u.%u.%u.%u/%u\n" : "%u.%u.%u.%u\n", u1, u2, u3, u4, 32-zct); pos = pos_end; }