Changeset 6c8579e


Ignore:
Timestamp:
11/12/18 17:30:59 (2 years ago)
Author:
Jacob Van Walraven <jcv9@…>
Branches:
develop
Children:
3d01ef7
Parents:
ccb2507
Message:

Added more statistics

File:
1 edited

Legend:

Unmodified
Added
Removed
  • examples/tutorial/ipdist-parallel.c

    r4d5e6b3 r6c8579e  
    1313        uint64_t src[4][256];
    1414        uint64_t dst[4][256];
    15         /* Maintains a running average over. Only used within the tally */
     15        /* Holds the results from the previous output */
    1616        uint64_t src_lastoutput[4][256];
    1717        uint64_t dst_lastoutput[4][256];
     
    2121        uint64_t packets;
    2222        uint64_t output_count;
     23        /* Pointer to stats structure */
     24        struct addr_stats *stats;
     25
     26};
     27struct addr_stats {
     28        /* Holds the percentage change compared to the previous output */
     29        float src[4][256];
     30        float dst[4][256];
     31        struct addr_rank *rank_src[4];
     32        struct addr_rank *rank_dst[4];
     33};
     34struct addr_rank {
     35        uint8_t addr;
     36        /* count is the priority */
     37        uint64_t count;
     38        /* pointer to next ranking item */
     39        struct addr_rank* next;
    2340};
    2441
     
    3653/* interval between outputs in seconds */
    3754uint64_t tickrate;
     55
     56char *stats_outputdir = "/home/jcv9/output/";
     57/* Calculate and plot the percentage change from the previous plot */
     58int stats_percentage_change = 1;
     59int stats_ranking = 1;
     60
     61
     62/*************************************************************************
     63Priority queue linked list */
     64
     65static struct addr_rank *rank_new(uint8_t addr, uint64_t count) {
     66        struct addr_rank *tmp = malloc(sizeof(struct addr_rank));
     67        tmp->addr = addr;
     68        tmp->count = count;
     69        tmp->next = NULL;
     70
     71        return tmp;
     72}
     73static uint8_t peak(struct addr_rank **head) {
     74        return (*head)->addr;
     75}
     76static void pop(struct addr_rank **head) {
     77        struct addr_rank* tmp = *head;
     78        (*head) = (*head)->next;
     79        free(tmp);
     80}
     81static void push(struct addr_rank **head, uint8_t addr, uint64_t count) {
     82        struct addr_rank *curr = (*head);
     83        struct addr_rank *tmp = rank_new(addr, count);
     84
     85        /* Check if the new node has a greater priority than the head */
     86        if((*head)->count < count) {
     87                tmp->next = *head;
     88                (*head) = tmp;
     89        } else {
     90                /* Jump through the list until we find the correct position */
     91                while (curr->next != NULL && curr->next->count > count) {
     92                        curr = curr->next;
     93                }
     94
     95                tmp->next = curr->next;
     96                curr->next = tmp;
     97        }
     98}
     99/*************************************************************************/
     100
     101
     102static void compute_stats(struct addr_local *tally) {
     103        int i, j;
     104
     105        /* Calculates the percentage change from the last output. NEED TO MAKE THIS WEIGHTED */
     106        if(stats_percentage_change) {
     107                for(i=0;i<256;i++) {
     108                        for(j=0;j<4;j++) {
     109                                tally->stats->src[j][i] = 0;
     110                                tally->stats->dst[j][i] = 0;
     111                                if(tally->src[j][i] != 0) {
     112                                        tally->stats->src[j][i] = (((float)tally->src[j][i] - (float)tally->src_lastoutput[j][i]) / (float)tally->src[j][i]) * 100;
     113                                }
     114                                if(tally->dst[j][i] != 0) {
     115                                        tally->stats->dst[j][i] = (((float)tally->dst[j][i] - (float)tally->dst_lastoutput[j][i]) / (float)tally->dst[j][i]) * 100;
     116                                }
     117                        }
     118                }
     119        }
     120
     121        /* RANKING SYSTEM */
     122        if(stats_ranking) {
     123                for(i=0;i<4;i++) {
     124                        tally->stats->rank_src[i] = rank_new(0, tally->src[i][0]);
     125                        tally->stats->rank_dst[i] = rank_new(0, tally->dst[i][0]);
     126
     127                        for(j=1;j<256;j++) {
     128                                /* Push everything into the priority queue
     129                                 * each item will be popped off in the correct order */
     130                                push(&tally->stats->rank_src[i], j, tally->src[i][j]);
     131                                push(&tally->stats->rank_dst[i], j, tally->dst[i][j]);
     132                        }
     133                }
     134        }
     135}
    38136
    39137static void per_tick(libtrace_t *trace, libtrace_thread_t *thread, void *global, void *tls, uint64_t tick) {
     
    219317        /* Create tally structure */
    220318        struct addr_local *tally = (struct addr_local *)malloc(sizeof(struct addr_local));
     319        tally->stats = malloc(sizeof(struct addr_stats));
    221320
    222321        /* Initialize the tally structure */
     
    228327                        tally->src_lastoutput[i][j] = 0;
    229328                        tally->dst_lastoutput[i][j] = 0;
     329                        tally->stats->src[i][j] = 0;
     330                        tally->stats->dst[i][j] = 0;
    230331                }
    231332        }
     
    239340static void plot_results(struct addr_local *tally, uint64_t tick) {
    240341
     342        /* Calculations before reporting the results */
     343        /* Need to initialise lastoutput values on first pass,
     344         * this is so we have a base line for percentage changed */
     345        if(tally->output_count == 0) {
     346                for(i=0;i<4;i++) {
     347                        for(j=0;j<256;j++) {
     348                                tally->src_lastoutput[i][j] = tally->src[i][j];
     349                                tally->dst_lastoutput[i][j] = tally->dst[i][j];
     350                        }
     351                }
     352         }
     353        /* Compute the stats */
     354        compute_stats(tally);
     355
     356        /* Finaly output the results */
     357        printf("Generating output \"%sipdist-%u\"\n", stats_outputdir, tick);
     358
     359        /* Output the results */
    241360        char outputfile[255];
    242         char outputplot[255];
    243         snprintf(outputfile, sizeof(outputfile), "ipdist-%u.data", tick);
    244         snprintf(outputplot, sizeof(outputplot), "ipdist-%u.png", tick);
    245 
    246         /* Push all data into data file */
     361        snprintf(outputfile, sizeof(outputfile), "%sipdist-%u.data", stats_outputdir, tick);
    247362        FILE *tmp = fopen(outputfile, "w");
    248363        int i, j;
    249         fprintf(tmp, "#Hits\t\t\t\t\t\t\t\t\tPercentage Change\n");
    250         fprintf(tmp, "#num\toctet1\t\toctet2\t\toctet3\t\toctet4\t\toctet1\t\toctet2\t\toctet3\t\toctet4\n");
    251         fprintf(tmp, "#\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst\n");
     364        fprintf(tmp, "#\tHits");
     365        if(stats_percentage_change) {
     366                fprintf(tmp, "\t\t\t\t\t\t\t\tPercentage");
     367        }
     368        if(stats_ranking) {
     369                fprintf(tmp, "\t\t\t\t\t\t\t\tRanking");
     370        }
     371        fprintf(tmp, "\n");
     372        fprintf(tmp, "#num\toctet1\t\toctet2\t\toctet3\t\toctet4");
     373        if(stats_percentage_change) {
     374                fprintf(tmp, "\t\toctet1\t\toctet2\t\toctet3\t\toctet4");
     375        }
     376        if(stats_ranking) {
     377                fprintf(tmp, "\t\toctet1\t\toctet2\t\toctet3\t\toctet4");
     378        }
     379        fprintf(tmp, "\n");
     380        fprintf(tmp, "#\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst");
     381        if(stats_percentage_change) {
     382                fprintf(tmp, "\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst");
     383        }
     384        if(stats_ranking) {
     385                fprintf(tmp, "\tsrc\tdst\tsrc\tdst\tsrc\tdst\tsrc\tdst");
     386        }
     387        fprintf(tmp, "\n");
    252388        for(i=0;i<256;i++) {
    253389                fprintf(tmp, "%d", i);
     
    255391                        fprintf(tmp, "\t%d\t%d", tally->src[j][i], tally->dst[j][i]);
    256392                }
    257 
    258                 /* Calculates the percentage change from the last output */
    259                 for(j=0;j<4;j++) {
    260                         float src_inc = 0;
    261                         float dst_inc = 0;
    262                         if(tally->src[j][i] != 0) {
    263                                 src_inc = (((float)tally->src[j][i] - (float)tally->src_lastoutput[j][i]) / (float)tally->src[j][i]) * 100;
     393                if(stats_percentage_change) {
     394                        for(j=0;j<4;j++) {
     395                                fprintf(tmp, "\t%.0f\t%.0f", tally->stats->src[j][i], tally->stats->dst[j][i]);
    264396                        }
    265                         if(tally->dst[j][i] != 0) {
    266                                 dst_inc = (((float)tally->dst[j][i] - (float)tally->dst_lastoutput[j][i]) / (float)tally->dst[j][i]) * 100;
     397                }
     398                if(stats_ranking) {
     399                        for(j=0;j<4;j++) {
     400                                /* Get the highest ranking to lowest ranking octets */
     401                                fprintf(tmp, "\t%d", peak(&tally->stats->rank_src[j]));
     402                                fprintf(tmp, "\t%d", peak(&tally->stats->rank_dst[j]));
     403                                pop(&tally->stats->rank_src[j]);
     404                                pop(&tally->stats->rank_dst[j]);
    267405                        }
    268                         fprintf(tmp, "\t%.0f\t%.0f", src_inc, dst_inc);
    269                 }
    270 
     406                }
    271407                fprintf(tmp, "\n");
    272408        }
    273409        fclose(tmp);
    274         printf("Ouput data file %s and plot %s\n", outputfile, outputplot);
    275 
    276         /* Open pipe to gnuplot */
    277         FILE *gnuplot = popen("gnuplot -persistent", "w");
    278         /* send all commands to gnuplot */
    279         fprintf(gnuplot, "set term png size 1280,960 \n");
    280         fprintf(gnuplot, "set title 'IP Distribution'\n");
    281         fprintf(gnuplot, "set xrange[0:255]\n");
    282         fprintf(gnuplot, "set xlabel 'Prefix'\n");
    283         fprintf(gnuplot, "set ylabel 'Hits'\n");
    284         fprintf(gnuplot, "set y2label 'Percentage Change'\n");
    285         fprintf(gnuplot, "set xtics 0,10,255\n");
    286         fprintf(gnuplot, "set y2range[-100:100]\n");
    287         //fprintf(gnuplot, "set ytics nomirror\n");
    288         //fprintf(gnuplot, "set y2tics\n");
    289         //fprintf(gnuplot, "set tics out\n");
    290         fprintf(gnuplot, "set output '%s'\n", outputplot);
    291         fprintf(gnuplot, "plot '%s' using 1:2 title 'Source octet 1' axes x1y1 with boxes,", outputfile);
    292         fprintf(gnuplot, "'%s' using 1:3 title 'Destination octet 1' axes x1y1 with boxes,", outputfile);
    293         //fprintf(gnuplot, "'%s' using 1:4 title 'Source octet 2' axes x1y1 with boxes,", outputfile);
    294         //fprintf(gnuplot, "'%s' using 1:5 title 'Destination octet 2' axes x1y1 with boxes,", outputfile);
    295         //fprintf(gnuplot, "'%s' using 1:6 title 'Source octet 3' axes x1y1 with boxes,", outputfile);
    296         //fprintf(gnuplot, "'%s' using 1:7 title 'Destination octet 3' axes x1y1 with boxes,", outputfile);
    297         //fprintf(gnuplot, "'%s' using 1:8 title 'Source octet 4' axes x1y1 with boxes,", outputfile);
    298         //fprintf(gnuplot, "'%s' using 1:9 title 'Destination octet 4' axes x1y1 with boxes,", outputfile);
    299         fprintf(gnuplot, "'%s' using 1:10 title 'Octet 1 source change' axes x1y2 with lines,", outputfile);
    300         fprintf(gnuplot, "'%s' using 1:11 title 'Octet 1 destination change' axes x1y2 with lines\n", outputfile);
    301         //fprintf(gnuplot, "'%s' using 1:12 title 'Octet 2 source change' axes x1y2 with lines,", outputfile);
    302         //fprintf(gnuplot, "'%s' using 1:13 title 'Octet 2 destination change' axes x1y2 with lines,", outputfile);
    303         //fprintf(gnuplot, "'%s' using 1:14 title 'Octet 3 source change' axes x1y2 with lines,", outputfile);
    304         //fprintf(gnuplot, "'%s' using 1:15 title 'Octet 3 destination change' axes x1y2 with lines,", outputfile);
    305         //fprintf(gnuplot, "'%s' using 1:16 title 'Octet 4 source change' axes x1y2 with lines,", outputfile);
    306         //fprintf(gnuplot, "'%s' using 1:17 title 'Octet 4 destination change' axes x1y2 with lines\n", outputfile);
    307         fprintf(gnuplot, "replot");
    308         pclose(gnuplot);
     410
     411        if(stats_ranking) {
     412                for(i=0;i<4;i++) {
     413                        free(tally->stats->rank_src[i]);
     414                        free(tally->stats->rank_dst[i]);
     415                }
     416        }
     417
     418        /* Plot the results */
     419        for(i=0;i<4;i++) {
     420                char outputplot[255];
     421                snprintf(outputplot, sizeof(outputplot), "%sipdist-%u-octet%d.png", stats_outputdir, tick, i+1);
     422
     423                /* Open pipe to gnuplot */
     424                FILE *gnuplot = popen("gnuplot -persistent", "w");
     425                /* send all commands to gnuplot */
     426                fprintf(gnuplot, "set term png size 1280,960 \n");
     427                fprintf(gnuplot, "set title 'IP Distribution - Octet %d'\n", i+1);
     428                fprintf(gnuplot, "set xrange[0:255]\n");
     429                fprintf(gnuplot, "set xlabel 'Prefix'\n");
     430                fprintf(gnuplot, "set ylabel 'Hits'\n");
     431                fprintf(gnuplot, "set xtics 0,10,255\n");
     432                fprintf(gnuplot, "set output '%s'\n", outputplot);
     433                if(stats_percentage_change) {
     434                        fprintf(gnuplot, "set y2label 'Percentage Change'\n");
     435                        fprintf(gnuplot, "set y2range[-100:100]\n");
     436                        fprintf(gnuplot, "set ytics nomirror\n");
     437                        fprintf(gnuplot, "plot '%s' using 1:%d title 'Source octet %d' axes x1y1 with boxes,", outputfile, i+2, i+1);
     438                        fprintf(gnuplot, "'%s' using 1:%d title 'Destination octet %d' axes x1y1 with boxes,", outputfile, i+3, i+1);
     439                        fprintf(gnuplot, "'%s' using 1:%d title 'Octet %d source change' axes x1y2 with lines,", outputfile, i+10, i+1);
     440                        fprintf(gnuplot, "'%s' using 1:%d title 'Octet %d destination change' axes x1y2 with lines\n", outputfile, i+11, i+1);
     441                } else {
     442                        fprintf(gnuplot, "plot '%s' using 1:%d title 'Source octet %d' axes x1y1 with boxes,", outputfile, i+2, i+1);
     443                        fprintf(gnuplot, "'%s' using 1:%d title 'Destination octet %d' axes x1y1 with boxes\n", outputfile, i+3, i+1);
     444                }
     445                fprintf(gnuplot, "replot");
     446                pclose(gnuplot);
     447        }
    309448}
    310449
     
    348487                /* update last key */
    349488                tally->lastkey = key;
    350 
    351                 /* Need to initialise lastoutput values on first pass */
    352                 if(tally->output_count == 0) {
    353                         for(i=0;i<4;i++) {
    354                                 for(j=0;j<256;j++) {
    355                                         tally->src_lastoutput[i][j] = tally->src[i][j];
    356                                         tally->dst_lastoutput[i][j] = tally->dst[i][j];
    357                                 }
    358                         }
    359                 }
    360489
    361490                /* Plot the result with the key in epoch seconds*/
     
    375504                }
    376505                tally->packets = 0;
     506
    377507        }
    378508
     
    389519        /* If there is any remaining data in the tally plot it */
    390520        if(tally->packets > 0) {
     521                /* Then plot the results */
    391522                plot_results(tally, (tally->lastkey >> 32) + 1);
    392523        }
Note: See TracChangeset for help on using the changeset viewer.