From 0bb20d36753ed1461e1181a2b179d89d0180cc93 Mon Sep 17 00:00:00 2001 From: pdw <> Date: Wed, 3 Apr 2002 21:28:41 +0000 Subject: [PATCH] Added src/dest bandwidth aggregation. --- CHANGES | 1 + hash.c | 16 ++++++++++ hash.h | 1 + options.c | 1 + options.h | 4 +-- ui.c | 90 ++++++++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 94 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 9e35e3e..72ea52c 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,7 @@ $Id$ 0.3 Fixed segfault bug. +Added src/dest aggregation. 0.2 02/04/02 diff --git a/hash.c b/hash.c index ed4f684..be73dbf 100644 --- a/hash.c +++ b/hash.c @@ -100,6 +100,22 @@ hash_status_enum hash_next_item(hash_type* hash_table, hash_node_type** ppnode) return HASH_STATUS_OK; } +void hash_delete_all(hash_type* hash_table) { + int i; + hash_node_type *n, *nn; + for(i = 0; i < hash_table->size; i++) { + n = hash_table->table[i]; + while(n != NULL) { + nn = n->next; + hash_table->delete_key(n->key); + free(n); + n = nn; + } + hash_table->table[i] = NULL; + } +} + + /* * Allocate and return a hash */ diff --git a/hash.h b/hash.h index b8f0d7b..9cb3460 100644 --- a/hash.h +++ b/hash.h @@ -35,5 +35,6 @@ hash_status_enum hash_insert(hash_type*, void* key, void *rec); hash_status_enum hash_delete(hash_type* hash_table, void* key); hash_status_enum hash_find(hash_type* hash_table, void* key, void** rec); hash_status_enum hash_next_item(hash_type* hash_table, hash_node_type** ppnode); +void hash_delete_all(hash_type* hash_table); #endif /* __HASH_H_ */ diff --git a/options.c b/options.c index c877762..cd7e8f2 100644 --- a/options.c +++ b/options.c @@ -121,6 +121,7 @@ void options_read(int argc, char **argv) { options.showbars = 0; break; + case '?': fprintf(stderr, "iftop: unknown option -%c\n", optopt); usage(stderr); diff --git a/options.h b/options.h index 35121cf..a244b67 100644 --- a/options.h +++ b/options.h @@ -10,9 +10,9 @@ #include #include -enum { +typedef enum { OPTION_AGGREGATE_OFF, - OPTION_AGGREGATE_SOURCE, + OPTION_AGGREGATE_SRC, OPTION_AGGREGATE_DEST } option_aggregate_t; diff --git a/ui.c b/ui.c index 946e1a0..7ff5a02 100644 --- a/ui.c +++ b/ui.c @@ -27,7 +27,7 @@ int history_divs[HISTORY_DIVISIONS] = {1, 5, 20}; typedef struct host_pair_line_tag { - addr_pair* ap; + addr_pair ap; long recv[HISTORY_DIVISIONS]; long sent[HISTORY_DIVISIONS]; } host_pair_line; @@ -41,6 +41,7 @@ extern options_t options ; void ui_finish(); +hash_type* screen_hash; sorted_list_type screen_list; host_pair_line totals; int peaksent, peakrecv, peaktotal; @@ -191,13 +192,25 @@ void analyse_data() { while(hash_next_item(history, &n) == HASH_STATUS_OK) { history_type* d = (history_type*)n->rec; host_pair_line* screen_line; + addr_pair ap; int i; int tsent, trecv; tsent = trecv = 0; - - screen_line = xcalloc(1, sizeof *screen_line); - screen_line->ap = (addr_pair*)n->key; + ap = *(addr_pair*)n->key; + + if(options.aggregate == OPTION_AGGREGATE_SRC) { + ap.dst.s_addr = 0; + } + else if(options.aggregate == OPTION_AGGREGATE_DEST) { + ap.src.s_addr = 0; + } + + if(hash_find(screen_hash, &ap, (void**)&screen_line) == HASH_STATUS_KEY_NOT_FOUND) { + screen_line = xcalloc(1, sizeof *screen_line); + hash_insert(screen_hash, &ap, screen_line); + screen_line->ap = ap; + } for(i = 0; i < HISTORY_LENGTH; i++) { int j; @@ -212,8 +225,13 @@ void analyse_data() { } - sorted_list_insert(&screen_list, screen_line); } + + n = NULL; + while(hash_next_item(screen_hash, &n) == HASH_STATUS_OK) { + sorted_list_insert(&screen_list, (host_pair_line*)n->rec); + } + hash_delete_all(screen_hash); for(i = 0; i < HISTORY_LENGTH; i++) { int j; @@ -262,13 +280,26 @@ void ui_print() { attron(A_REVERSE); addstr(" R "); attroff(A_REVERSE); - addstr(options.dnsresolution ? " name resolution off " - : " name resolution on "); + addstr(options.dnsresolution ? " resolver off " + : " resolver on "); attron(A_REVERSE); addstr(" B "); attroff(A_REVERSE); - addstr(options.showbars ? " bar graphs off " - : " bar graphs on "); + addstr(options.showbars ? " bars off " + : " bars on "); + + attron(A_REVERSE); + addstr(" S "); + attroff(A_REVERSE); + addstr(options.aggregate == OPTION_AGGREGATE_SRC ? " aggregate off " + : " aggregate src "); + + attron(A_REVERSE); + addstr(" D "); + attroff(A_REVERSE); + addstr(options.aggregate == OPTION_AGGREGATE_DEST ? " aggregate off " + : " aggregate dest "); + draw_bar_scale(&y); @@ -288,10 +319,15 @@ void ui_print() { L = sizeof hostname; } - if (options.dnsresolution) - resolve(&screen_line->ap->src, hostname, L); - else - strcpy(hostname, inet_ntoa(screen_line->ap->src)); + if(screen_line->ap.src.s_addr == 0) { + sprintf(hostname, " * "); + } + else { + if (options.dnsresolution) + resolve(&(screen_line->ap.src), hostname, L); + else + strcpy(hostname, inet_ntoa(screen_line->ap.src)); + } sprintf(line, "%-*s", L, hostname); mvaddstr(y, x, line); x += L; @@ -300,10 +336,15 @@ void ui_print() { mvaddstr(y+1, x, " <= "); x += 4; - if (options.dnsresolution) - resolve(&screen_line->ap->dst, hostname, L); - else - strcpy(hostname, inet_ntoa(screen_line->ap->dst)); + if(screen_line->ap.dst.s_addr == 0) { + sprintf(hostname, " * "); + } + else { + if (options.dnsresolution) + resolve(&screen_line->ap.dst, hostname, L); + else + strcpy(hostname, inet_ntoa(screen_line->ap.dst)); + } sprintf(line, "%-*s", L, hostname); mvaddstr(y, x, line); @@ -371,6 +412,7 @@ void ui_init() { erase(); screen_list_init(); + screen_hash = addr_hash_create(); } void ui_loop() { @@ -392,6 +434,20 @@ void ui_loop() { options.showbars = !options.showbars; tick(1); break; + + case 'S': + options.aggregate = + (options.aggregate == OPTION_AGGREGATE_SRC) + ? OPTION_AGGREGATE_OFF + : OPTION_AGGREGATE_SRC; + break; + + case 'D': + options.aggregate = + (options.aggregate == OPTION_AGGREGATE_DEST) + ? OPTION_AGGREGATE_OFF + : OPTION_AGGREGATE_DEST; + break; } tick(0); }