#include <stdio.h>
#include <stdlib.h>
main(int argc,char **argv) {
 char linia[500],l1[200],country[20],*iptable;
 unsigned ip1,ip2,ip3,ip4,eip1,eip2,eip3,eip4;
 unsigned jump,mask,maskmax,iptsize;

 if(argc!=3) {
  fputs(
"RIPE database to squid acl converter\n\n"
"Usage:\n"
"download ripe.db.in.gz from ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.in.gz\n"
"then run\n\n"
"zcat ripe.db.in.gz|ripe2acl country maxmask >aclfile\n"
"where:\n\n"
"country - 2 letter country code for which generate acl's\n"
"maxmask - defines maximum mask value in output\n"
"value 26 of maxmask (i.e. min 64 IP allocation) seems good as RIPE never allocated smaller zones\n"
"using smaller value means less exact acl's but less memory usage\n"
"maximum memory required is 1<<maxmask which equals to 64MB with maxmask=26\n\n"
"use acl acl_name dst \"generated file name\" in squid.conf\n",stderr);
 exit(1);}

 strcpy(country,"*cy: ");
 strcat(country,argv[1]);
 maskmax=atoi(argv[2]);
 iptsize=(1<<maskmax);
 iptable=calloc(1,iptsize);
 if(!iptable) {
  fprintf(stderr,"error allocating %d bytes of memory",iptsize);
  exit(1);}
 while(gets(linia)) {
  if(!memcmp(linia,"*in: ",5))
   strcpy(l1,linia);
  if(!strcmp(linia,country)) {
   if(8!=sscanf(l1,"*in: %u.%u.%u.%u - %u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4,&eip1,&eip2,&eip3,&eip4)) {
    fputs("RIPE database broken or they changed format!!!\n",stderr); exit(1);}
   ip1=((ip1<<24)+(ip2<<16)+(ip3<<8)+ip4)>>(32-maskmax);
   eip1=((eip1<<24)+(eip2<<16)+(eip3<<8)+eip4)>>(32-maskmax);
   while(ip1<=eip1) iptable[ip1++]=maskmax; 
 } }
 
//IP table compression
 for(jump=1,mask=maskmax;mask>0;jump<<=1,mask--)  {
  for(ip1=0;ip1<iptsize;ip1+=(jump<<1))
   if((iptable[ip1]==mask)&&(iptable[ip1]==iptable[ip1+jump])) {
    iptable[ip1]--; iptable[ip1+jump]=0;
 } }
 
  for(ip1=0;ip1<iptsize;ip1++)
   if(iptable[ip1]) {
    ip2=ip1<<(32-maskmax);
    printf("%d.%d.%d.%d/%d\n",ip2>>24,(ip2>>16)&0xff,(ip2>>8)&0xff,ip2&0xff,iptable[ip1]);
}  }
   

