User selectable sort criteria.
This commit is contained in:
11
TODO
11
TODO
@@ -1,21 +1,12 @@
|
|||||||
Things to do for iftop
|
Things to do for iftop
|
||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
* Bandwidth display in bytes/s
|
|
||||||
|
|
||||||
* Search for BSD interface names - need to know what to look for.
|
* Search for BSD interface names - need to know what to look for.
|
||||||
|
|
||||||
* IP types other than v4?
|
* IP types other than v4?
|
||||||
|
|
||||||
* Config file.
|
* 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.
|
* Find someone gullible to sort out autoconf.
|
||||||
|
|
||||||
* Which average to use for the bar graph? Show several and peaks? Colours?
|
* 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
|
* Single keypress firewalling of troublesome connections, a la top(1)'s K
|
||||||
to kill?
|
to kill?
|
||||||
|
|
||||||
* Configurable sort criteria.
|
|
||||||
|
|
||||||
* Configurable refresh rates.
|
* Configurable refresh rates.
|
||||||
|
|
||||||
* Filtering of items included in diplay
|
* Filtering of items included in diplay
|
||||||
|
|||||||
4
iftop.c
4
iftop.c
@@ -242,11 +242,11 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir)
|
|||||||
|
|
||||||
if(direction == 0) {
|
if(direction == 0) {
|
||||||
/* incoming */
|
/* incoming */
|
||||||
history_totals.recv[history_pos] += ntohs(iptr->ip_len);
|
history_totals.recv[history_pos] += len;
|
||||||
history_totals.total_recv += len;
|
history_totals.total_recv += len;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
history_totals.sent[history_pos] += ntohs(iptr->ip_len);
|
history_totals.sent[history_pos] += len;
|
||||||
history_totals.total_sent += len;
|
history_totals.total_sent += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ static void set_defaults() {
|
|||||||
options.paused = 0;
|
options.paused = 0;
|
||||||
options.showhelp = 0;
|
options.showhelp = 0;
|
||||||
options.bandwidth_in_bytes = 0;
|
options.bandwidth_in_bytes = 0;
|
||||||
|
options.sort = OPTION_SORT_DIV2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void die(char *msg) {
|
static void die(char *msg) {
|
||||||
|
|||||||
@@ -18,6 +18,14 @@ typedef enum {
|
|||||||
OPTION_PORTS_ON
|
OPTION_PORTS_ON
|
||||||
} option_port_t;
|
} 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 {
|
typedef struct {
|
||||||
/* interface on which to listen */
|
/* interface on which to listen */
|
||||||
char *interface;
|
char *interface;
|
||||||
@@ -39,6 +47,7 @@ typedef struct {
|
|||||||
int paused;
|
int paused;
|
||||||
int showhelp;
|
int showhelp;
|
||||||
int bandwidth_in_bytes;
|
int bandwidth_in_bytes;
|
||||||
|
option_sort_t sort;
|
||||||
|
|
||||||
} options_t;
|
} options_t;
|
||||||
|
|
||||||
|
|||||||
88
ui.c
88
ui.c
@@ -39,6 +39,10 @@
|
|||||||
" S - toggle show source port \n"\
|
" S - toggle show source port \n"\
|
||||||
" D - toggle show destination port\n"\
|
" D - toggle show destination port\n"\
|
||||||
" p - toggle port display\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"\
|
"\nGeneral:\n"\
|
||||||
" P - pause display\n"\
|
" P - pause display\n"\
|
||||||
" h - toggle this help display\n"\
|
" h - toggle this help display\n"\
|
||||||
@@ -84,12 +88,13 @@ int helptimer = 0;
|
|||||||
char helpmsg[HELP_MSG_SIZE];
|
char helpmsg[HELP_MSG_SIZE];
|
||||||
int dontshowdisplay = 0;
|
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;
|
int i;
|
||||||
host_pair_line* aa = (host_pair_line*)a;
|
for(i = start_div; i < HISTORY_DIVISIONS; i++) {
|
||||||
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++) {
|
|
||||||
if(aa->recv[i] + aa->sent[i] != bb->recv[i] + bb->sent[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]);
|
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;
|
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) {
|
void readable_size(float n, char* buf, int bsize, int ksize, int bytes) {
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -686,6 +744,26 @@ void ui_loop() {
|
|||||||
case 'P':
|
case 'P':
|
||||||
options.paused = !options.paused;
|
options.paused = !options.paused;
|
||||||
break;
|
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': {
|
case 'f': {
|
||||||
char *s;
|
char *s;
|
||||||
dontshowdisplay = 1;
|
dontshowdisplay = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user