diff --git a/TODO b/TODO index 8b1d47b..d010a03 100644 --- a/TODO +++ b/TODO @@ -1,21 +1,12 @@ Things to do for iftop $Id$ -* Bandwidth display in bytes/s - * Search for BSD interface names - need to know what to look for. * IP types other than v4? * Config file. -* Redesign totals: - - 2sec 10sec 40sec Peak Total -TX x x x x x -RX x x x x x -Total x x x x x - * Find someone gullible to sort out autoconf. * Which average to use for the bar graph? Show several and peaks? Colours? @@ -23,8 +14,6 @@ Total x x x x x * Single keypress firewalling of troublesome connections, a la top(1)'s K to kill? -* Configurable sort criteria. - * Configurable refresh rates. * Filtering of items included in diplay diff --git a/iftop.c b/iftop.c index 364e16f..232eaf9 100644 --- a/iftop.c +++ b/iftop.c @@ -242,11 +242,11 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir) if(direction == 0) { /* incoming */ - history_totals.recv[history_pos] += ntohs(iptr->ip_len); + history_totals.recv[history_pos] += len; history_totals.total_recv += len; } else { - history_totals.sent[history_pos] += ntohs(iptr->ip_len); + history_totals.sent[history_pos] += len; history_totals.total_sent += len; } diff --git a/options.c b/options.c index 98914af..7aaef08 100644 --- a/options.c +++ b/options.c @@ -95,6 +95,7 @@ static void set_defaults() { options.paused = 0; options.showhelp = 0; options.bandwidth_in_bytes = 0; + options.sort = OPTION_SORT_DIV2; } static void die(char *msg) { diff --git a/options.h b/options.h index 47b278e..b52911f 100644 --- a/options.h +++ b/options.h @@ -18,6 +18,14 @@ typedef enum { OPTION_PORTS_ON } option_port_t; +typedef enum { + OPTION_SORT_DIV1, + OPTION_SORT_DIV2, + OPTION_SORT_DIV3, + OPTION_SORT_SRC, + OPTION_SORT_DEST +} option_sort_t; + typedef struct { /* interface on which to listen */ char *interface; @@ -39,6 +47,7 @@ typedef struct { int paused; int showhelp; int bandwidth_in_bytes; + option_sort_t sort; } options_t; diff --git a/ui.c b/ui.c index 118185b..d53797e 100644 --- a/ui.c +++ b/ui.c @@ -39,6 +39,10 @@ " S - toggle show source port \n"\ " D - toggle show destination port\n"\ " p - toggle port display\n"\ +"\nSorting:\n"\ +" 1/2/3 - sort by 1st/2nd/3rd column\n"\ +" < - sort by source name\n"\ +" > - sort by dest name\n"\ "\nGeneral:\n"\ " P - pause display\n"\ " h - toggle this help display\n"\ @@ -84,12 +88,13 @@ int helptimer = 0; char helpmsg[HELP_MSG_SIZE]; int dontshowdisplay = 0; -int screen_line_compare(void* a, void* b) { +/* + * Compare two screen lines based on bandwidth. Start comparing from the + * specified column + */ +int screen_line_bandwidth_compare(host_pair_line* aa, host_pair_line* bb, int start_div) { int i; - host_pair_line* aa = (host_pair_line*)a; - host_pair_line* bb = (host_pair_line*)b; - /* Ignore the first division so that stuff doesn't jump around too much */ - for(i = 1; i < HISTORY_DIVISIONS; i++) { + for(i = start_div; i < HISTORY_DIVISIONS; i++) { if(aa->recv[i] + aa->sent[i] != bb->recv[i] + bb->sent[i]) { return(aa->recv[i] + aa->sent[i] < bb->recv[i] + bb->sent[i]); } @@ -97,6 +102,59 @@ int screen_line_compare(void* a, void* b) { return 1; } +/* + * Compare two screen lines based on hostname / IP. Fall over to compare by + * bandwidth. + */ +int screen_line_host_compare(struct in_addr* a, struct in_addr* b, host_pair_line* aa, host_pair_line* bb) { + char hosta[HOSTNAME_LENGTH], hostb[HOSTNAME_LENGTH]; + int r; + + /* This isn't overly efficient because we resolve again before + display. */ + if (options.dnsresolution) { + resolve(a, hosta, HOSTNAME_LENGTH); + resolve(b, hostb, HOSTNAME_LENGTH); + } + else { + strcpy(hosta, inet_ntoa(*a)); + strcpy(hostb, inet_ntoa(*b)); + } + + r = strcmp(hosta, hostb); + + if(r == 0) { + return screen_line_bandwidth_compare(aa, bb, 2); + } + else { + return (r > 0); + } + + +} + +int screen_line_compare(void* a, void* b) { + host_pair_line* aa = (host_pair_line*)a; + host_pair_line* bb = (host_pair_line*)b; + if(options.sort == OPTION_SORT_DIV1) { + return screen_line_bandwidth_compare(aa, bb, 0); + } + else if(options.sort == OPTION_SORT_DIV2) { + return screen_line_bandwidth_compare(aa, bb, 1); + } + else if(options.sort == OPTION_SORT_DIV3) { + return screen_line_bandwidth_compare(aa, bb, 2); + } + else if(options.sort == OPTION_SORT_SRC) { + return screen_line_host_compare(&(aa->ap.src), &(bb->ap.src), aa, bb); + } + else if(options.sort == OPTION_SORT_DEST) { + return screen_line_host_compare(&(aa->ap.dst), &(bb->ap.dst), aa, bb); + } + + return 1; +} + void readable_size(float n, char* buf, int bsize, int ksize, int bytes) { int i = 0; @@ -686,6 +744,26 @@ void ui_loop() { case 'P': options.paused = !options.paused; break; + case '1': + options.sort = OPTION_SORT_DIV1; + showhelp("Sort by col 1"); + break; + case '2': + options.sort = OPTION_SORT_DIV2; + showhelp("Sort by col 2"); + break; + case '3': + options.sort = OPTION_SORT_DIV3; + showhelp("Sort by col 3"); + break; + case '<': + options.sort = OPTION_SORT_SRC; + showhelp("Sort by source"); + break; + case '>': + options.sort = OPTION_SORT_DEST; + showhelp("Sort by dest"); + break; case 'f': { char *s; dontshowdisplay = 1;