diff --git a/src/capdiff.c b/src/capdiff.c index 684841d..a2e1cc9 100644 --- a/src/capdiff.c +++ b/src/capdiff.c @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include "cap_utils.h" #include "packet.h" @@ -24,7 +27,36 @@ struct pkt_reconstruct { int diff_1; }; -void reconstruct_action(struct cap_file cf[], struct pkt_reconstruct* pr) { +struct pkt_stats { + gint port; + uint64_t count; + double cumulated_size; +}; + +void destroy_pkt_stats(gpointer data) { + struct pkt_stats* ps = data; + free(ps); +} + +void update_stats(struct buffer_packet *bp, GHashTable* stat_elem) { + gint port = bp->ip.ap.fmt.content.clear.port; + struct pkt_stats *ps = g_hash_table_lookup(stat_elem, &port); + if (ps == NULL) { + ps = malloc(sizeof(struct pkt_stats)); + if (ps == NULL) { + perror("Unable to alloc pkt_stats"); + exit(EXIT_FAILURE); + } + ps->port = port; + ps->count = 0; + ps->cumulated_size = 0; + g_hash_table_insert (stat_elem, &ps->port, ps); + } + ps->count++; + ps->cumulated_size += bp->ip.ap.fmt.headers.size; +} + +void reconstruct_action(struct cap_file cf[], struct pkt_reconstruct* pr, GHashTable *stats[]) { struct buffer_packet bpread[2]; pr->r = PREC_FAIL; for (int m1 = 0; m1 < MAX_PKTS_TO_CHECK_FOR_DROP; m1++) { @@ -35,8 +67,8 @@ void reconstruct_action(struct cap_file cf[], struct pkt_reconstruct* pr) { pr->r = m1 == 0 && m2 == 0 ? PREC_SAME : PREC_DROP; pr->diff_0 = m1; pr->diff_1 = m2; - while (m1-- >= 0) cap_next_bp (&cf[0], &bpread[0]); - while (m2-- >= 0) cap_next_bp (&cf[1], &bpread[1]); + while (m1-- >= 0) { cap_next_bp (&cf[0], &bpread[0]); update_stats(&bpread[0], stats[0]); } + while (m2-- >= 0) { cap_next_bp (&cf[1], &bpread[1]); update_stats(&bpread[1], stats[1]); } return; } @@ -46,8 +78,8 @@ void reconstruct_action(struct cap_file cf[], struct pkt_reconstruct* pr) { pr->r = PREC_DROP; pr->diff_0 = m2; pr->diff_1 = m1; - while (m2-- >= 0) cap_next_bp (&cf[0], &bpread[0]); - while (m1-- >= 0) cap_next_bp (&cf[1], &bpread[1]); + while (m2-- >= 0) { cap_next_bp (&cf[0], &bpread[0]); update_stats(&bpread[0], stats[0]); } + while (m1-- >= 0) { cap_next_bp (&cf[1], &bpread[1]); update_stats(&bpread[1], stats[1]); } return; } } @@ -80,11 +112,16 @@ int main(int argc, char** argv) { cf[0].sz/sizeof(struct buffer_packet)); } + + GHashTable *stats[2]; + stats[0] = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, destroy_pkt_stats); + stats[1] = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, destroy_pkt_stats); + struct pkt_reconstruct pr; struct buffer_packet bpread[2]; int c0 = 0, c1 = 0, stop = 0; while (c0 < cf[0].sz_obj && c1 < cf[1].sz_obj && !stop) { - reconstruct_action(cf, &pr); + reconstruct_action(cf, &pr, stats); c0 += pr.diff_0 + 1; c1 += pr.diff_1 + 1; switch (pr.r) { @@ -93,8 +130,8 @@ int main(int argc, char** argv) { break; case PREC_DROP: fprintf(stderr, "[!!] packets (%d,%d) ", c0, c1); - if (c0 > 0) fprintf(stderr, "%s dropped %d pkts ", cf[0].filename, pr.diff_0); - if (c1 > 0) fprintf(stderr, "%s has dropped %d pkts ", cf[1].filename, pr.diff_1); + if (c0 > 0) fprintf(stderr, "%s dropped %d pkts ", cf[0].filename, pr.diff_1); + if (c1 > 0) fprintf(stderr, "%s dropped %d pkts ", cf[1].filename, pr.diff_0); fprintf(stderr, "\n"); break; case PREC_FAIL: @@ -106,6 +143,29 @@ int main(int argc, char** argv) { printf("parsed (%d,%d) packets\n", c0, c1); + GHashTableIter iter; + gpointer key, value; + + struct pkt_stats ps_default = { + .count = 0, + .cumulated_size = 0 + }; + g_hash_table_iter_init (&iter, stats[0]); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + int *port = key; + struct pkt_stats *ps = value; + struct pkt_stats *ps2 = g_hash_table_lookup (stats[1], port); + if (ps2 == NULL) { + fprintf(stderr, "[!!] No packet received for this port\n"); + ps2 = &ps_default; + } + + double drop = ps->count > ps2->count ? (double)(ps->count - ps2->count) / (double)ps->count : (double)(ps2->count - ps->count) / (double)ps2->count; + + fprintf(stdout, "port=%d, avg_size=%lf, count=%ld, drop=%lf\n", *port, ps->cumulated_size / ps->count, ps->count, drop); + } + for (int i = 0; i < 2; i++) cap_unload (&cf[i]); return 0; }