#include #include #include #include #include #include #include #include "smooth.h" #include "lsq.h" // max is 2**32 - 1 #define MAX 4294967295UL // slash8 IS 2**24 #define SLASH8 16777216 // start of the stats series #define START 1984 // baseline day count for the projection models - 3 years #define DAYSPAN 1095 // smoothing window - 71 days wide #define SMOOTH 71 // clip the smoothed array by (SMOOTH - 1) /2 at the start and finish #define CLIP ((SMOOTH - 15) / 2) // max /8 handed out by IANA to an RIR in a single transaction #define MAXIANA 2 // address compression factor for traded addresses #define COMPRESSION 0.25 // additional compression per day #define DAILY_COMPRESSION 0.005 // the holdback per RIR #define HOLDBACK 1 // advertised / unadvertised slope correction factor //#define ADV_FACTOR 1.0013 #define ADV_FACTOR 1.00 // per RIR thresholds for IANA allocation #define AFRINIC_THRESH 0.45 #define APNIC_THRESH 1.75 #define ARIN_THRESH 3.0 #define LACNIC_THRESH 0.60 #define RIPE_THRESH 1.3 // RIR Count #define RIRS 5 // ADDRESS STATES #define IANA 0 #define IETF 1 #define IANA_R 2 #define AFRINIC 3 #define APNIC 4 #define ARIN 5 #define RIPENCC 6 #define LACNIC 7 #define VARIOUS 8 #define MINREG 2 #define MAXREG 9 #define RIR 9 #define ASSIGNED 10 #define ADVERTISED 11 #define MAXPOOLS 12 char *WDIR = "." ; /* working directory */ struct tm tmd ; /* time structures */ time_t tv, now, tvstart ; int tvv ; int maxdayno ; int daystart ; /* Start best fit projections from (now - DAYSPAN) days */ unsigned long int pools[MAXPOOLS] = {0,0,0,0,0,0,0,0,0,0,0,0}; unsigned long int assigned_pools[MAXPOOLS] = {0,0,0,0,0,0,0,0,0,0,0,0}; unsigned long int advertised_pools[MAXPOOLS] = {0,0,0,0,0,0,0,0,0,0,0,0}; int print_flag = 0 ; char *regs[] = {"allocated","ietf","iana","afrinic","apnic","arin","ripencc","lacnic","various","rirs"} ; char *regnames[] = {"IANA_Pool","IETF_Reserved","IANA_Registry","AFRINIC","APNIC","ARIN","RIPENCC","LACNIC","VARIOUS", "RIRS","ASSIGNED","ADVERTISED"} ; char *rpts[] = {"ipv4.alloc.txt", //0 "ipv4.alloc.rirs.txt", //1 "ipv4.assign.txt", //2 "ipv4.assign.rirs.txt", //3 "ipv4.advert.txt", //4 "ipv4.advert.rirs.txt", //5 "ipv4.series.txt", //6 "ipv4.series.proj.txt", //7 "ipv4.status.txt", //8 "ipv4.series.advunadv.txt", //9 "ipv4.series.alloc.txt", //10 "ipv4.series.adv.txt", //11 "ipv4.series.unadv.txt", //12 "ipv4.series.unaratio.txt", //13 "ipv4.series.model.txt", //14 "ipv4.series.bgp.txt", //15 "ipv4.series.rirs.txt", //16 "ipv4.series.modelb.txt"}; //17 extern void usage(); extern void fetch_files() ; extern void count_pool_totals() ; extern void sequencing(); extern void smoothdata(); extern void project(); extern double cvtime(int) ; struct address { unsigned int start ; /* start address value */ unsigned int count ; /* size of the block */ unsigned char registry ; /* registry value (regs 2 - 8 */ unsigned char alloc_registry ; unsigned char status ; /* IETF (1) IANA (0) RIR (9) ASSIGNED (10) ADVERTISED (11) */ unsigned int iana_date ; /* iana date */ unsigned int rir_date ; /* rir assignment date */ } ; struct add_list { struct address *addr ; struct add_list *nxt ; struct add_list *prv ; } ; struct slash8 { int pools[MAXPOOLS] ; struct add_list *addrs ; } *ipv4 ; struct sequence { int date ; unsigned int out ; unsigned int in ; struct sequence *nxt ; int trans ; unsigned int sum ; unsigned int pool ; unsigned int psum ; } *regseq[MAXPOOLS] = {0,0,0,0,0,0,0,0,0,0,0,0}, *reg_alloc[MAXPOOLS] = {0,0,0,0,0,0,0,0,0,0,0,0}; extern void alloc(int, int, int, int, int) ; struct series { double datef ; int date ; int day_of_year ; unsigned int pool_sum[MAXREG] ; unsigned int pool[MAXREG] ; unsigned int allocs[MAXREG] ; unsigned int reg_allocs[MAXREG] ; int trans[MAXREG] ; unsigned int iana[MAXREG]; unsigned int iana_recv[MAXREG] ; unsigned int in[MAXREG] ; unsigned int out[MAXREG] ; unsigned int adv ; unsigned int unadv ; } *series = 0 ; double *smoothed_adv ; double *smoothed_adv_1 ; double *smoothed_adv_2 ; double *smoothed_adv_3 ; double *smoothed_alloc_1 ; double *smoothed_alloc ; double *diff_alloc_1 ; double *smoothed_unadv ; double *smoothed_ratio ; double *iana_alloc ; double *smoothed_iana_alloc_1 ; double *smoothed_iana_alloc_2 ; double *smoothed_iana_alloc ; double *smoothed_tmp_1 ; double *smoothed_tmp_2 ; double *smoothed_reg ; double *smoothed_dreg_dt ; double *smoothed_regs[MAXREG] ; double *smoothed_dregs_dt[MAXREG] ; double rir_alloc_window[5][550] ; int rir_alloc_indx; int i_to_reg[5] = {2,3,1,4,0} ; double poolsize ; int main(int argc, char **argv) { int gopt ; int f_flag = 0 ; char cmd[1024] ; int ch ; while ((ch = getopt(argc, argv, "f")) != -1) { switch (ch) { case 'f': f_flag = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc) { WDIR = strdup(argv[0]) ; } tmd.tm_sec = 0 ; tmd.tm_min = 0 ; tmd.tm_hour = 12 ; tmd.tm_mday = 1 ; tmd.tm_mon = 0 ; tmd.tm_year = START - 1900 ; tv = mktime(&tmd) ; tvstart = tv ; tvv = (START * 10000) + 101 ; now = time(0) ; maxdayno = ((now - tv) / 86400) + 1 ; daystart = maxdayno - DAYSPAN ; if (f_flag) fetch_files() ; printf("Allocation and advertisement data\n") ; count_pool_totals() ; printf("Sequencing\n") ; sequencing() ; printf("Smoothdata\n") ; smoothdata() ; printf("Project\n") ; project() ; } /*----------------------------*/ void usage() { printf("ipv4 [-f] [directory] - fetch data files \n") ; } void fetch_files() { char cmd[1024] ; sprintf(cmd,"/usr/local/bin/wget -O %s/delegated.arin.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/arin/delegated",WDIR); printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/delegated.apnic.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/apnic/delegated",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/delegated.afrinic.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/afrinic/delegated",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/delegated.ripencc.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/ripe/delegated",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/delegated.lacnic.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/lacnic/delegated",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/delegated.iana.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/iana/delegated",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/rirdb.txt -q -o /dev/null http://www.potaroo.net/bgp/stats/rir-rpt-errors.txt",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/bgp.txt -q -o /dev/null http://www.potaroo.net/bgp/as2.0/bgptable.txt",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; sprintf(cmd,"/usr/local/bin/wget -O %s/bgp.series.txt -q -o /dev/null http://www.potaroo.net/bgp/as2.0/bgp-total-space.txt",WDIR) ; printf("%s\n",cmd) ; system(cmd) ; } void count_pool_totals() { char line[1024], sline[2048]; char *f[7] ; char *cp ; int registry ; int count ; int i, mask, rir, y, m, e, j ; FILE *inf ; double maxd ; int astatus ; unsigned int q[3], address, date ; char fon[256] ; FILE *fo; int col ; struct tm *tmp; time_t now; double year, ratio ; int maxt, size ; struct add_list *t ; struct address *ap; struct days { double fdate ; int date ; int unadv, adv ; int rir_unadv[MAXREG],rir_adv[MAXREG]; } *da ; init_list() ; sprintf(line,"%s/%s",WDIR,"delegated.iana.txt") ; inf = fopen(line,"r"); while (fgets(line,1024,inf)) { if (cp = strchr(line,'\n')) *cp = '\0'; strcpy(sline,line) ; f[0] = line ; i = 0 ; while ((i < 6) && (cp = strchr(f[i],'|'))) { *cp++ = '\0'; f[++i] = cp ; } if ((*f[1] == '*') || (strcmp(f[2],"ipv4"))) continue ; count = atoi(f[4]) ; sscanf(f[3],"%d.%d.%d.%d",&q[0],&q[1],&q[2],&q[3]) ; address = (q[0] << 24) + (q[1] << 16) + (q[2] << 8) + q[3] ; date = atoi(f[5]) ; if (!strcmp(f[6],"assigned")) { registry = 2 ; } else { registry = 8 ; for (i = 1 ; i < 8 ; ++i) if (!strcmp(f[6],regs[i])) registry = i ; } if (registry > 1) astatus = RIR ; else astatus = 1 ; add_entry(address,count,registry,date,astatus) ; if (registry == 2) { add_entry(address,count,registry,date,ASSIGNED) ; } } fclose(inf) ; for (rir = 0 ; rir < 5 ; ++rir) { sprintf(line,"%s/%s%s%s",WDIR,"delegated.",regs[rir+3],".txt") ; inf = fopen(line,"r"); while (fgets(line,1024,inf)) { if (cp = strchr(line,'\n')) *cp = '\0'; f[0] = line ; i = 0 ; while ((i < 6) && (cp = strchr(f[i],'|'))) { *cp++ = '\0'; f[++i] = cp ; } if ((*f[1] == '*') || (strcmp(f[2],"ipv4"))) continue ; count = atoi(f[4]) ; sscanf(f[3],"%d.%d.%d.%d",&q[0],&q[1],&q[2],&q[3]) ; address = (q[0] << 24) + (q[1] << 16) + (q[2] << 8) + q[3] ; registry = rir + 3; date = atoi(f[5]) ; registry = rir + 3 ; add_entry(address,count,registry,date,ASSIGNED) ; } fclose(inf) ; } sprintf(line,"%s/rirdb.txt",WDIR) ; inf = fopen(line,"r"); while (fgets(line,1024,inf)) { if (strncmp(line,"IPv4:ripe",9)) continue ; if (cp = strchr(line,'\n')) *cp = '\0'; i = strlen(line) ; if (strncmp(&line[i-12],"Not_in_stats",12)) continue ; line[i-13] = '\0'; if (cp = strrchr(line,'/')) { *cp++ = '\0'; mask = 32 - atoi(cp) ; count = (1 << mask) ; registry = RIPENCC; cp = strrchr(line,' ') ; ++cp ; sscanf(cp,"%d.%d.%d.%d",&q[0],&q[1],&q[2],&q[3]) ; address = (q[0] << 24) + (q[1] << 16) + (q[2] << 8) + q[3] ; date = 0 ; add_entry(address,count,registry,date,ASSIGNED) ; } } fclose(inf) ; maxd = (double) MAX ; poolsize = (maxd - pools[IETF]) / (double) SLASH8 ; sprintf(fon,"%s/%s",WDIR,rpts[0]) ; fo = fopen(fon,"w") ; fprintf(fo,"IETF_Reserved %u %6.4f %3.1f%%\n",pools[IETF],(pools[IETF] / (double) SLASH8), 100.0 * (pools[IETF]/maxd)) ; fprintf(fo,"IANA_Pool %u %6.4f %3.1f%%\n",pools[IANA],(pools[IANA] / (double) SLASH8),100.0 * (pools[IANA]/maxd)) ; fprintf(fo,"Allocated %u %6.4f %3.1f%%\n",(pools[RIR] + pools[ASSIGNED]),((pools[RIR] + pools[ASSIGNED]) / (double) SLASH8),100.0 * ((pools[RIR] + pools[ASSIGNED])/maxd)) ; fclose(fo) ; sprintf(fon,"%s/%s",WDIR,rpts[1]) ; fo = fopen(fon,"w") ; astatus = IETF; fprintf(fo,"%s %u %6.4f %3.1f%%\n",regnames[astatus],(pools[astatus] + assigned_pools[astatus]), ((pools[astatus] + assigned_pools[astatus]) / (float) SLASH8), 100.0 * ((pools[astatus] + assigned_pools[astatus]) / maxd)) ; astatus = IANA; fprintf(fo,"%s %u %6.4f %3.1f%%\n",regnames[astatus],(pools[astatus] + assigned_pools[astatus]), ((pools[astatus] + assigned_pools[astatus]) / (float) SLASH8), 100.0 * ((pools[astatus] + assigned_pools[astatus]) / maxd)) ; astatus = IANA_R; fprintf(fo,"%s %u %6.4f %3.1f%%\n",regnames[astatus],(pools[astatus] + assigned_pools[astatus]), ((pools[astatus] + assigned_pools[astatus]) / (float) SLASH8), 100.0 * ((pools[astatus] + assigned_pools[astatus]) / maxd)) ; astatus = VARIOUS; fprintf(fo,"%s %u %6.4f %3.1f%%\n",regnames[astatus],(pools[astatus] + assigned_pools[astatus]), ((pools[astatus] + assigned_pools[astatus]) / (float) SLASH8), 100.0 * ((pools[astatus] + assigned_pools[astatus]) / maxd)) ; for (astatus = MINREG + 1; astatus < (MAXREG - 1) ; ++astatus) { fprintf(fo,"%s %u %6.4f %3.1f%%\n",regnames[astatus],(pools[astatus] + assigned_pools[astatus]), ((pools[astatus] + assigned_pools[astatus]) / (float) SLASH8), 100.0 * ((pools[astatus] + assigned_pools[astatus]) / maxd)) ; } fclose(fo) ; sprintf(fon,"%s/%s",WDIR,rpts[2]) ; fo = fopen(fon,"w") ; fprintf(fo,"IETF_Reserved %u %6.4f %3.1f%%\n",pools[IETF],(pools[IETF] / (float) SLASH8), 100.0 * (pools[IETF]/maxd)) ; fprintf(fo,"IANA_Pool %u %6.4f %3.1f%%\n",pools[IANA],(pools[IANA] / (float) SLASH8),100.0 * (pools[IANA]/maxd)) ; fprintf(fo,"Allocated %u %6.4f %3.1f%%\n",pools[RIR],(pools[RIR] / (float) SLASH8),100.0 * (pools[RIR]/maxd)) ; fprintf(fo,"Assigned %u %6.4f %3.1f%%\n",pools[ASSIGNED],(pools[ASSIGNED] / (float) SLASH8),100.0 * (pools[ASSIGNED]/maxd)) ; fclose(fo) ; sprintf(fon,"%s/%s",WDIR,rpts[3]) ; fo = fopen(fon,"w") ; for (astatus = 1 ; astatus < MINREG ; ++astatus) { fprintf(fo,"%s %d %6,4f %3.1f%%\n",regnames[astatus],pools[astatus],(pools[astatus] / (float) SLASH8),100.0 * (pools[astatus] / maxd)) ; } for (astatus = MINREG ; astatus < MAXREG ; ++astatus) { fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Pool",pools[astatus],pools[astatus] / (float) SLASH8,100.0 * (pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%%\n",regnames[astatus],"Assigned",assigned_pools[astatus],assigned_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; } fclose(fo) ; sprintf(line,"%s/bgp.txt",WDIR) ; inf = fopen(line,"r"); while (fgets(line,1024,inf)) { if (!isdigit(line[3])) continue ; count = 0 ; if (cp = strchr(line,'/')) { *cp++ = '\0'; mask = 32 - atoi(cp) ; count = (1 << mask) ; } sscanf(&line[3],"%d.%d.%d.%d",&q[0],&q[1],&q[2],&q[3]) ; address = (q[0] << 24) + (q[1] << 16) + (q[2] << 8) + q[3] ; if (!count) { if (q[0] < 128) count = (1 << 24) ; else if (q[0] < 192) count = (1 << 16) ; else count = (1 << 8) ; } date = 0 ; registry = 0 ; add_entry(address,count,registry,date,ADVERTISED) ; } fclose(inf) ; sprintf(fon,"%s/%s",WDIR,rpts[4]) ; fo = fopen(fon,"w") ; fprintf(fo,"IETF_Reserved %u %6.4f %3.1f%%\n",pools[IETF],(pools[IETF] / (float) SLASH8), 100.0 * (pools[IETF]/maxd)) ; fprintf(fo,"IANA_Pool %u %6.4f %3.1f%%\n",pools[IANA],(pools[IANA] / (float) SLASH8),100.0 * (pools[IANA]/maxd)) ; fprintf(fo,"Allocated %u %6.4f %3.1f%%\n",pools[RIR],(pools[RIR] / (float) SLASH8),100.0 * (pools[RIR]/maxd)) ; fprintf(fo,"Assigned %u %6.4f %3.1f%%\n",pools[ASSIGNED],(pools[ASSIGNED] / (float) SLASH8),100.0 * (pools[ASSIGNED]/maxd)) ; fprintf(fo,"Advertised %u %6.4f %3.1f%%\n",pools[ADVERTISED],(pools[ADVERTISED] / (float) SLASH8),100.0 * (pools[ADVERTISED]/maxd)) ; fclose(fo) ; sprintf(fon,"%s/%s",WDIR,rpts[5]) ; fo = fopen(fon,"w") ; astatus = IETF; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Pool",pools[astatus],pools[astatus] / (float) SLASH8,100.0 * (pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Assigned",assigned_pools[astatus],assigned_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%%\n",regnames[astatus],"Advertised",advertised_pools[astatus],advertised_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; astatus = IANA; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Pool",pools[astatus],pools[astatus] / (float) SLASH8,100.0 * (pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Assigned",assigned_pools[astatus],assigned_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%%\n",regnames[astatus],"Advertised",advertised_pools[astatus],advertised_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; astatus = IANA_R; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Pool",pools[astatus],pools[astatus] / (float) SLASH8,100.0 * (pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Assigned",assigned_pools[astatus],assigned_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%%\n",regnames[astatus],"Advertised",advertised_pools[astatus],advertised_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; astatus = VARIOUS; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Pool",pools[astatus],pools[astatus] / (float) SLASH8,100.0 * (pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Assigned",assigned_pools[astatus],assigned_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%%\n",regnames[astatus],"Advertised",advertised_pools[astatus],advertised_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; for (astatus = MINREG + 1; astatus < MAXREG - 1 ; ++astatus) { fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Pool",pools[astatus],pools[astatus] / (float) SLASH8,100.0 * (pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%% ",regnames[astatus],"Assigned",assigned_pools[astatus],assigned_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; fprintf(fo,"%s_%s %d %6.4f %3.1f%%\n",regnames[astatus],"Advertised",advertised_pools[astatus],advertised_pools[astatus] / (float) SLASH8,100.0 * (assigned_pools[astatus] / maxd)) ; } fclose(fo) ; sprintf(fon,"%s/%s",WDIR,rpts[8]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Block IETF IANA RIR ASGN/UNADV ASGN/ADV\n") ; for (col = 0 ; col < 256 ; ++col) { fprintf(fo,"%05d %5d %5d %5d %5d %5d\n",col, ipv4[col].pools[IETF],ipv4[col].pools[IANA],ipv4[col].pools[RIR],ipv4[col].pools[ASSIGNED],ipv4[col].pools[ADVERTISED]) ; } fclose(fo) ; // we need to generate a sequence of rir allocation dates on a month-by month // basis and then print them out // the array is from START until the present // this approach is to generate the array size, populate it and then print it out // generate the array size now = time(0) ; tmp = localtime(&now) ; //maxt = ((tmp->tm_year + 1900) * 10000) + ((tmp->tm_mon + 1) * 100) + tmp->tm_mday ; size = ((tmp->tm_year + 1900) - START + 2) * 12 ; da = (struct days *) malloc((sizeof *da) * size) ; y = START ; m = 1 ; // initialize the array for (i = 0 ; i < size ; ++i) { da[i].date = (y * 10000) + (m * 100) + 1 ; da[i].fdate = cvtime(da[i].date) ; da[i].unadv = 0 ; da[i].adv = 0 ; for (j = 0 ; j < MAXREG ; ++j) da[i].rir_unadv[j] = da[i].rir_adv[j] = 0 ; if (++m > 12) { m = 1 ; ++y ; } } // scan the prefix set and populate the array based on rir allocation date // record advertised / unadvertised address counter per rir for (e = 0 ; e < 256 ; ++e) { t = ipv4[e].addrs ; while (t) { if ((t->addr->status == ADVERTISED) || (t->addr->status == ASSIGNED)) { date = t->addr->rir_date ; y = date / 10000 ; m = (date / 100) % 100 ; i = ((y - START) * 12) + m - 1 ; if (i < 0) i = 0 ; if (t->addr->status == ADVERTISED) { da[i].adv += t->addr->count ; da[i].rir_adv[t->addr->alloc_registry] += t->addr->count ; } else if (t->addr->status == ASSIGNED) { da[i].unadv += t->addr->count ; da[i].rir_unadv[t->addr->alloc_registry] += t->addr->count ; } } t = t->nxt ; } } // write out the array sprintf(fon,"%s/%s",WDIR,rpts[9]) ; fo = fopen(fon,"w") ; fprintf(fo,"Date Unadv Adv Unadv_perc Adv_perc ") ; fprintf(fo,"adv_afrinic adv_apnic adv_arin adv_ripe adv_lacnic "); fprintf(fo,"uadv_afrinic uadv_apnic uadv_arin uadv_ripe uadv_lacnic\n"); for (i = 0 ; i < size ; ++i) { if (da[i].unadv + da[i].adv) { ratio = ((double) da[i].unadv / (double) (da[i].unadv + da[i].adv)) * 100.0 ; fprintf(fo,"%8.3f %5.3f %5.3f %4.2f %4.2f ",da[i].fdate,((double)(da[i].unadv/(double) SLASH8)),((double)(da[i].adv/(double) SLASH8)),ratio,(100.0 - ratio)) ; for (j = 3 ; j < MAXREG - 1 ; ++j) fprintf(fo,"%10.8f ",(double)(da[i].rir_unadv[j] / (double) SLASH8)) ; for (j = 3 ; j < MAXREG - 1 ; ++j) fprintf(fo,"%10.8f ",(double)(da[i].rir_adv[j] / (double) SLASH8)) ; fprintf(fo,"\n") ; } } fclose(fo) ; // no further need for the detailed prefix structure - free off the memory free(da) ; clear_list() ; } void sequencing() { struct sequence *tmp ; int reg ; unsigned int psum ; unsigned int sum ; unsigned int pool ; struct tm *tp ; unsigned int in, out ; int dayno, cdayno ; FILE *seq, *fo; char line[1024], fon[256] ; int astot; unsigned acount, adcount ; unsigned long long dcount ; double dpsum,dsum,dpool,dtrans,din,dout,dadv,dunadv ; double yfrac; reg = IANA ; sum = 0 ; pool = MAX - pools[IETF] ; psum = MAX - pools[IETF] ; tmp = regseq[reg] ; while (tmp) { pool += tmp->in ; pool -= tmp->out ; sum += tmp->out ; psum -= tmp->out ; tmp->trans = tmp->in - tmp->out ; tmp->psum = psum ; tmp->sum = sum ; tmp->pool = pool ; //dpsum = (double)(tmp->psum / (double) SLASH8) ; //dsum = (double)(tmp->sum / (double) SLASH8) ; //dpool = (double)(tmp->pool / (double) SLASH8) ; //dtrans = (double)(tmp->trans / (double) SLASH8) ; //printf("%5.3f %u %5.3f %5.3f %5.3f %5.3f\n",cvtime(tmp->date),tmp->date,dpsum,dsum,dpool,dtrans); tmp = tmp->nxt ; } tmd.tm_sec = 0 ; tmd.tm_min = 0 ; tmd.tm_hour = 12 ; tmd.tm_mday = 1 ; tmd.tm_mon = 0 ; tmd.tm_year = START - 1900 ; tv = mktime(&tmd) ; tp = localtime(&tv) ; tvv = ((tmd.tm_year + 1900) * 10000) + ((tmd.tm_mon + 1) * 100) + tmd.tm_mday ; tmp = regseq[reg] ; sum = 0 ; pool = MAX - pools[IETF] ; psum = MAX - pools[IETF] ; in = out = 0 ; series = (struct series *) malloc((sizeof *series) * maxdayno) ; dayno = 0 ; while (tv < now) { in = out = 0; while (tmp && (tmp->date <= tvv)) { pool += tmp->in ; pool -= tmp->out ; sum += tmp->out ; psum -= tmp->out ; in += tmp->in ; out += tmp->out ; tmp = tmp->nxt ; } series[dayno].datef = cvtime(tvv) ; series[dayno].date = tvv ; series[dayno].day_of_year = tp->tm_yday ; series[dayno].pool_sum[IANA] = psum ; series[dayno].allocs[IANA] = sum ; series[dayno].trans[IANA] = in + out ; series[dayno].pool[IANA] = pool ; series[dayno].iana_recv[IANA] = in ; series[dayno].in[IANA] = in ; series[dayno].out[IANA] = out ; series[dayno].adv = 0 ; series[dayno].unadv = 0 ; //dpsum = (double)(series[dayno].pool_sum[IANA] / (double) SLASH8) ; //dsum = (double)(series[dayno].allocs[IANA] / (double) SLASH8) ; //dpool = (double)(series[dayno].pool[IANA] / (double) SLASH8) ; //dtrans = (double)(series[dayno].trans[IANA] / (double) SLASH8) ; //printf("%5.3f %u %5.3f %5.3f %5.3f %5.3f\n",cvtime(tvv),tvv,dpsum,dsum,dpool,dtrans); tv += 86400 ; tp = localtime(&tv) ; tvv = ((tp->tm_year + 1900) * 10000) + ((tp->tm_mon + 1) * 100) + tp->tm_mday ; ++dayno ; } for (reg = MINREG ; reg < MAXREG ; ++reg) { sum = 0 ; psum = 0 ; pool = 0 ; tmp = regseq[reg] ; while (tmp) { //if (reg == MINREG) tmp->in = tmp->out ; pool += tmp->in ; if (tmp->out > pool) { pool = 0 ; printf("%s %u %u %d .\n",regnames[reg],tmp->date,tmp->out,tmp->out - pool) ; } else pool -= tmp->out ; sum += tmp->out ; psum += tmp->in ; tmp->trans = tmp->in - tmp->out ; tmp->psum = psum ; tmp->sum = sum ; tmp->pool = pool ; //dpsum = (double)(tmp->psum / (double) SLASH8) ; //dsum = (double)(tmp->sum / (double) SLASH8) ; //dpool = (double)(tmp->pool / (double) SLASH8) ; //dtrans = (double)(tmp->trans / (double) SLASH8) ; //din = (double)(tmp->in / (double) SLASH8) ; //dout = (double)(tmp->out / (double) SLASH8) ; //if (reg == MINREG) printf("%5.3f %u %5.3f %5.3f %5.3f %5.3f %5.3f %5.3f\n",cvtime(tmp->date),tmp->date,dpsum,dsum,dpool,dtrans,din,dout); tmp = tmp->nxt ; } tmd.tm_sec = 0 ; tmd.tm_min = 0 ; tmd.tm_hour = 12 ; tmd.tm_mday = 1 ; tmd.tm_mon = 0 ; tmd.tm_year = START - 1900 ; tv = mktime(&tmd) ; tvv = ((tmd.tm_year + 1900) * 10000) + ((tmd.tm_mon + 1) * 100) + tmd.tm_mday ; tmp = regseq[reg] ; sum = 0 ; pool = 0 ; psum = 0 ; in = out = 0 ; dayno = 0 ; while (tv < now) { in = out = 0; while (tmp && (tmp->date <= tvv)) { pool += tmp->in ; if (tmp->out > pool) pool = 0 ; else pool -= tmp->out ; sum += tmp->out ; psum += tmp->in ; in += tmp->in ; out += tmp->out ; tmp = tmp->nxt ; } series[dayno].pool_sum[reg] = psum ; series[dayno].pool[reg] = pool ; series[dayno].allocs[reg] = sum ; series[dayno].trans[reg] = in + out ; series[dayno].iana_recv[reg] = in ; series[dayno].iana[reg] = psum ; series[dayno].in[reg] = in ; series[dayno].out[reg] = out ; //dpsum = (double)(series[dayno].pool_sum[reg] / (double) SLASH8) ; //dsum = (double)(series[dayno].allocs[reg] / (double) SLASH8) ; //dpool = (double)(series[dayno].pool[reg] / (double) SLASH8) ; //dtrans = (double)(series[dayno].trans[reg] / (double) SLASH8) ; //printf("%5.3f %u %5.3f %5.3f %5.3f %5.3f\n",cvtime(tvv),tvv,dpsum,dsum,dpool,dtrans); //printf("%5.3f %u %5.3f\n",cvtime(tvv),tvv,dpool); ++dayno ; tv += 86400 ; tp = localtime(&tv) ; tvv = ((tp->tm_year + 1900) * 10000) + ((tp->tm_mon + 1) * 100) + tp->tm_mday ; } } for (dayno = 0 ; dayno < maxdayno ; ++dayno) { series[dayno].pool_sum[1] = 0; series[dayno].pool[1] = 0; series[dayno].allocs[1] = 0; series[dayno].trans[1] = 0; series[dayno].iana[1] = 0 ; series[dayno].in[1] = 0 ; series[dayno].out[1] = 0 ; series[dayno].adv = 0 ; series[dayno].unadv = 0 ; for (reg = MINREG ; reg < MAXREG ; ++reg) { series[dayno].pool_sum[1] += series[dayno].pool_sum[reg]; series[dayno].pool[1] += series[dayno].pool[reg]; series[dayno].allocs[1] += series[dayno].allocs[reg]; series[dayno].trans[1] += series[dayno].trans[reg]; series[dayno].iana[1] += series[dayno].iana[reg] ; series[dayno].iana_recv[1] += series[dayno].iana_recv[reg] ; series[dayno].in[1] += series[dayno].in[reg] ; series[dayno].out[1] += series[dayno].out[reg] ; } } for (reg = MINREG ; reg < MAXREG - 1 ; ++reg) { // now run through the allocations made by each RIR sum = 0 ; tmp = reg_alloc[reg] ; while (tmp) { sum += tmp->out ; tmp->sum = sum ; tmp = tmp->nxt ; } tmd.tm_sec = 0 ; tmd.tm_min = 0 ; tmd.tm_hour = 12 ; tmd.tm_mday = 1 ; tmd.tm_mon = 0 ; tmd.tm_year = START - 1900 ; tv = mktime(&tmd) ; tvv = ((tmd.tm_year + 1900) * 10000) + ((tmd.tm_mon + 1) * 100) + tmd.tm_mday ; tmp = reg_alloc[reg] ; sum = 0 ; dayno = 0 ; while (tv < now) { in = out = 0; while (tmp && (tmp->date <= tvv)) { sum += tmp->out ; out += tmp->out ; tmp = tmp->nxt ; } series[dayno].reg_allocs[reg] = sum ; ++dayno ; tv += 86400 ; tp = localtime(&tv) ; tvv = ((tp->tm_year + 1900) * 10000) + ((tp->tm_mon + 1) * 100) + tp->tm_mday ; } } sprintf(fon,"%s/%s",WDIR,rpts[15]) ; fo = fopen(fon,"w") ; dayno = maxdayno; seq = fopen("bgp.series.txt","r") ; while (fgets(line,1024,seq)) { if (sscanf(line,"%u %u",&tv,&acount)== 2) { if (acount < 1000000000UL) continue ; if (acount > 2000000000UL) continue ; cdayno = (tv - tvstart) / 86400 ; tp = localtime(&tv) ; yfrac = (((double) (tp->tm_sec + (tp->tm_min * 60.0) + (tp->tm_hour * 3600.0)) / (double) 86400.0) + (double) tp->tm_yday) / (double) 366.0; yfrac += tp->tm_year + 1900.0; fprintf(fo,"%5.8f %5.3f\n",yfrac,acount / (double) SLASH8) ; //if we've moved onto the next day if (cdayno != dayno) { // then store the average of the previous day if (astot) { adcount = dcount / astot ; if (dayno < maxdayno) { series[dayno].adv = adcount ; if (series[dayno].adv > series[dayno].allocs[1]) { series[dayno].adv = series[dayno].allocs[1] ; series[dayno].unadv = 0 ; } else series[dayno].unadv = series[dayno].allocs[1] - series[dayno].adv ; } } dcount = 0 ; astot = 0 ; } dayno = cdayno ; dcount += acount ; ++astot ; } } adcount = dcount / astot ; if (dayno < maxdayno) { series[dayno].adv = adcount ; if (series[dayno].adv > series[dayno].allocs[1]) { series[dayno].adv = series[dayno].allocs[1] ; series[dayno].unadv = 0 ; } else series[dayno].unadv = series[dayno].allocs[1] - series[dayno].adv ; } fclose(seq) ; fclose(fo) ; sprintf(fon,"%s/%s",WDIR,rpts[6]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Dayno Year Date IANA_pool IANA_allocs IANA_trans IANA_recv ") ; fprintf(fo,"%s_pool %s_allocs %s_trans %s_recv ","RIR","RIR","RIR","RIR") ; for (reg = MINREG ; reg < MAXREG; ++reg) { fprintf(fo,"%s_pool %s_allocs %s_trans %s_recv ",regnames[reg],regnames[reg],regnames[reg],regnames[reg]) ; } fprintf(fo,"Unadv Adv Un/Ad_Ratio\n") ; for (dayno = 0 ; dayno < maxdayno ; ++dayno) { if (dayno && (!series[dayno].adv)) { series[dayno].adv = series[dayno - 1].adv ; if (series[dayno].adv > series[dayno].allocs[1]) { series[dayno].adv = series[dayno].allocs[1] ; series[dayno].unadv = 0 ; } else series[dayno].unadv = series[dayno].allocs[1] - series[dayno].adv ; } fprintf(fo,"%d %5.3f %d ",dayno,series[dayno].datef,series[dayno].date); for (reg = 0 ; reg < MAXREG ; ++reg) { dpsum = (double)(series[dayno].pool[reg] / (double) SLASH8) ; dsum = (double)(series[dayno].allocs[reg] / (double) SLASH8) ; dtrans = (double)(series[dayno].trans[reg] / (double) SLASH8) ; dpool = (double)(series[dayno].iana[reg] / (double) SLASH8) ; fprintf(fo,"%5.3f %5.3f %5.3f %5.3f ",dpsum,dsum,dtrans,dpool); } dunadv = (double)(series[dayno].unadv / (double) SLASH8) ; dadv = (double)(series[dayno].adv / (double) SLASH8) ; fprintf(fo,"%5.3f %5.3f ",dunadv,dadv) ; if (series[dayno].adv > 0) { fprintf(fo,"%6.4f",(dunadv /dadv)) ; } else fprintf(fo,"%6.4f",0.0) ; fprintf(fo,"\n") ; } fclose(fo) ; } void smoothdata() { double *data ; int dayno ; double ming, maxg ; int reg ; data = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_adv = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_adv_1 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_adv_2 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_adv_3 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_alloc = (double *) malloc((sizeof *data) * maxdayno) ; diff_alloc_1 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_alloc_1 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_unadv = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_ratio = (double *) malloc((sizeof *data) * maxdayno) ; iana_alloc = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_iana_alloc_1 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_iana_alloc_2 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_iana_alloc = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_tmp_1 = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_tmp_2 = (double *) malloc((sizeof *data) * maxdayno) ; // advertised size -> smoothed_adv for (dayno = 0 ; dayno < maxdayno ; ++dayno) data[dayno] = (double) (series[dayno].adv / (double) SLASH8); smooth(data, smoothed_adv_1, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_adv_1, smoothed_adv_2, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_adv_2, smoothed_adv_3, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_adv_3, smoothed_adv, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; // rir allocations -> smoothed_alloc for (dayno = 0 ; dayno < maxdayno ; ++dayno) data[dayno] = (double) (series[dayno].allocs[1] / (double) SLASH8); smooth(data, smoothed_alloc_1, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_alloc_1, smoothed_alloc, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_alloc, smoothed_alloc_1, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_alloc_1, smoothed_alloc, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; // unadvertised address pool -> smoothed_unadv for (dayno = 0 ; dayno < maxdayno ; ++dayno) { smoothed_unadv[dayno] = ((smoothed_alloc[dayno] - smoothed_adv[dayno]) < 0.0 ) ? 0.0 : (smoothed_alloc[dayno] - smoothed_adv[dayno]); iana_alloc[dayno] = (double)(series[dayno].allocs[0] / (double) SLASH8) ; } // unadvertised / advertised ratio -> smoothed_ratio for (dayno = 0 ; dayno < maxdayno ; ++dayno) { if (series[dayno].adv > 0) data[dayno] = (double) ( series[dayno].unadv / series[dayno].adv); else data[dayno] = 1.0 ; } smooth(data, smoothed_ratio, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; // iana allocations -> smoothed_iana_alloc smooth(iana_alloc,smoothed_iana_alloc_1,maxdayno, SMOOTH, 0.0, 0.0, &ming, &maxg) ; smooth(smoothed_iana_alloc_1,smoothed_iana_alloc_2,maxdayno, SMOOTH, 0.0, 0.0, &ming, &maxg) ; smooth(smoothed_iana_alloc_2,smoothed_iana_alloc,maxdayno, SMOOTH, 0.0, 0.0, &ming, &maxg) ; // rir allocation totals -> smoothed_reg for (reg = MINREG + 1 ; reg < MAXREG - 1 ; ++reg) { for (dayno = 0 ; dayno < maxdayno ; ++dayno) data[dayno] = (double) (series[dayno].reg_allocs[reg] / (double) SLASH8); smoothed_reg = smoothed_regs[reg] = (double *) malloc((sizeof *data) * maxdayno) ; smoothed_dreg_dt = smoothed_dregs_dt[reg] = (double *) malloc((sizeof *data) * maxdayno) ; smooth(data, smoothed_tmp_1, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_tmp_1, smoothed_tmp_2, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_tmp_2, smoothed_tmp_1, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_tmp_1, smoothed_tmp_2, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; smooth(smoothed_tmp_2, smoothed_reg, maxdayno, SMOOTH, 0.0,0.0,&ming,&maxg) ; } } void project() { double *xvals, *dxvals, *logvals ; struct lsq adv_avals, adv_expvals, alc_avals, alc_expvals, iana_avals, iana_expvals, unadv_avals, unadv_expvals ; struct lsq diff_alloc, diff_log_alloc, diff_adv, diff_log_adv, diff_unadv, diff_log_unadv, adv_ratio, d_adv_ratio ; int dayno, i, i_vars[4], spike ; double iana_amt, alloc_amt , adv_amt ; double last_date, a_corr, ur_corr, rval, cdate; double adv_dslope, adv_dintercept ; double adv_eslope, adv_eintercept ; double alc_dslope, alc_dintercept ; double alc_eslope, alc_eintercept ; double iana_dslope, iana_dintercept ; double iana_eslope, iana_eintercept ; double unadv_dslope, unadv_dintercept ; double unadv_eslope, unadv_eintercept ; double d_alloc_slope, d_alloc_intercept ; double d_log_alloc_slope, d_log_alloc_intercept ; double d_adv_slope, d_adv_intercept ; double d_log_adv_slope, d_log_adv_intercept ; double d_unadv_slope, d_unadv_intercept ; double d_log_unadv_slope, d_log_unadv_intercept ; double adv_ratio_slope, adv_ratio_intercept ; double d_adv_ratio_slope, d_adv_ratio_intercept ; double p_vars[5], p_inc[5], spikeval ; double rir_slope[7], rir_intercept[7]; struct lsq rir_vals[7] ; struct rir { double inc_window ; double pool ; double threshold ; double rate ; char *name ; int inc ; int empty ; } rirs[6] ; int all_ok ; char fon[256]; FILE *fo, *fob ; double reg_slope[MAXREG]; double reg_intercept[MAXREG]; struct lsq regs[MAXREG] ; double adv_dxslope, adv_dxintercept, adv_dxc, adv_dxcc, adv_dxcc_err, adv_dxcc_erru, adv_dxcc_errd, adv_dxval; struct lsq adv_dxvals ; double alc_dxslope, alc_dxintercept, alc_dxc, alx_dxval; struct lsq alc_dxvals ; double iana_dxslope, iana_dxintercept, iana_dxc, iana_dxval; struct lsq iana_dxvals ; double one_day ; int reg ; double daily_total ; double a_total ; double reg_c[MAXREG], cur_val[MAXREG], last_val[MAXREG] ; double dsum ; int dcount, dcc ; double *rirs_ratio[MAXREG] ; double *rir_ratio ; double dtt; int unadv_ok ; double rir_amt ; int rirs_empty ; double compress_factor = 0.75 ; int projected_day_count = 0 ; int loopcount ; int move ; double adv_g_ratio ; int counts[366] ; double variation[366]; time_t last_time ; struct tm *tp ; int yday ; double alloc_val ; double p_inc_1_offset ; double p_inc_2_offset ; xvals = (double *) malloc((sizeof *xvals) * maxdayno) ; logvals = (double *) malloc((sizeof *logvals) * maxdayno) ; dxvals = (double *) malloc((sizeof *logvals) * maxdayno) ; one_day = series[10].datef - series[9].datef ; // best fit of advertised count for (dayno = 0 ; dayno < maxdayno ; ++dayno) { xvals[dayno] = (double) (series[dayno].datef); logvals[dayno] = log(smoothed_adv[dayno]) ; if (dayno) dxvals[dayno] = (smoothed_adv[dayno] - smoothed_adv[dayno - 1])/one_day; } least_squares(&xvals[daystart],&smoothed_adv[daystart],dayno-daystart-CLIP, &adv_dslope, &adv_dintercept, &adv_avals); least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &adv_eslope, &adv_eintercept, &adv_expvals); least_squares(&xvals[daystart],&dxvals[daystart],dayno-daystart-CLIP, &adv_dxslope, &adv_dxintercept, &adv_dxvals); last_date = series[maxdayno - 1].datef ; // This sets the poly to join at the last data point adv_dxc = smoothed_adv[maxdayno - 1] - (((adv_dxslope * 0.5) * (pow(last_date,2))) + (adv_dxintercept * last_date)) ; // now to calculate the least error point adv_dxcc = adv_dxc ; move = 2 ; loopcount = 0 ; while ((move) && (loopcount < 50000)) { adv_dxcc_err = 0.0; adv_dxcc_erru = 0.0; adv_dxcc_errd = 0.0; for (dayno = daystart; dayno <= maxdayno - CLIP ; ++dayno) { cdate = series[dayno].datef ; adv_dxcc_err += smoothed_adv[dayno] - (((adv_dxslope * 0.5) * cdate * cdate) + (adv_dxintercept * cdate) + adv_dxcc) ; adv_dxcc_erru += smoothed_adv[dayno] - (((adv_dxslope * 0.5) * cdate * cdate) + (adv_dxintercept * cdate) + adv_dxcc+ 0.001) ; adv_dxcc_errd += smoothed_adv[dayno] - (((adv_dxslope * 0.5) * cdate * cdate) + (adv_dxintercept * cdate) + adv_dxcc - 0.001) ; } if (move == 2) { if ((adv_dxcc_erru > 0.0) && (adv_dxcc_errd > 0.0)) { move = 1 ; adv_dxcc += 0.001 ; } else if ((adv_dxcc_erru < 0.0) && (adv_dxcc_errd < 0.0)) { move = -1 ; adv_dxcc -= 0.001 ; } else move = 0 ; } else if (move > 0) { if ((adv_dxcc_erru > 0.0) && (adv_dxcc_errd > 0.0)) adv_dxcc += 0.001 ; else move = 0 ; } else if (move < 0) { if ((adv_dxcc_erru < 0.0) && (adv_dxcc_errd < 0.0)) adv_dxcc -= 0.001 ; else move = 0 ; } ++loopcount ; printf("%d %7.5f %7.5f (%7.5f %7.5f %7.5f %d)\n",loopcount,adv_dxc, adv_dxcc,adv_dxcc_errd,adv_dxcc_err, adv_dxcc_erru,move) ; } if (loopcount >= 10000) adv_dxcc = adv_dxc ; // best fit of allocated count for (dayno = 0 ; dayno < maxdayno ; ++dayno) { logvals[dayno] = log(smoothed_alloc[dayno]) ; if (dayno) diff_alloc_1[dayno] = dxvals[dayno] = (smoothed_alloc[dayno] - smoothed_alloc[dayno - 1])/one_day ; } least_squares(&xvals[daystart],&smoothed_alloc[daystart],dayno-daystart-CLIP, &alc_dslope, &alc_dintercept, &alc_avals); least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &alc_eslope, &alc_eintercept, &alc_expvals); least_squares(&xvals[daystart],&dxvals[daystart],dayno-daystart-CLIP, &alc_dxslope, &alc_dxintercept, &alc_dxvals); alc_dxc = smoothed_alloc[maxdayno - 1] - (((alc_dxslope * 0.5) * (pow(last_date,2))) + (alc_dxintercept * last_date)) ; // best fit of IANA data for (dayno = 0 ; dayno < maxdayno ; ++dayno) { logvals[dayno] = log(iana_alloc[dayno]) ; if (dayno) dxvals[dayno] = (smoothed_iana_alloc[dayno] - smoothed_iana_alloc[dayno - 1]) / one_day; } least_squares(&xvals[daystart],&iana_alloc[daystart],dayno-daystart-CLIP, &iana_dslope, &iana_dintercept, &iana_avals); least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &iana_eslope, &iana_eintercept, &iana_expvals); least_squares(&xvals[daystart],&dxvals[daystart],dayno-daystart-CLIP, &iana_dxslope, &iana_dxintercept, &iana_dxvals); iana_dxc = smoothed_iana_alloc[maxdayno - 1] - (((iana_dxslope * 0.5) * (pow(last_date,2))) + (iana_dxintercept * last_date)) ; for (dayno = 0 ; dayno < maxdayno ; ++dayno) { logvals[dayno] = log(smoothed_unadv[dayno]) ; } least_squares(&xvals[daystart],&smoothed_unadv[daystart],dayno-daystart-CLIP, &unadv_dslope, &unadv_dintercept, &unadv_avals); least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &unadv_eslope, &unadv_eintercept, &unadv_expvals); // generate least squares best fit on first order diff of // smoothed_alloc, log(smoothed_alloc) // smoothed_adv, log(smoothed_adv) // smoothed_unadv, log(smoothed_unadv) for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (smoothed_alloc[dayno] - smoothed_alloc[dayno - 1])/one_day ; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_alloc_slope, &d_alloc_intercept, &diff_alloc); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (log(smoothed_alloc[dayno]) - log(smoothed_alloc[dayno - 1]))/one_day; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_log_alloc_slope, &d_log_alloc_intercept, &diff_log_alloc); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (smoothed_adv[dayno] - smoothed_adv[dayno - 1])/one_day ; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_adv_slope, &d_adv_intercept, &diff_adv); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (log(smoothed_adv[dayno]) - log(smoothed_adv[dayno - 1]))/ one_day ; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_log_adv_slope, &d_log_adv_intercept, &diff_log_adv); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (smoothed_unadv[dayno] - smoothed_unadv[dayno - 1])/ one_day ; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_unadv_slope, &d_unadv_intercept, &diff_unadv); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (log(smoothed_unadv[dayno]) - log(smoothed_unadv[dayno - 1]))/ one_day ; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_log_unadv_slope, &d_log_unadv_intercept, &diff_log_unadv); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (log(smoothed_unadv[dayno]) - log(smoothed_unadv[dayno - 1]))/ one_day; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_log_unadv_slope, &d_log_unadv_intercept, &diff_log_unadv); for (dayno = 0 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (smoothed_unadv[dayno] / (float) smoothed_adv[dayno]); least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &adv_ratio_slope, &adv_ratio_intercept, &adv_ratio); for (dayno = 1 ; dayno < maxdayno ; ++dayno) logvals[dayno] = ((smoothed_unadv[dayno] / (float) smoothed_adv[dayno]) - (smoothed_unadv[dayno-1] / (float) smoothed_adv[dayno-1])) / one_day; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &d_adv_ratio_slope, &d_adv_ratio_intercept, &d_adv_ratio); // now look at the per-rir allocation rates // smooth the data (series[dayno].reg_allocs[MINREG+1 - MAXREG-2] // smoothed_tmp1, smoothed_tmp2, -> smoothed_afrinic, _apnic, _arin, _ripencc, _lacnic - smoothed_regs[reg] // generate exponential trend models // write these out in rpt[16] // generate relative daily ratio // write these out in rpt[16] for (reg = MINREG + 1 ; reg < MAXREG - 1 ; ++reg) { smoothed_reg = smoothed_regs[reg] ; smoothed_dreg_dt = smoothed_dregs_dt[reg]; for (dayno = 0 ; dayno < maxdayno ; ++dayno) { logvals[dayno] = log(smoothed_reg[dayno]) ; if (dayno) smoothed_dreg_dt[dayno] = (smoothed_reg[dayno] - smoothed_reg[dayno-1]) / one_day; } least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP,&(reg_slope[reg]),&(reg_intercept[reg]),&(regs[reg])) ; } a_total = 0.0 ; last_date = series[maxdayno - 1].datef ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { smoothed_reg = smoothed_regs[reg] ; a_total += smoothed_reg[maxdayno - 1] ; reg_c[reg] = smoothed_reg[maxdayno - 1] - exp(reg_intercept[reg] + (reg_slope[reg] * last_date)); cur_val[reg] = smoothed_reg[maxdayno - 1] ; } sprintf(fon,"%s/%s",WDIR,rpts[16]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Dayno Year ") ; for (reg = MINREG ; reg < MAXREG - 1; ++reg) { fprintf(fo,"%s_allocs ",regnames[reg]); } for (reg = MINREG + 1 ; reg < MAXREG - 1; ++reg) { fprintf(fo,"%s_allocs_diff ",regnames[reg]); } fprintf(fo,"\n") ; for (dayno = 1 ; dayno < maxdayno ; ++dayno) { // ** 1 - Dayno // ** 2 - Date (yyyy.frac) fprintf(fo,"%d %5.4f ",dayno,series[dayno].datef); // ** 3 - IANA Allocations // ** 4 - AFRINIC Allocations // ** 5 - APNIC Allocations // ** 6 - ARIN Allocations // ** 7 - RIPENCC Allocations // ** 8 - LACNIC Allocations for (reg = MINREG ; reg < MAXREG - 1 ; ++reg) { dsum = (double)(series[dayno].reg_allocs[reg] / (double) SLASH8) ; fprintf(fo," %10.8f",dsum); } // ** 9 - AFRINIC smoothed Allocations // ** 10 - APNIC smoothed Allocations // ** 11 - ARIN smoothed Allocations // ** 12 - RIPENCC smoothed Allocations // ** 13 - LACNIC smoothed Allocations daily_total = 0.0 ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { smoothed_reg = smoothed_regs[reg] ; fprintf(fo," %10.8f",smoothed_reg[dayno]) ; daily_total += smoothed_reg[dayno] - smoothed_reg[dayno - 1] ; } // daily_total is the total allocations across the RIRs for the day // ** 14 - AFRINIC diff smoothed Allocations/dt // ** 15 - APNIC diff smoothed Allocations/dt // ** 16 - ARIN diff smoothed Allocations/dt // ** 17 - RIPENCC diff smoothed Allocations/dt // ** 18 - LACNIC diff smoothed Allocations/dt // ** 19 - RIRs diff smoothed Allocations/dt dtt = 0.0 ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { smoothed_dreg_dt = smoothed_dregs_dt[reg] ; fprintf(fo," %10.8f ",smoothed_dreg_dt[dayno]) ; dtt += smoothed_dreg_dt[dayno]; } fprintf(fo," %10.8f ",dtt) ; // ** 20 - AFRINIC relative allocation rate // ** 21 - APNIC relative allocation rate // ** 22 - ARIN relative allocation rate // ** 23 - RIPENCC relative allocation rate // ** 24 - LACNIC relative allocation rate for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { smoothed_reg = smoothed_regs[reg] ; fprintf(fo," %10.8f",((daily_total > 0.001) ? ((smoothed_reg[dayno] - smoothed_reg[dayno - 1]) / daily_total): 0.0)) ; } // ** 25 - AFRINIC exp trend allocation rate // ** 26 - APNIC exp trend allocation rate // ** 27 - ARIN exp trend allocation rate // ** 28 - RIPENCC exp trend allocation rate // ** 29 - LACNIC exp trend allocation rate // ** 30 - AFRINIC exp trend allocation rate // ** 31 - APNIC exp trend allocation rate // ** 32 - ARIN exp trend allocation rate // ** 33 - RIPENCC exp trend allocation rate // ** 34 - LACNIC exp trend allocation rate if (dayno >= daystart) { daily_total = 0.0 ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { last_val[reg] = exp(reg_intercept[reg] + (reg_slope[reg] * series[dayno].datef)) + reg_c[reg]; fprintf(fo," %10.8f",last_val[reg]); last_val[reg] -= exp(reg_intercept[reg] + (reg_slope[reg] * series[dayno-1].datef)) + reg_c[reg]; daily_total += last_val[reg] ; } for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { fprintf(fo," %10.8f",last_val[reg] / daily_total) ; } } else { for (reg = 0 ; reg < 10 ; ++reg) fprintf(fo," %7.5f ",0.0) ; } fprintf(fo,"\n") ; } dcount = 0 ; a_total = 0 ; loopcount = 0 ; while ((a_total < 256.0) && (loopcount < (50 * 365))){ ++loopcount ; ++dayno ; last_date += one_day ; fprintf(fo,"%d %5.4f ",dayno,last_date); for (reg = 0 ; reg < 22 ; ++reg) fprintf(fo,"%7.5f ",0.0) ; a_total = 0.0 ; daily_total = 0.0 ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { smoothed_reg = smoothed_regs[reg] ; last_val[reg] = cur_val[reg] ; cur_val[reg] = exp(reg_intercept[reg] + (reg_slope[reg] * last_date)) + reg_c[reg]; a_total += cur_val[reg] ; daily_total += cur_val[reg] - last_val[reg] ; fprintf(fo,"%7.5f ",cur_val[reg]) ; } for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) fprintf(fo," %10.8f",(cur_val[reg] - last_val[reg]) / daily_total) ; ++dcount ; fprintf(fo,"\n") ; //printf("%7.5f %7.5f\n",last_date,a_total) ; } fclose(fo) ; dayno = maxdayno - 1 ; dcc = 0 ; last_date = series[dayno].datef ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { rirs_ratio[reg] = (double *)malloc((sizeof *rir_ratio) * dcount) ; cur_val[reg] = exp(reg_intercept[reg] + (reg_slope[reg] * last_date)) + reg_c[reg]; } while (dcc < dcount) { ++dayno ; last_date += one_day ; daily_total = 0.0 ; for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { last_val[reg] = cur_val[reg] ; cur_val[reg] = exp(reg_intercept[reg] + (reg_slope[reg] * last_date)) + reg_c[reg]; daily_total += cur_val[reg] - last_val[reg] ; } for (reg = MINREG + 1; reg < MAXREG - 1 ; ++reg) { rir_ratio = rirs_ratio[reg] ; rir_ratio[dcc] = (cur_val[reg] - last_val[reg]) / daily_total ; } ++dcc ; } sprintf(fon,"%s/%s",WDIR,rpts[7]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Date IANA Assigned Advertised Unadvertised IANA-Smoothed IANA-Linear IANA-Exp IANA-O2 Linear-Alloc Linear-Adv Linear-UnAdv Exp-Alloc Exp-Adv Exp-UnAdv O2-Alloc O2-ADv O2-UnAdv\n") ; // printf("%12.10f %12.10f %12.10f\n",adv_dxslope,adv_dxintercept,adv_dxc) ; // printf("%12.10f %12.10f %12.10f\n",alc_dxslope,alc_dxintercept,alc_dxc) ; // printf("%12.10f %12.10f %12.10f\n",iana_dxslope,iana_dxintercept,iana_dxc) ; for (dayno = 1 ; dayno < maxdayno ; ++dayno) { /* 1 2 3 4 5 */ fprintf(fo,"%5.3f %5.3f %5.3f %5.3f %5.3f",xvals[dayno],((float)(series[dayno].allocs[0] / (double) SLASH8)),smoothed_alloc[dayno],smoothed_adv[dayno],smoothed_unadv[dayno]); if (dayno > daystart ) { last_date = series[dayno].datef ; // IANA Smoothed 6 fprintf(fo," %7.5f",smoothed_iana_alloc[dayno]) ; // IANA-Linear 7 iana_amt = (iana_dintercept + (iana_dslope * last_date)) ; if (iana_amt > 219.914) iana_amt = 0.0 ; fprintf(fo," %7.5f",iana_amt) ; // IANA-Exp 8 iana_amt = (double) (exp(iana_eintercept + (iana_eslope * last_date))); if (iana_amt > 219.914) iana_amt = 0.0 ; fprintf(fo," %7.5f",iana_amt) ; // IANA-O2 9 iana_dxval = (iana_dxslope * 0.5 * last_date * last_date) + (iana_dxintercept * last_date) + iana_dxc ; if (iana_dxval >= 219.914) iana_dxval = 0.0 ; fprintf(fo," %7.5f",iana_dxval) ; //printf("%7.5f %7.5f %7.5f %7.5f %7.5f\n",last_date,smoothed_iana_alloc[dayno],iana_dxval,(smoothed_iana_alloc[dayno] - smoothed_iana_alloc[dayno - 1]),(iana_dxintercept + (iana_dxslope * last_date))) ; // Alloc-Linear 10 if ((alloc_amt = (double) (alc_dintercept + (alc_dslope * last_date))) > 219.914) alloc_amt = 219.914 ; // Adv-Linear (Unadv-Linear) 11 12 if ((adv_amt = (double) (adv_dintercept + (adv_dslope * last_date))) > 219.914) adv_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; // Alloc-Exp 13 if ((alloc_amt = (double) (exp(alc_eintercept + (alc_eslope * last_date)))) < 219.914) { // Adv-Exp (Unadv-Exp) 14 15 adv_amt = (double) (exp(adv_eintercept + (adv_eslope * last_date))); fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else if ((adv_amt = (double) (exp(adv_eintercept + (adv_eslope * last_date)))) < 219.914) { // Adv-Exp (Unadv-Exp) 16 alloc_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else { alloc_amt = 219.914 ; adv_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } // Alloc-O2 if ((alloc_amt = (alc_dxslope * 0.5 * last_date * last_date) + (alc_dxintercept * last_date) + alc_dxc) < 219.914) { // Adv-Exp (Unadv-Exp) adv_amt = (adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else if ((adv_amt = (adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc) < 219.914) { // Adv-Exp (Unadv-Exp) alloc_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else { alloc_amt = 219.914 ; adv_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } } fprintf(fo,"\n") ; } last_date = series[maxdayno - 1].datef ; last_date += 1.0 / 12.0; alloc_amt = smoothed_alloc[maxdayno - 1] ; loopcount = 0 ; while (((adv_amt = (adv_dintercept + (adv_dslope * last_date))) < 219.9136) && (loopcount < (50 * 365))) { ++loopcount ; fprintf(fo,"%8.3f 000.000 000.000 000.000 000.000 000.000",last_date) ; // IANA-Linear iana_amt = (iana_dintercept + (iana_dslope * last_date)) ; if (iana_amt > 219.914) iana_amt = 0 ; fprintf(fo," %7.5f",iana_amt) ; // IANA-Exp iana_amt = (exp(iana_eintercept + (iana_eslope * last_date))); if (iana_amt > 219.914) iana_amt = 0 ; fprintf(fo," %7.5f",iana_amt) ; // IANA-O2 iana_dxval = (iana_dxslope * 0.5 * last_date * last_date) + (iana_dxintercept * last_date) + iana_dxc ; if (iana_dxval >= 219.914) iana_dxval = 0.0 ; fprintf(fo," %7.5f",iana_dxval) ; // Alloc-Linear if ((alloc_amt = (alc_dintercept + (alc_dslope * last_date))) > 219.914) alloc_amt = 219.914 ; // Adv-Linear (Unadv-Linear) if ((adv_amt = (adv_dintercept + (adv_dslope * last_date))) > 219.914) adv_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; if ((alloc_amt = (exp(alc_eintercept + (alc_eslope * last_date)))) < 219.914) { adv_amt = (exp(adv_eintercept + (adv_eslope * last_date))); fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else if ((adv_amt = (exp(adv_eintercept + (adv_eslope * last_date)))) < 219.914) { alloc_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else { alloc_amt = 219.914 ; adv_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } // Alloc-O2 if ((alloc_amt = (alc_dxslope * 0.5 * last_date * last_date) + (alc_dxintercept * last_date) + alc_dxc) < 219.914) { // Adv-Exp (Unadv-Exp) adv_amt = (adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else if ((adv_amt = (adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc) < 219.914) { // Adv-Exp (Unadv-Exp) alloc_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } else { alloc_amt = 219.914 ; adv_amt = 219.914 ; fprintf(fo," %7.5f %7.5f %7.5f",alloc_amt, adv_amt, alloc_amt - adv_amt) ; } fprintf(fo,"\n") ; last_date += 1.0 / 12.0 ; } fclose(fo) ; //printf("%s\n",rpts[10]) ; sprintf(fon,"%s/%s",WDIR,rpts[10]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Dayno RIR-Alloc Smoothed Diff-Smoothed Log-Smoothed Diff-Log-Smoothed Linear Exp best-fit-diff best-fit-diff-log\n") ; for (dayno = 1 ; dayno < maxdayno ; ++dayno) { fprintf(fo,"%7.5f", series[dayno].datef) ; fprintf(fo," %7.5f",(float)(series[dayno].allocs[1]/(double) SLASH8)); fprintf(fo," %7.5f",smoothed_alloc[dayno]); fprintf(fo," %7.5f",diff_alloc_1[dayno]); fprintf(fo," %7.5f",log(smoothed_alloc[dayno])) ; fprintf(fo," %7.5f",((log(smoothed_alloc[dayno]) - log(smoothed_alloc[dayno - 1])) / one_day)) ; if (dayno > daystart) { last_date = series[dayno].datef ; fprintf(fo," %7.5f",(alc_dintercept + (alc_dslope * last_date))); fprintf(fo," %7.5f",(exp(alc_eintercept + (alc_eslope * last_date)))) ; fprintf(fo," %7.5f",(d_alloc_intercept + (d_alloc_slope * last_date))) ; fprintf(fo," %10.8f",(d_log_alloc_intercept + (d_log_alloc_slope * last_date))) ; } fprintf(fo,"\n") ; } fclose(fo) ; /* first order differential data ... ipv4.series.adv.txt */ //printf("%s\n",rpts[11]) ; sprintf(fon,"%s/%s",WDIR,rpts[11]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Dayno ADV Smoothed_1 Smoothed_4 Diff-Smoothed Log-Smoothed Diff-Log-Smoothed Linear Exp best-fit-diff best-fit-diff-log O2-poly\n") ; i = 0 ; for (dayno = 1 ; dayno < maxdayno ; ++dayno) { smoothed_adv_2[dayno] = (smoothed_adv[dayno] - smoothed_adv[dayno - 1])/ one_day ; smoothed_adv_3[dayno] = (log(smoothed_adv[dayno]) - log(smoothed_adv[dayno - 1]))/ one_day; if (series[dayno].adv < 0.01) continue ; if (++i < 5) continue ; fprintf(fo,"%7.5f", series[dayno].datef) ; fprintf(fo," %7.5f",(float)(series[dayno].adv / (double) SLASH8)); fprintf(fo," %7.5f",smoothed_adv_1[dayno]); fprintf(fo," %7.5f",smoothed_adv[dayno]); fprintf(fo," %7.5f",smoothed_adv_2[dayno]) ; fprintf(fo," %7.5f",log(smoothed_adv[dayno])) ; fprintf(fo," %7.5f",smoothed_adv_3[dayno]) ; if ((dayno > daystart) && (dayno < maxdayno - CLIP)) { last_date = series[dayno].datef ; fprintf(fo," %7.5f",(adv_dintercept + (adv_dslope * last_date))); fprintf(fo," %5.3f",(exp(adv_eintercept + (adv_eslope * last_date)))) ; fprintf(fo," %7.5f",(d_adv_intercept + (d_adv_slope * last_date))) ; fprintf(fo," %7.5f",(d_log_adv_intercept + (d_log_adv_slope * last_date))) ; fprintf(fo," %7.5f",((adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxcc)) ; } fprintf(fo,"\n") ; } fclose(fo) ; /* first order differential data ... as.series.unadv.txt */ //printf("%s\n",rpts[12]) ; sprintf(fon,"%s/%s",WDIR,rpts[12]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Dayno UNADV Smoothed Diff-Smoothed Log-Smoothed Diff-Log-Smoothed Linear Exp best-fit-diff best-fit-diff-log\n") ; for (dayno = 1 ; dayno < maxdayno ; ++dayno) { fprintf(fo,"%5.3f", series[dayno].datef) ; fprintf(fo," %5.3f",(float)(series[dayno].unadv/ (double) SLASH8)); fprintf(fo," %5.3f",smoothed_unadv[dayno]); fprintf(fo," %5.3f",smoothed_unadv[dayno] - smoothed_unadv[dayno - 1]) ; fprintf(fo," %7.5f",log(smoothed_unadv[dayno])) ; fprintf(fo," %7.5f",log(smoothed_unadv[dayno]) - log(smoothed_unadv[dayno - 1])) ; if (dayno > daystart) { last_date = series[dayno].datef ; fprintf(fo," %5.3f",(unadv_dintercept + (unadv_dslope * last_date))); fprintf(fo," %5.3f",(exp(unadv_eintercept + (unadv_eslope * last_date)))) ; fprintf(fo," %7.5f",(d_unadv_intercept + (d_unadv_slope * last_date))) ; fprintf(fo," %7.5f",(d_log_unadv_intercept + (d_log_unadv_slope * last_date))) ; } fprintf(fo,"\n") ; } fclose(fo) ; /* first order differential data ... as.series.unaratio.txt */ //printf("%s\n",rpts[13]) ; sprintf(fon,"%s/%s",WDIR,rpts[13]) ; fo = fopen(fon,"w") ; fprintf(fo,"#Dayno UNADVRatio SmoothedRatio DiffSmoothedRatio Linear LinearDiff\n") ; for (dayno = daystart + 1 ; dayno < maxdayno ; ++dayno) { fprintf(fo,"%8.6f", series[dayno].datef) ; fprintf(fo," %8.6f",(series[dayno].unadv / (float) series[dayno].adv)); fprintf(fo," %8.6f",(smoothed_unadv[dayno]/ smoothed_adv[dayno])); fprintf(fo," %8.6f",((smoothed_unadv[dayno]/ smoothed_adv[dayno]) - (smoothed_unadv[dayno-1]/ smoothed_adv[dayno-1]))) ; if (dayno > daystart) { last_date = series[dayno].datef ; fprintf(fo," %8.6f",(adv_ratio_intercept + (adv_ratio_slope * last_date))); fprintf(fo," %8.6f",(d_adv_ratio_intercept + (d_adv_ratio_slope * last_date))) ; } fprintf(fo,"\n") ; } fclose(fo) ; /* model of IPv4 consumption */ //printf("%s/%s\n",WDIR,rpts[14]) ; // model this twice - once stopping at the RIR exhaustion point and then by simulating the draining of the //unadvertised space and then some (say COMPRESS%) of the advertised space at the time of the start of the sprintf(fon,"%s/%s",WDIR,rpts[14]) ; fo = fopen(fon,"w") ; sprintf(fon,"%s/%s",WDIR,rpts[17]) ; fob = fopen(fon,"w") ; fprintf(fo,"#Date IANA_Pool RIR_Alloc Advertised Unadvertised RIR_Pool project arin ripe apnic lacnic afrinic various\n") ; fprintf(fob,"#Date IANA_Pool RIR_Alloc Advertised Unadvertised RIR_Pool project arin ripe apnic lacnic afrinic various\n") ; rirs[0].pool = rirs[1].pool = rirs[2].pool = rirs[3].pool = rirs[4].pool = 0.0; for (dayno = 0 ; dayno < maxdayno ; ++dayno) { if (series[dayno].datef < 1998.0) continue ; // col 1 = date fprintf(fo,"%5.3f ",series[dayno].datef) ; fprintf(fob,"%5.3f ",series[dayno].datef) ; // col 2 = IANA pool size fprintf(fo,"%5.3f ",(float)(series[dayno].pool_sum[0]/ (double) SLASH8)) ; fprintf(fob,"%5.3f ",(float)(series[dayno].pool_sum[0]/ (double) SLASH8)) ; // col 3 = total allocated //fprintf(fo,"%5.3f ",(float)((series[dayno].adv + series[dayno].unadv)/ (double) SLASH8)) ; fprintf(fo,"%5.3f ",(float)(series[dayno].allocs[1] / (double) SLASH8)) ; fprintf(fob,"%5.3f ",(float)(series[dayno].allocs[1] / (double) SLASH8)) ; // col 4 = advertised fprintf(fo,"%5.3f ",(float) (series[dayno].adv/ (double) SLASH8)) ; fprintf(fob,"%5.3f ",(float) (series[dayno].adv/ (double) SLASH8)) ; // col 5 = unadvertised fprintf(fo,"%5.3f ",(float) (series[dayno].unadv / (double) SLASH8)) ; fprintf(fob,"%5.3f ",(float) (series[dayno].unadv / (double) SLASH8)) ; // col 6 = total RIR Pool //fprintf(fo,"%5.3f ",219.914 - ((float) ((series[dayno].pool_sum[0] + series[dayno].allocs[1]) / (double) SLASH8))) ; fprintf(fo,"%5.3f ",(float)(series[dayno].pool[1] / (double) SLASH8)) ; fprintf(fob,"%5.3f ",(float)(series[dayno].pool[1] / (double) SLASH8)) ; fprintf(fo,"%5.3f ",0.0); fprintf(fob,"%5.3f ",0.0); fprintf(fo,"%5.3f %5.3f %5.3f %5.3f %5.3f %5.3f ", (double) (series[dayno].pool[5] / (double) SLASH8), (double) (series[dayno].pool[6] / (double) SLASH8), (double) (series[dayno].pool[4] / (double) SLASH8), (double) (series[dayno].pool[7] / (double) SLASH8), (double) (series[dayno].pool[3] / (double) SLASH8), (double) (series[dayno].pool[8] / (double) SLASH8)); fprintf(fob,"%5.3f %5.3f %5.3f %5.3f %5.3f %5.3f ", (double) (series[dayno].pool[5] / (double) SLASH8), (double) (series[dayno].pool[6] / (double) SLASH8), (double) (series[dayno].pool[4] / (double) SLASH8), (double) (series[dayno].pool[7] / (double) SLASH8), (double) (series[dayno].pool[3] / (double) SLASH8), (double) (series[dayno].pool[8] / (double) SLASH8)); rirs[0].pool = (double) (series[dayno].pool[5] / (double) SLASH8); rirs[1].pool = (double) (series[dayno].pool[6] / (double) SLASH8); rirs[2].pool = (double) (series[dayno].pool[4] / (double) SLASH8); rirs[3].pool = (double) (series[dayno].pool[7] / (double) SLASH8); rirs[4].pool = (double) (series[dayno].pool[3] / (double) SLASH8); rirs[5].pool = (double) (series[dayno].pool[8] / (double) SLASH8); if (dayno > 0) { for (reg = 0 ; reg < 5 ; ++reg) rir_alloc_window[reg][rir_alloc_indx] = (double) ((series[dayno].reg_allocs[reg+3] - series[dayno-1].reg_allocs[reg+3])/ (double) SLASH8) ; rir_alloc_indx = (rir_alloc_indx + 1) % 550 ; } fprintf(fo,"\n") ; fprintf(fob,"\n") ; // printf("Day: %d Allocations: RIR=%u Components=%u Diff = %d\n",dayno,series[dayno].allocs[1], // series[dayno].adv + series[dayno].unadv, // series[dayno].allocs[1] - (series[dayno].adv + series[dayno].unadv)); } dayno = maxdayno - 1 ; spike = 1 ; p_vars[0] = (double) (series[dayno].pool_sum[0] / (double) SLASH8); p_vars[1] = (double) ((series[dayno].adv + series[dayno].unadv) / (double) SLASH8) ; p_vars[2] = (double) (series[dayno].adv / (double) SLASH8) ; p_vars[3] = (double) (series[dayno].unadv / (double) SLASH8) ; p_vars[4] = 219.914 - ((double) ((series[dayno].pool_sum[0] + series[dayno].adv + series[dayno].unadv) / (double) SLASH8)) ; last_date = series[dayno].datef ; last_time = series[dayno].date ; // exponential correction // a_corr = ((double) (series[dayno].adv / (double) SLASH8)) - (exp(adv_eintercept + (adv_eslope * last_date))) ; // quad correction printf("adv_ratio_slope = %5.3f\n",adv_ratio_slope) ; adv_ratio_slope *= ADV_FACTOR ; printf("adv_ratio_slope = %5.3f\n",adv_ratio_slope) ; a_corr = ((double) (series[dayno].adv / (double) SLASH8)) - ((adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc) ; ur_corr = ((double) (series[dayno].unadv / (double) SLASH8)) - (((double)(series[dayno].adv / (double) SLASH8)) * (adv_ratio_intercept + (adv_ratio_slope * last_date))) ; //# p_vars[0] = iana pool size //# p_vars[1] = rir allocated number //# p_vars[2] = advertized count //# p_vars[3] = unadvertised count //# p_vars[4] = rir pool //# relative consumption rates across the RIRs - assume these hold steady // calculate relative consumption speeds across RIRs using linear average consumption rate rir_slope[0] = rir_slope[1] = 0.050 ; rir_slope[6] = 0.050 ; rir_slope[0] += rir_slope[6] ; for (i = 2 ; i < 6 ; ++i) { for (dayno = 0 ; dayno < maxdayno ; ++dayno) logvals[dayno] = (double) (series[dayno].allocs[i+2] / (double) SLASH8) ; least_squares(&xvals[daystart],&logvals[daystart],dayno-daystart-CLIP, &rir_slope[i], &rir_intercept[i], &rir_vals[i]); rir_slope[0] += rir_slope[i]; } // set the parameters for each RIR pool rirs[0].name = "arin" ; rirs[0].threshold = ARIN_THRESH ; rirs[0].rate = rir_slope[3] / rir_slope[0] ; rirs[0].inc = 3 ; rirs[0].empty = 0 ; rirs[1].name = "ripencc" ; rirs[1].threshold = RIPE_THRESH ; rirs[1].rate = rir_slope[4] / rir_slope[0] ; rirs[1].inc = 3 ; rirs[1].empty = 0 ; rirs[2].name = "apnic" ; rirs[2].threshold = APNIC_THRESH ; rirs[2].rate = rir_slope[2] / rir_slope[0] ; rirs[2].inc = 3 ; rirs[2].empty = 0 ; rirs[3].name = "lacnic" ; rirs[3].threshold = LACNIC_THRESH ; rirs[3].rate = rir_slope[5] / rir_slope[0] ; rirs[3].inc = 2 ; rirs[3].empty = 0 ; rirs[4].name = "afrinic" ; rirs[4].threshold = AFRINIC_THRESH ; rirs[4].rate = rir_slope[1] / rir_slope[0] ; rirs[4].inc = 2 ; rirs[4].empty = 0 ; rirs[5].name = "various" ; rirs[5].threshold = 0.0 ; rirs[5].rate = rir_slope[6] / rir_slope[0] ; rirs[5].inc = 0 ; rirs[5].empty = 0 ; //printf("p_vars[4]=%5.3f arin=%5.3f ripe=%5.3f apnic=%5.3f lacnic=%5.3f afrinic=%5.3f various = %5.3f sum = %5.3f Diff = %5.3f\n", // p_vars[4], // rirs[0].pool,rirs[1].pool,rirs[2].pool,rirs[3].pool,rirs[4].pool,rirs[5].pool, // (rirs[0].pool+rirs[1].pool+rirs[2].pool+rirs[3].pool+rirs[4].pool+rirs[5].pool), // p_vars[4] - (rirs[0].pool+rirs[1].pool+rirs[2].pool+rirs[3].pool+rirs[4].pool+rirs[5].pool)); for (dayno = 0 ; dayno <= 366 ; ++dayno) { counts[dayno] = 0 ; variation[dayno] = 0.0 ; } for (dayno = daystart ; dayno < maxdayno ; ++dayno) { double ld ; double model_val ; int yday ; ld = series[dayno].datef ; model_val = (alc_dxslope * 0.5 * ld * ld) + (alc_dxintercept * ld) + alc_dxc ; yday = series[dayno].day_of_year ; ++counts[yday] ; variation[yday] += ((smoothed_alloc[dayno] - model_val) * 100.0)/ model_val; } for (dayno = 0 ; dayno <= 366 ; ++dayno) { if (counts[dayno]) variation[dayno] = variation[dayno]/counts[dayno] ; else variation[dayno] = variation[dayno - 1] ; //printf("%d %3.2f\n",dayno,variation[dayno]) ; } unadv_ok = 1 ; all_ok = 1 ; dcc = 0 ; rirs_empty = 0 ; loopcount = 0 ; while ((!rirs_empty) && (unadv_ok) && (loopcount < (50 * 365))) { ++loopcount ; //while (all_ok && (p_vars[4] > 0.0) && unadv_ok) { // do this 1 day at a time last_date += one_day ; last_time += 86400 ; tp = localtime(&last_time) ; yday = tp->tm_yday ; // use exponential model - p_inc[2] is the advertised space demand for the day using // p_inc[2] = ((exp(adv_eintercept + (adv_eslope * last_date))) + a_corr) - p_vars[2] ; // or one could go linear using // p_inc[2] = ((adv_dintercept + (adv_dslope * last_date)) + a_corr) - p_vars[2] ; // or O(2) using // p_inc[2] = (((adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc)) + a_corr) - p_vars[2] ; if (!rirs_empty) //p_inc[2] = ((exp(adv_eintercept + (adv_eslope * last_date))) + a_corr) - p_vars[2] ; p_inc[2] = (((adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc) + a_corr) - p_vars[2] ; else { //p_inc[2] = (((exp(adv_eintercept + (adv_eslope * last_date))) + a_corr) - //((exp(adv_eintercept + (adv_eslope * (last_date - one_day)))) + a_corr)) // * compress_factor ; p_inc[2] = ((((adv_dxslope * 0.5 * last_date * last_date) + (adv_dxintercept * last_date) + adv_dxc) + a_corr) - (((adv_dxslope * 0.5 * (last_date - one_day) * (last_date - one_day)) + (adv_dxintercept * (last_date - one_day)) + adv_dxc) + a_corr)) * compress_factor ; if (compress_factor > COMPRESSION) compress_factor -= DAILY_COMPRESSION ; } // printf("%5.3f %5.3f\n",last_date,p_vars[2]) ; // p_inc[3] is the growth of the unadvertised space - this is calculated as // a growth value while the RIR pool, p_vars[4], is > 0, otherwise it is considered as a pool // of addresses to be used to fuel further growth. if (!rirs_empty) p_inc[3] = ((p_vars[2] + p_inc[2]) * (adv_ratio_intercept + (adv_ratio_slope * last_date)))+ ur_corr - p_vars[3] ; else p_inc[3] = 0.0 ; // p_inc[1] = total demand from the unallocated pool = the sum of the adv and unadv growth p_inc[1] = p_inc[2] + p_inc[3] ; // ignore that and instead use the RIR total allocation model as the total demand from the unalocated pool alloc_val = ((alc_dxslope * 0.5 * last_date * last_date) + (alc_dxintercept * last_date) + alc_dxc) * ((100.0 + variation[yday])/100.0) ; p_inc[1] = alloc_val - p_vars[1] ; if (p_inc[1] <= 0.0) p_inc[1] = 0.0001 ; if (loopcount == 1) { p_inc_1_offset = p_inc[1] ; } p_inc[1] -= p_inc_1_offset ; //adv_g_ratio = p_inc[2] / (p_inc[2] + p_inc[3]) ; // adv_g_ratio = adv_ratio_intercept + (adv_ratio_slope * last_date) ; //adv_g_ratio = 0.99 ; //p_inc[2] = p_inc[1] * adv_g_ratio ; //p_inc[3] = p_inc[1] - p_inc[2] ; adv_g_ratio = (adv_ratio_intercept + (adv_ratio_slope * last_date)) ; p_inc[2] = ((p_inc[1] + p_vars[1]) / (1.0 + adv_g_ratio)) - p_vars[2] ; if (loopcount == 1) { p_inc_2_offset = p_inc[2] ; } p_inc[2] -= p_inc_2_offset ; p_inc[3] = (p_vars[1] + p_inc[1]) - (p_vars[2] + p_inc[2]) - p_vars[3] ; printf("%d %8.3f ririnc=%3.2f ratio=%3.2f advinc=%3.2f unadvinc=%3.2f",loopcount,last_date,p_inc[1],adv_g_ratio,p_inc[2],p_inc[3]) ; // p_inc[4] = expansion of the unallocated RIR pool p_inc[4] = 0 - p_inc[1] ; // p_inc[0] is the change in the IANA pool p_inc[0] = 0.0 ; // now apply the daily increments to the running totals for (i = 0 ; i < 4 ; ++i) p_vars[i] += p_inc[i] ; printf(" iana=%3.2f rir=%3.2f adv=%3.2f unadv=%3.2f\n",p_vars[0],p_vars[1],p_vars[2],p_vars[3]) ; if (p_vars[2] > poolsize) p_vars[2] = poolsize ; // p_vars[4] is the RIR pool size - the value 219.914 is hard coded here - it should not be hard coded p_vars[4] = rirs_empty ? 0.0 : poolsize - (p_vars[0]+ p_vars[2] + p_vars[3]) ; // calculate relative RIR withdrawal rates rir_ratio = rirs_ratio[5] ; rirs[0].rate = rir_ratio[dcc] ; rir_ratio = rirs_ratio[6] ; rirs[1].rate = rir_ratio[dcc] ; rir_ratio = rirs_ratio[4] ; rirs[2].rate = rir_ratio[dcc] ; rir_ratio = rirs_ratio[7] ; rirs[3].rate = rir_ratio[dcc] ; rir_ratio = rirs_ratio[3] ; rirs[4].rate = rir_ratio[dcc] ; // now record the withdrawals from each RIR in the 18 month window rir_alloc_window[0][rir_alloc_indx] = p_inc[4] * rirs[4].rate * -1.0 ; rir_alloc_window[1][rir_alloc_indx] = p_inc[4] * rirs[2].rate * -1.0 ; rir_alloc_window[2][rir_alloc_indx] = p_inc[4] * rirs[0].rate * -1.0 ; rir_alloc_window[3][rir_alloc_indx] = p_inc[4] * rirs[1].rate * -1.0 ; rir_alloc_window[4][rir_alloc_indx] = p_inc[4] * rirs[3].rate * -1.0 ; // printf("day=%5.3f alloc=%5.3f %5.3f + %5.3f + %5.3f + %5.3f + %5.3f = %5.3f (%5.3f %5.3f %5.3f %5.3f %5.3f=%5.3f) \n",last_date, p_inc[4], // rir_alloc_window[0][rir_alloc_indx], // rir_alloc_window[1][rir_alloc_indx], // rir_alloc_window[2][rir_alloc_indx], // rir_alloc_window[3][rir_alloc_indx], // rir_alloc_window[4][rir_alloc_indx], // rir_alloc_window[1][rir_alloc_indx]+rir_alloc_window[2][rir_alloc_indx]+rir_alloc_window[3][rir_alloc_indx]+rir_alloc_window[4][rir_alloc_indx]+rir_alloc_window[5][rir_alloc_indx], // rirs[4].rate,rirs[2].rate,rirs[0].rate,rirs[1].rate,rirs[3].rate, // rirs[4].rate+rirs[2].rate+rirs[0].rate+rirs[1].rate+rirs[3].rate) ; // update the 18 month windolw pointer (well 550 days to be precise) rir_alloc_indx = (rir_alloc_indx + 1) % 550 ; for (i = 0 ; i < 5 ; ++i) { rir_amt = p_inc[4] * rirs[i].rate ; if (rirs[i].empty) { // just run the model til the last RIR dries up unadv_ok = 0 ; // then substitute a transfer from the unadvertised pool // and stop the show once the unadvertised space is empty //p_vars[1] += rir_amt ; // p_vars[3] += rir_amt ; //if (p_vars[3] < 0.0) // unadv_ok = 0 ; } else { // perform the allocation from the RIR rirs[i].pool += p_inc[4] * rirs[i].rate ; // if this takes the RIR into less than the threshold then replenish the RIR pool if possible if (rirs[i].pool < rirs[i].threshold) { double count ; int inc ; // this RIR needs another allocation // look at last 18 months to see what the size should be reg = i_to_reg[i] ; count = 0.0 ; for (inc = 0 ; inc < 550 ; ++inc) { count += rir_alloc_window[reg][inc] ; // printf("%d %3.5f\n",inc,rir_alloc_window[reg][inc]) ; } inc = count ; ++inc ; // max allocation in this model is MAXIANA /8s if (inc > MAXIANA) inc = MAXIANA ; if (inc < 2) inc = 2 ; rirs[i].inc = inc ; // printf("registry = %d count = %7.5f /8 = %d\n",reg,count,inc) ; // check if IANA can service the allocation request // p_vars[0] is the IANA pool size // rir[i].inc is the request if (p_vars[0] > (rirs[i].inc + (HOLDBACK * RIRS))) { rirs[i].pool += rirs[i].inc ; p_vars[0] -= rirs[i].inc ; p_vars[4] += rirs[i].inc ; } // or take whats left in the iana pool else if (p_vars[0] > (HOLDBACK * RIRS)) { // time to drain the IANA // first do the clawback reserve of 1 x HOLDBACK per RIR - but don't let the RIR use it p_vars[0] -= HOLDBACK * RIRS ; // then pass whats left to this RIR rirs[i].pool += p_vars[0] ; p_vars[4] += p_vars[0] ; p_vars[0] = 0.0 ; } // or see if there is something in the 'various' pool? else if (rirs[5].pool > 0.10) { rirs[i].pool += 1.0 ; rirs[5].pool -= 1.0 ; } } if ((i < 5) && (rirs[i].pool < 0.0)) { rirs[i].pool = 0.0; rirs[i].empty = 1 ; all_ok = 0 ; } } } if (!rirs_empty) { rirs_empty = (rirs[0].empty +rirs[1].empty +rirs[2].empty +rirs[3].empty +rirs[4].empty == 5); rirs_empty = (rirs[0].empty +rirs[1].empty +rirs[2].empty +rirs[3].empty +rirs[4].empty); } // correct the RIR pool size back to zero if negative if (p_vars[4] < 0.0) p_vars[4] = 0.0 ; if (rirs_empty) p_vars[4] = 0.0 ; // now print out the picture if (all_ok) fprintf(fo,"%5.3f ",last_date) ; fprintf(fob,"%5.3f ",last_date) ; //printf("%5.3f ",last_date) ; for (i = 0 ; i < 5 ; ++i) { if (all_ok) fprintf(fo,"%5.3f ",p_vars[i]) ; fprintf(fob,"%5.3f ",p_vars[i]) ; //printf("%5.3f ",p_vars[i]) ; } if (spike) { spikeval = p_vars[0] + p_vars[2] + p_vars[3] + p_vars[4] ; spike = 0 ; } else spikeval = 0.0 ; if (all_ok) fprintf(fo,"%5.3f ",spikeval) ; fprintf(fob,"%5.3f ",spikeval) ; //printf("%5.3f ",spikeval) ; for (i = 0 ; i <= 5 ; ++i) { if (all_ok) fprintf(fo,"%5.3f ",rirs[i].pool); fprintf(fob,"%5.3f ",rirs[i].pool); //printf("%d=%5.3f ",i,rirs[i].pool); } if (all_ok) fprintf(fo,"\n") ; fprintf(fob,"\n") ; //printf("\n") ; //printf("p_vars[4]=%5.3f arin=%5.3f ripe=%5.3f apnic=%5.3f lacnic=%5.3f afrinic=%5.3f various = %5.3f sum = %5.3f Diff = %5.3f\n", // p_vars[4], // rirs[0].pool,rirs[1].pool,rirs[2].pool,rirs[3].pool,rirs[4].pool,rirs[5].pool, // (rirs[0].pool+rirs[1].pool+rirs[2].pool+rirs[3].pool+rirs[4].pool+rirs[5].pool), // p_vars[4] - (rirs[0].pool+rirs[1].pool+rirs[2].pool+rirs[3].pool+rirs[4].pool+rirs[5].pool)); if (dcc < dcount - 1) ++dcc ; if (++projected_day_count > (365 * 20)) unadv_ok = 0 ; } fclose(fo); fclose(fob) ; } /*----------------------------*/ void alloc(int from, int to, int date, int count, int rir) { struct sequence *tmpa, *tmpb ; //printf("ALLOC: %d %d %d %d %d\n",from,to,date,count,rir); // process the from resource as an "out" tmpa = 0 ; tmpb = regseq[from] ; if ((from == VARIOUS) && (print_flag)) { printf("from=%d, to = %d, date = %d, count = %d\n",from,to,date,count) ; } // position the insertion point between > tmpa and <= tmpb while (tmpb && (date > tmpb->date)) { tmpa = tmpb ; tmpb = tmpb->nxt ; } if (tmpb && (tmpb->date == date)) { // additional outgoing on the same date tmpb->out += count; } else if (tmpa && (tmpa->date == date)) { // additional outgoing on the same date tmpa->out += count; } else if (!tmpa) { // new list head tmpa = (struct sequence *) malloc(sizeof *tmpa) ; regseq[from] = tmpa ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = count ; tmpa->in = 0 ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } else { // insert into list between tmpa and tmpb tmpa->nxt = (struct sequence *) malloc(sizeof *tmpa) ; tmpa = tmpa->nxt ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = count ; tmpa->in = 0 ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } if (to == ASSIGNED) { // this is actually a booking from an RIR pool to assigned - so also record the // transaction against the common RIR entry from = RIR ; // process the from resource as an "out" tmpa = 0 ; tmpb = regseq[from] ; // position the insertion point between > tmpa and <= tmpb while (tmpb && (tmpb->date < date)) { tmpa = tmpb ; tmpb = tmpb->nxt ; } if (tmpb && (tmpb->date == date)) { // additional outgoing on the same date tmpb->out += count; } else if (tmpa && (tmpa->date == date)) { // additional outgoing on the same date tmpa->out += count; } else if (!tmpa) { // new list head tmpa = (struct sequence *) malloc(sizeof *tmpa) ; regseq[from] = tmpa ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = count ; tmpa->in = 0 ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } else { // insert into list between tmpa and tmpb tmpa->nxt = (struct sequence *) malloc(sizeof *tmpa) ; tmpa = tmpa->nxt ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = count ; tmpa->in = 0 ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } // now process this as an "out' from the actual allocation registry // (as distinct from the registry to which IANA allocated the /8) // record this in the "reg_alloc" data structure from = rir ; // process the 'from' resource as an "out" from the RIR (no corresponding "in" tmpa = 0 ; tmpb = reg_alloc[from] ; // position the insertion point between > tmpa and <= tmpb while (tmpb && (tmpb->date < date)) { tmpa = tmpb ; tmpb = tmpb->nxt ; } if (tmpb && (tmpb->date == date)) { // additional outgoing on the same date tmpb->out += count; } else if (tmpa && (tmpa->date == date)) { // additional outgoing on the same date tmpa->out += count; } else if (!tmpa) { // new list head tmpa = (struct sequence *) malloc(sizeof *tmpa) ; reg_alloc[from] = tmpa ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = count ; tmpa->in = 0 ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } else { // insert into list between tmpa and tmpb tmpa->nxt = (struct sequence *) malloc(sizeof *tmpa) ; tmpa = tmpa->nxt ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = count ; tmpa->in = 0 ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } } // now process the destination "to" point tmpa = 0 ; tmpb = regseq[to] ; // position the insertion point between > tmpa and <= tmpb while (tmpb && (tmpb->date < date)) { tmpa = tmpb ; tmpb = tmpb->nxt ; } if (tmpb && (tmpb->date == date)) { // additional outgoing on the same date tmpb->in += count; } else if (tmpa && (tmpa->date == date)) { // additional outgoing on the same date tmpa->in += count; } else if (!tmpa) { // new list head tmpa = (struct sequence *) malloc(sizeof *tmpa) ; regseq[to] = tmpa ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = 0 ; tmpa->in = count ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } else { // insert into list between tmpa and tmpb tmpa->nxt = (struct sequence *) malloc(sizeof *tmpa) ; tmpa = tmpa->nxt ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = 0 ; tmpa->in = count ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } if (from == IANA) { // then this is an IANA -> RIR transaction to = RIR ; // now process the destination "to" point tmpa = 0 ; tmpb = regseq[to] ; // position the insertion point between > tmpa and <= tmpb while (tmpb && (tmpb->date < date)) { tmpa = tmpb ; tmpb = tmpb->nxt ; } if (tmpb && (tmpb->date == date)) { // additional outgoing on the same date tmpb->in += count; } else if (tmpa && (tmpa->date == date)) { // additional outgoing on the same date tmpa->in += count; } else if (!tmpa) { // new list head tmpa = (struct sequence *) malloc(sizeof *tmpa) ; regseq[to] = tmpa ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = 0 ; tmpa->in = count ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } else { // insert into list between tmpa and tmpb tmpa->nxt = (struct sequence *) malloc(sizeof *tmpa) ; tmpa = tmpa->nxt ; tmpa->nxt = tmpb ; tmpa->date = date ; tmpa->out = 0 ; tmpa->in = count ; tmpa->trans = 0 ; tmpa->sum = 0 ; tmpa->pool = 0 ; tmpa->psum = 0 ; } } } init_list() { struct add_list *ap ; struct address *app ; int e,i ; ipv4 = (struct slash8 *)malloc((sizeof *ipv4) * 256) ; pools[IANA] = 4294967295UL ; for (e = 0 ; e < 256 ; ++e) { for (i = 0 ; i < MAXPOOLS ; ++i) ipv4[e].pools[i] = 0 ; ipv4[e].pools[IANA] = (1 << 24) ; ipv4[e].addrs = ap = (struct add_list *) malloc(sizeof *ap) ; ap->nxt = ap->prv = 0 ; ap->addr = app = (struct address *) malloc(sizeof *app) ; app->start = e << 24 ; app->count = (1 << 24) ; app->registry = IANA ; app->status = IANA ; app->iana_date = 19830101 ; app->rir_date = 0 ; } } clear_list() { struct add_list *ap, *t; int e; for (e = 0 ; e < 256 ; ++e) { t = ap = ipv4[e].addrs ; while (t) { ap = ap->nxt ; free(t->addr) ; free(t) ; t = ap ; } } free(ipv4) ; } /******************************************************** * add_entry * */ add_entry(unsigned int address,int count,int registry,int date,int status) { int q[4], mask , error, mc; struct slash8 *e ; struct add_list *ep, *tmpa ; struct address *epp, *tmpb ; q[0] = (address >> 24) & 255 ; q[1] = (address >> 16) & 255 ; q[2] = (address >> 8) & 255 ; q[3] = address & 255 ; e = &(ipv4[q[0]]) ; ep = e->addrs ; // now head along the list until we find either // - an exact match // - an enclosing block // - a sub-block while ((ep->addr->start < address) && ((ep->addr->start + (ep->addr->count - 1)) < address)) ep = ep->nxt ; // at the start // first carve off any front piece epp = ep->addr ; if (epp->start < address) { tmpb = (struct address *) malloc(sizeof *tmpb) ; tmpb->start = epp->start ; tmpb->count = address - epp->start ; tmpb->registry = epp->registry; tmpb->alloc_registry = epp->alloc_registry; tmpb->status = epp->status; tmpb->iana_date = epp->iana_date ; tmpb->rir_date = epp->rir_date ; tmpa = (struct add_list *) malloc(sizeof *tmpa) ; tmpa->addr = tmpb ; tmpa->nxt = ep ; tmpa->prv = ep->prv ; if (ep->prv) ep->prv->nxt = tmpa ; else e->addrs = tmpa ; ep->prv = tmpa ; epp->start = address; epp->count -= tmpb->count ; } // epp is now the start point // loop through sucessive blocks until all done while (count > 0) { // first check to see if there is any end remanent and lop it off epp = ep->addr ; if (epp->count > count) { tmpb = (struct address *) malloc(sizeof *tmpb) ; tmpb->start = epp->start + count; tmpb->count = epp->count - count ; tmpb->registry = epp->registry; tmpb->alloc_registry = epp->alloc_registry; tmpb->status = epp->status; tmpb->iana_date = epp->iana_date ; tmpb->rir_date = epp->rir_date ; tmpa = (struct add_list *) malloc(sizeof *tmpa) ; tmpa->addr = tmpb ; tmpa->nxt = ep->nxt ; tmpa->prv = ep ; if (ep->nxt) ep->nxt->prv = tmpa ; ep->nxt = tmpa ; epp->count -= tmpb->count ; } // now check the blocks's transition // allowable transitions: // - IANA to IETF // - IANA to RIR // - RIR to ASSIGNED // - ASSIGNED to ADVERTISED error = 0 ; if (epp->status == IANA) { if ((status != IETF) && (status != RIR)) { //printf("Error From %d to %d\n",epp->status,status) ; error = 1 ; } } else if (epp->status == RIR) { if (status != ASSIGNED) { //printf("Error From %d to %d\n",epp->status,status) ; error = 1 ; } } else if (epp->status == ASSIGNED) { if (status != ADVERTISED) { //printf("Error From %d to %d\n",epp->status,status) ; error = 1 ; } } else if (epp->status == ADVERTISED) { // printf("Error From %d to %d\n",epp->status,status) ; error = 1 ; } if (!error) { if (status == RIR) { // then this is an IANA allocation to the RIR, and the RIR registry is recorded // as the app->registry epp->registry = registry ; epp->iana_date = date ; epp->status = status ; e->pools[RIR] += epp->count ; e->pools[registry] += epp->count ; e->pools[0] -= epp->count ; pools[RIR] += epp->count ; pools[registry] += epp->count ; pools[IANA] -= epp->count ; //if ((date < 19800000) || (date > 20051100)) { // mask = 32 ; // mc = 1 ; // while (mc < count) { mc *= 2 ; --mask ; } // printf("Add: %d.%d.%d.%d/%d %d %d s=%s r=%s\n",q[0],q[1],q[2],q[3],mask,count,date,regnames[status],regs[registry]) ; // } alloc(IANA,registry,date,epp->count,0) ; } else if (status == IETF) { // this is an IETF address reservation epp->registry = IETF ; epp->iana_date = date ; epp->status = status ; e->pools[IETF] += epp->count ; e->pools[0] -= epp->count ; pools[IETF] += epp->count ; pools[IANA] -= epp->count ; } else if (status == ASSIGNED) { // this is an RIR assignment record // the assigned_pools[epp->registry] value is if (epp->registry != IETF) { if (date < epp->iana_date) date = epp->iana_date ; epp->rir_date = date ; epp->status = status ; // record which registry made the allocation epp->alloc_registry = registry; e->pools[RIR] -= epp->count ; e->pools[ASSIGNED] += epp->count ; pools[RIR] -= epp->count ; pools[ASSIGNED] += epp->count ; assigned_pools[epp->registry] += epp->count ; pools[epp->registry] -= epp->count ; //if ((date < 19800000) || (date > 20051100)) { // mask = 32 ; // mc = 1 ; // while (mc < count) { mc *= 2 ; --mask ; } // printf("Add: %d.%d.%d.%d/%d %d %d s=%s r=%s ar=%s\n",q[0],q[1],q[2],q[3],mask,count,date,regnames[status],regs[registry],regs[epp->registry]) ; // } alloc(epp->registry,ASSIGNED,date,epp->count,registry) ; } } else if (status == ADVERTISED) { if (epp->registry != IETF) { epp->status = status ; e->pools[ASSIGNED] -= epp->count ; e->pools[ADVERTISED] += epp->count ; pools[ASSIGNED] -= epp->count ; pools[ADVERTISED] += epp->count ; advertised_pools[epp->registry] += epp->count ; assigned_pools[epp->registry] -= epp->count ; } } } count -= epp->count ; if (count < 0) count = 0 ; else if (count > 0) ep = ep->nxt ; } } /******************************************************** * cvtime * * convert a value of the form yyyymmdd to year.fraction * assume 366 days per year in generating the fraction */ double cvtime(int date) { int year, month, day ; struct tm tmd, *tp ; double retval ; time_t tv ; year = date / 10000 ; month = (date / 100) % 100 ; day = date % 100 ; tmd.tm_sec = 0 ; tmd.tm_min = 0 ; tmd.tm_hour = 0 ; tmd.tm_mday = day ; tmd.tm_mon = month - 1 ; tmd.tm_year = year - 1900 ; tmd.tm_wday = 0 ; tmd.tm_yday = 0 ; tmd.tm_isdst = 0 ; tv = mktime(&tmd) ; tp = localtime(&tv) ; retval = 1900 + tp->tm_year + (tp->tm_yday / 366.0) ; return(retval) ; }