123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- /*
- * tui.c:
- *
- * Based on ui.c from the original iftop sources.
- *
- * This user interface does not make use of curses. Instead, it prints its
- * output to STDOUT. This output is activated by providing the '-t' flag.
- *
- */
- #include "config.h"
- #include <string.h>
- #include <stdio.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <unistd.h>
- #if defined(HAVE_TERMIOS_H)
- #include <termios.h>
- #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
- #include <sys/ioctl.h>
- #include <sgtty.h>
- #elif defined(HAVE_TERMIO_H)
- #include <sys/ioctl.h>
- #include <termio.h>
- #else
- #include <stdlib.h>
- #endif
- #include "sorted_list.h"
- #include "options.h"
- #include "ui_common.h"
- /* Width of the host column in the output */
- #define PRINT_WIDTH 40
- /*
- * UI print function
- */
- void tui_print() {
- sorted_list_node* nn = NULL;
- char host1[HOSTNAME_LENGTH], host2[HOSTNAME_LENGTH];
- char buf0_10[10], buf1_10[10], buf2_10[10];
- int j;
- static char *label;
- static char *labellong;
- int l = 0;
- if (!label) {
- xfree(label);
- label = (char *)calloc(PRINT_WIDTH + 1, 1);
- }
- if (!labellong) {
- xfree(labellong);
- labellong = (char *)calloc(PRINT_WIDTH + 1 + 9, 1);
- }
- if (options.paused ) {
- return;
- }
- /* Headings */
- snprintf(label, PRINT_WIDTH, "%-*s", PRINT_WIDTH, "Host name (port/service if enabled)");
- printf("%s %s %10s %10s %10s %10s\n", " #", label, "last 2s", "last 10s", "last 40s", "cumulative");
- /* Divider line */
- for (j = 0; j < PRINT_WIDTH + 52; j++) {
- printf("-");
- }
- printf("\n");
- /* Traverse the list of all connections */
- while((nn = sorted_list_next_item(&screen_list, nn)) != NULL && l < options.num_lines) {
- /* Increment the line counter */
- l++;
- /* Get the connection information */
- host_pair_line* screen_line = (host_pair_line*)nn->data;
- /* Assemble host information */
- sprint_host(host1, screen_line->ap.af, &(screen_line->ap.src6), screen_line->ap.src_port, screen_line->ap.protocol, PRINT_WIDTH, options.aggregate_src);
- sprint_host(host2, screen_line->ap.af, &(screen_line->ap.dst6), screen_line->ap.dst_port, screen_line->ap.protocol, PRINT_WIDTH, options.aggregate_dest);
- /* Send rate per connection */
- printf("%4d %s%s", l, host1, " =>");
- for(j = 0; j < HISTORY_DIVISIONS; j++) {
- readable_size(screen_line->sent[j], buf0_10, 10, 1024, options.bandwidth_in_bytes);
- printf(" %10s", buf0_10);
- }
- /* Cumulative sent data per connection */
- readable_size(screen_line->total_sent, buf0_10, 10, 1024, 1);
- printf(" %10s\n", buf0_10);
- /* Receive rate per connection */
- printf(" %s%s", host2, " <=");
- for(j = 0; j < HISTORY_DIVISIONS; j++) {
- readable_size(screen_line->recv[j], buf0_10, 10, 1024, options.bandwidth_in_bytes);
- printf(" %10s", buf0_10);
- }
- /* Cumulative received data per connection */
- readable_size(screen_line->total_recv, buf0_10, 10, 1024, 1);
- printf(" %10s\n", buf0_10);
- }
- /* Divider line */
- for (j = 0; j < PRINT_WIDTH + 52; j++) {
- printf("-");
- }
- printf("\n");
- /* Rate totals */
- snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total send rate:");
- printf("%s ", labellong);
- for(j = 0; j < HISTORY_DIVISIONS; j++) {
- readable_size((((host_pair_line *)&totals)->sent[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
- printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
- }
- snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total receive rate:");
- printf("%s ", labellong);
- for(j = 0; j < HISTORY_DIVISIONS; j++) {
- readable_size((((host_pair_line *)&totals)->recv[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
- printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
- }
- snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total send and receive rate:");
- printf("%s ", labellong);
- for(j = 0; j < HISTORY_DIVISIONS; j++) {
- readable_size((((host_pair_line *)&totals)->sent[j] + ((host_pair_line *)&totals)->recv[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
- printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
- }
- /* Divider line */
- for (j = 0; j < PRINT_WIDTH + 52; j++) {
- printf("-");
- }
- printf("\n");
- /* Peak traffic */
- snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Peak rate (sent/received/total):");
- readable_size(peaksent / RESOLUTION, buf0_10, 10, 1024, options.bandwidth_in_bytes);
- readable_size(peakrecv / RESOLUTION, buf1_10, 10, 1024, options.bandwidth_in_bytes);
- readable_size(peaktotal / RESOLUTION, buf2_10, 10, 1024, options.bandwidth_in_bytes);
- printf("%s %10s %10s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
- /* Cumulative totals */
- snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Cumulative (sent/received/total):");
- readable_size(history_totals.total_sent, buf0_10, 10, 1024, 1);
- readable_size(history_totals.total_recv, buf1_10, 10, 1024, 1);
- readable_size(history_totals.total_recv + history_totals.total_sent, buf2_10, 10, 1024, 1);
- printf("%s %10s %10s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
- /* Double divider line */
- for (j = 0; j < PRINT_WIDTH + 52; j++) {
- printf("=");
- }
- printf("\n\n");
- }
- /*
- * Text interface data structure initializations.
- */
- void tui_init() {
- screen_list_init();
- screen_hash = addr_hash_create();
- service_hash = serv_hash_create();
- serv_hash_initialise(service_hash);
- printf("Listening on %s\n", options.interface);
- }
- /*
- * Tick function indicating screen refresh
- */
- void tui_tick(int print) {
- if (print) {
- tui_print();
- }
- }
- /*
- * Main UI loop. Code any interactive character inputs here.
- */
- void tui_loop() {
- int i;
- extern sig_atomic_t foad;
- #if defined(HAVE_TERMIOS_H)
- struct termios new_termios, old_termios;
- tcgetattr(STDIN_FILENO, &old_termios);
- new_termios = old_termios;
- new_termios.c_lflag &= ~(ICANON|ECHO);
- new_termios.c_cc[VMIN] = 1;
- new_termios.c_cc[VTIME] = 0;
- tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
- #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
- struct sgttyb new_tty, old_tty;
- ioctl(STDIN_FILENO, TIOCGETP, &old_tty);
- new_tty = old_tty;
- new_tty.sg_flags &= ~(ICANON|ECHO);
- ioctl(STDIN_FILENO, TIOCSETP, &new_tty);
- #elif defined(HAVE_TERMIO_H)
- struct termio new_termio, old_termio;
- ioctl(0, TCGETA, &old_termio);
- new_termio = old_termio;
- new_termio.c_lflag &= ~(ICANON|ECHO);
- new_termio.c_cc[VMIN] = 1;
- new_termio.c_cc[VTIME] = 0;
- ioctl(0, TCSETA, &new_termio);
- #else
- system("/bin/stty cbreak -echo >/dev/null 2>&1");
- #endif
- while ((i = getchar()) != 'q' && foad == 0) {
- switch (i) {
- case 'u':
- tick(1);
- break;
- case 'n':
- options.dnsresolution ^= 1;
- printf("DNS resolution is %s.\n\n", options.dnsresolution ? "ON" : "OFF");
- tick(1);
- break;
- case 'N':
- options.portresolution ^= 1;
- printf("Port resolution is %s.\n\n", options.portresolution ? "ON" : "OFF");
- tick(1);
- break;
- case 's':
- options.aggregate_src ^= 1;
- printf("%s source host\n\n", options.aggregate_src ? "Hide" : "Show");
- tick(1);
- break;
- case 'd':
- options.aggregate_dest ^= 1;
- printf("%s destination host\n\n", options.aggregate_dest ? "Hide" : "Show");
- tick(1);
- break;
- case 'S':
- if (options.showports == OPTION_PORTS_OFF) {
- options.showports = OPTION_PORTS_SRC;
- }
- else if (options.showports == OPTION_PORTS_DEST) {
- options.showports = OPTION_PORTS_ON;
- }
- else if(options.showports == OPTION_PORTS_ON) {
- options.showports = OPTION_PORTS_DEST;
- }
- else {
- options.showports = OPTION_PORTS_OFF;
- }
- printf("Showing ports:%s%s%s%s.\n\n",
- options.showports == OPTION_PORTS_SRC ? " src" : "",
- options.showports == OPTION_PORTS_DEST ? " dest" : "",
- options.showports == OPTION_PORTS_ON ? " both" : "",
- options.showports == OPTION_PORTS_OFF ? " none" : "");
- tick(1);
- break;
- case 'D':
- if (options.showports == OPTION_PORTS_OFF) {
- options.showports = OPTION_PORTS_DEST;
- }
- else if (options.showports == OPTION_PORTS_SRC) {
- options.showports = OPTION_PORTS_ON;
- }
- else if(options.showports == OPTION_PORTS_ON) {
- options.showports = OPTION_PORTS_SRC;
- }
- else {
- options.showports = OPTION_PORTS_OFF;
- }
- printf("Showing ports:%s%s%s%s.\n\n",
- options.showports == OPTION_PORTS_SRC ? " src" : "",
- options.showports == OPTION_PORTS_DEST ? " dest" : "",
- options.showports == OPTION_PORTS_ON ? " both" : "",
- options.showports == OPTION_PORTS_OFF ? " none" : "");
- tick(1);
- break;
- case 'p':
- options.showports =
- (options.showports == OPTION_PORTS_OFF) ?
- OPTION_PORTS_ON :
- OPTION_PORTS_OFF;
- printf("Showing ports:%s%s%s%s.\n\n",
- options.showports == OPTION_PORTS_SRC ? " src" : "",
- options.showports == OPTION_PORTS_DEST ? " dest" : "",
- options.showports == OPTION_PORTS_ON ? " both" : "",
- options.showports == OPTION_PORTS_OFF ? " none" : "");
- tick(1);
- break;
- case 'P':
- options.paused ^= 1;
- if (options.paused) {
- printf("Pausing... press 'P' again to continue.\n");
- }
- else {
- printf("Continuing.\n\n");
- tick(1);
- }
- break;
- case 'o':
- options.freezeorder ^= 1;
- printf("Order %s.\n\n", options.freezeorder ? "frozen" : "unfrozen");
- tick(1);
- break;
- case '1':
- options.sort = OPTION_SORT_DIV1;
- printf("Sorting by column 1.\n\n");
- tick(1);
- break;
- case '2':
- options.sort = OPTION_SORT_DIV2;
- printf("Sorting by column 2.\n\n");
- tick(1);
- break;
- case '3':
- options.sort = OPTION_SORT_DIV3;
- printf("Sorting by column 3.\n\n");
- tick(1);
- break;
- case '<':
- options.sort = OPTION_SORT_SRC;
- printf("Sorting by column source.\n\n");
- tick(1);
- break;
- case '>':
- options.sort = OPTION_SORT_DEST;
- printf("Sorting by column destination.\n\n");
- tick(1);
- break;
- default:
- break;
- }
- }
- #if defined(HAVE_TERMIOS_H)
- tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
- #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
- ioctl(0, TIOCSETP, &old_tty);
- #elif defined(HAVE_TERMIO_H)
- ioctl(0, TCSETA, &old_termio);
- #else
- system("/bin/stty -cbreak echo >/dev/null 2>&1");
- #endif
- }
|