Annotation of embedaddon/iftop/tui.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * tui.c:
                      3:  *
                      4:  * Based on ui.c from the original iftop sources.
                      5:  *
                      6:  * This user interface does not make use of curses. Instead, it prints its
                      7:  * output to STDOUT. This output is activated by providing the '-t' flag.
                      8:  *
                      9:  */
                     10: 
                     11: #include "config.h"
                     12: 
                     13: #include <string.h>
                     14: #include <stdio.h>
                     15: #include <signal.h>
                     16: #include <stdlib.h>
                     17: #include <unistd.h>
                     18: 
                     19: #if defined(HAVE_TERMIOS_H)
                     20: #include <termios.h>
                     21: #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
                     22: #include <sys/ioctl.h>
                     23: #include <sgtty.h>
                     24: #elif defined(HAVE_TERMIO_H)
                     25: #include <sys/ioctl.h>
                     26: #include <termio.h>
                     27: #else
                     28: #include <stdlib.h>
                     29: #endif
                     30: 
                     31: #include "sorted_list.h"
                     32: #include "options.h"
                     33: #include "ui_common.h"
                     34: 
                     35: /* Width of the host column in the output */
                     36: #define PRINT_WIDTH 40
                     37: 
                     38: 
                     39: /*
                     40:  * UI print function
                     41:  */
                     42: void tui_print() {
                     43:   sorted_list_node* nn = NULL;
                     44:   char host1[HOSTNAME_LENGTH], host2[HOSTNAME_LENGTH];
                     45:   char buf0_10[10], buf1_10[10], buf2_10[10];
                     46:   int j;
                     47:   static char *label;
                     48:   static char *labellong;
                     49:   int l = 0;
                     50: 
                     51:   if (!label) {
                     52:     xfree(label);
                     53:     label = (char *)calloc(PRINT_WIDTH + 1, 1);
                     54:   }
                     55: 
                     56:   if (!labellong) {
                     57:     xfree(labellong);
                     58:     labellong = (char *)calloc(PRINT_WIDTH + 1 + 9, 1);
                     59:   }
                     60: 
                     61:   if (options.paused ) {
                     62:     return;
                     63:   }
                     64: 
                     65:   /* Headings */
                     66:   snprintf(label, PRINT_WIDTH, "%-*s", PRINT_WIDTH, "Host name (port/service if enabled)");
                     67:   printf("%s %s     %10s %10s %10s %10s\n", "   #", label, "last 2s", "last 10s", "last 40s", "cumulative");
                     68: 
                     69:   /* Divider line */
                     70:   for (j = 0; j < PRINT_WIDTH + 52; j++) {
                     71:     printf("-");
                     72:   }
                     73:   printf("\n");
                     74: 
                     75:   /* Traverse the list of all connections */
                     76:   while((nn = sorted_list_next_item(&screen_list, nn)) != NULL && l < options.num_lines) {
                     77:     /* Increment the line counter */
                     78:     l++;
                     79: 
                     80:     /* Get the connection information */
                     81:     host_pair_line* screen_line = (host_pair_line*)nn->data;
                     82: 
                     83:     /* Assemble host information */
                     84:     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);
                     85:     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);
                     86: 
                     87:     /* Send rate per connection */
                     88:     printf("%4d %s%s", l, host1, " =>");
                     89:     for(j = 0; j < HISTORY_DIVISIONS; j++) {
                     90:       readable_size(screen_line->sent[j], buf0_10, 10, 1024, options.bandwidth_in_bytes);
                     91:       printf(" %10s", buf0_10);
                     92:     }
                     93:     /* Cumulative sent data per connection */
                     94:     readable_size(screen_line->total_sent, buf0_10, 10, 1024, 1);
                     95:     printf(" %10s\n", buf0_10);
                     96: 
                     97:     /* Receive rate per connection */
                     98:     printf("     %s%s", host2, " <=");
                     99:     for(j = 0; j < HISTORY_DIVISIONS; j++) {
                    100:       readable_size(screen_line->recv[j], buf0_10, 10, 1024, options.bandwidth_in_bytes);
                    101:       printf(" %10s", buf0_10);
                    102:     }
                    103:     /* Cumulative received data per connection */
                    104:     readable_size(screen_line->total_recv, buf0_10, 10, 1024, 1);
                    105:     printf(" %10s\n", buf0_10);
                    106:   }
                    107: 
                    108:   /* Divider line */
                    109:   for (j = 0; j < PRINT_WIDTH + 52; j++) {
                    110:     printf("-");
                    111:   }
                    112:   printf("\n");
                    113: 
                    114:   /* Rate totals */
                    115:   snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total send rate:");
                    116:   printf("%s ", labellong);
                    117:   for(j = 0; j < HISTORY_DIVISIONS; j++) {
                    118:     readable_size((((host_pair_line *)&totals)->sent[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
                    119:     printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
                    120:   }
                    121: 
                    122:   snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total receive rate:");
                    123:   printf("%s ", labellong);
                    124:   for(j = 0; j < HISTORY_DIVISIONS; j++) {
                    125:     readable_size((((host_pair_line *)&totals)->recv[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
                    126:     printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
                    127:   }
                    128: 
                    129:   snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total send and receive rate:");
                    130:   printf("%s ", labellong);
                    131:   for(j = 0; j < HISTORY_DIVISIONS; j++) {
                    132:     readable_size((((host_pair_line *)&totals)->sent[j] + ((host_pair_line *)&totals)->recv[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
                    133:     printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
                    134:   }
                    135: 
                    136:   /* Divider line */
                    137:   for (j = 0; j < PRINT_WIDTH + 52; j++) {
                    138:     printf("-");
                    139:   }
                    140:   printf("\n");
                    141: 
                    142:   /* Peak traffic */
                    143:   snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Peak rate (sent/received/total):");
                    144:   readable_size(peaksent / RESOLUTION, buf0_10, 10, 1024, options.bandwidth_in_bytes);
                    145:   readable_size(peakrecv / RESOLUTION, buf1_10, 10, 1024, options.bandwidth_in_bytes);
                    146:   readable_size(peaktotal / RESOLUTION, buf2_10, 10, 1024, options.bandwidth_in_bytes);
                    147:   printf("%s %10s %10s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
                    148: 
                    149:   /* Cumulative totals */
                    150:   snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Cumulative (sent/received/total):");
                    151:   readable_size(history_totals.total_sent, buf0_10, 10, 1024, 1);
                    152:   readable_size(history_totals.total_recv, buf1_10, 10, 1024, 1);
                    153:   readable_size(history_totals.total_recv + history_totals.total_sent, buf2_10, 10, 1024, 1);
                    154:   printf("%s %10s %10s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
                    155: 
                    156:   /* Double divider line */
                    157:   for (j = 0; j < PRINT_WIDTH + 52; j++) {
                    158:     printf("=");
                    159:   }
                    160:   printf("\n\n");
                    161: }
                    162: 
                    163: 
                    164: /*
                    165:  * Text interface data structure initializations.
                    166:  */
                    167: void tui_init() {
                    168:   screen_list_init();
                    169:   screen_hash = addr_hash_create();
                    170:   service_hash = serv_hash_create();
                    171:   serv_hash_initialise(service_hash);
                    172: 
                    173:   printf("Listening on %s\n", options.interface);
                    174: }
                    175: 
                    176: 
                    177: /*
                    178:  * Tick function indicating screen refresh
                    179:  */
                    180: void tui_tick(int print) {
                    181:   if (print) {
                    182:     tui_print();
                    183:   }
                    184: }
                    185: 
                    186: 
                    187: /*
                    188:  * Main UI loop. Code any interactive character inputs here.
                    189:  */
                    190: void tui_loop() {
                    191:   int i;
                    192:   extern sig_atomic_t foad;
                    193: 
                    194: #if defined(HAVE_TERMIOS_H)
                    195:   struct termios new_termios, old_termios;
                    196: 
                    197:   tcgetattr(STDIN_FILENO, &old_termios);
                    198:   new_termios = old_termios;
                    199:   new_termios.c_lflag &= ~(ICANON|ECHO);
                    200:   new_termios.c_cc[VMIN] = 1;
                    201:   new_termios.c_cc[VTIME] = 0;
                    202:   tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
                    203: #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
                    204:   struct sgttyb new_tty, old_tty;
                    205: 
                    206:   ioctl(STDIN_FILENO, TIOCGETP, &old_tty);
                    207:   new_tty = old_tty;
                    208:   new_tty.sg_flags &= ~(ICANON|ECHO);
                    209:   ioctl(STDIN_FILENO, TIOCSETP, &new_tty);
                    210: #elif defined(HAVE_TERMIO_H)
                    211:   struct termio new_termio, old_termio;
                    212: 
                    213:   ioctl(0, TCGETA, &old_termio);
                    214:   new_termio = old_termio;
                    215:   new_termio.c_lflag &= ~(ICANON|ECHO);
                    216:   new_termio.c_cc[VMIN] = 1;
                    217:   new_termio.c_cc[VTIME] = 0;
                    218:   ioctl(0, TCSETA, &new_termio);
                    219: #else
                    220:   system("/bin/stty cbreak -echo >/dev/null 2>&1");
                    221: #endif
                    222: 
                    223:   while ((i = getchar()) != 'q' && foad == 0) {
                    224:     switch (i) {
                    225:       case 'u':
                    226:         tick(1);
                    227:         break;
                    228:       case 'n':
                    229:         options.dnsresolution ^= 1;
                    230:         printf("DNS resolution is %s.\n\n", options.dnsresolution ? "ON" : "OFF");
                    231:         tick(1);
                    232:         break;
                    233:       case 'N':
                    234:         options.portresolution ^= 1;
                    235:         printf("Port resolution is %s.\n\n", options.portresolution ? "ON" : "OFF");
                    236:         tick(1);
                    237:         break;
                    238:       case 's':
                    239:         options.aggregate_src ^= 1;
                    240:         printf("%s source host\n\n", options.aggregate_src ? "Hide" : "Show");
                    241:         tick(1);
                    242:         break;
                    243:       case 'd':
                    244:         options.aggregate_dest ^= 1;
                    245:         printf("%s destination host\n\n", options.aggregate_dest ? "Hide" : "Show");
                    246:         tick(1);
                    247:         break;
                    248:       case 'S':
                    249:         if (options.showports == OPTION_PORTS_OFF) {
                    250:           options.showports = OPTION_PORTS_SRC;
                    251:         }
                    252:         else if (options.showports == OPTION_PORTS_DEST) {
                    253:           options.showports = OPTION_PORTS_ON;
                    254:         }
                    255:         else if(options.showports == OPTION_PORTS_ON) {
                    256:           options.showports = OPTION_PORTS_DEST;
                    257:         }
                    258:         else {
                    259:           options.showports = OPTION_PORTS_OFF;
                    260:         }
                    261:         printf("Showing ports:%s%s%s%s.\n\n",
                    262:           options.showports == OPTION_PORTS_SRC ? " src" : "",
                    263:           options.showports == OPTION_PORTS_DEST ? " dest" : "",
                    264:           options.showports == OPTION_PORTS_ON ? " both" : "",
                    265:           options.showports == OPTION_PORTS_OFF ? " none" : "");
                    266:         tick(1);
                    267:         break;
                    268:       case 'D':
                    269:         if (options.showports == OPTION_PORTS_OFF) {
                    270:           options.showports = OPTION_PORTS_DEST;
                    271:         }
                    272:         else if (options.showports == OPTION_PORTS_SRC) {
                    273:           options.showports = OPTION_PORTS_ON;
                    274:         }
                    275:         else if(options.showports == OPTION_PORTS_ON) {
                    276:           options.showports = OPTION_PORTS_SRC;
                    277:         }
                    278:         else {
                    279:           options.showports = OPTION_PORTS_OFF;
                    280:         }
                    281:         printf("Showing ports:%s%s%s%s.\n\n",
                    282:           options.showports == OPTION_PORTS_SRC ? " src" : "",
                    283:           options.showports == OPTION_PORTS_DEST ? " dest" : "",
                    284:           options.showports == OPTION_PORTS_ON ? " both" : "",
                    285:           options.showports == OPTION_PORTS_OFF ? " none" : "");
                    286:         tick(1);
                    287:         break;
                    288:       case 'p':
                    289:         options.showports =
                    290:          (options.showports == OPTION_PORTS_OFF) ?
                    291:           OPTION_PORTS_ON :
                    292:           OPTION_PORTS_OFF;
                    293:         printf("Showing ports:%s%s%s%s.\n\n",
                    294:           options.showports == OPTION_PORTS_SRC ? " src" : "",
                    295:           options.showports == OPTION_PORTS_DEST ? " dest" : "",
                    296:           options.showports == OPTION_PORTS_ON ? " both" : "",
                    297:           options.showports == OPTION_PORTS_OFF ? " none" : "");
                    298:         tick(1);
                    299:         break;
                    300:       case 'P':
                    301:         options.paused ^= 1;
                    302:         if (options.paused) {
                    303:           printf("Pausing... press 'P' again to continue.\n");
                    304:         }
                    305:        else {
                    306:          printf("Continuing.\n\n");
                    307:          tick(1);
                    308:        }
                    309:        break;
                    310:       case 'o':
                    311:         options.freezeorder ^= 1;
                    312:         printf("Order %s.\n\n", options.freezeorder ? "frozen" : "unfrozen");
                    313:        tick(1);
                    314:        break;
                    315:       case '1':
                    316:         options.sort = OPTION_SORT_DIV1;
                    317:         printf("Sorting by column 1.\n\n");
                    318:        tick(1);
                    319:         break;
                    320:       case '2':
                    321:         options.sort = OPTION_SORT_DIV2;
                    322:         printf("Sorting by column 2.\n\n");
                    323:         tick(1);
                    324:         break;
                    325:       case '3':
                    326:         options.sort = OPTION_SORT_DIV3;
                    327:         printf("Sorting by column 3.\n\n");
                    328:         tick(1);
                    329:         break;
                    330:       case '<':
                    331:         options.sort = OPTION_SORT_SRC;
                    332:         printf("Sorting by column source.\n\n");
                    333:         tick(1);
                    334:         break;
                    335:       case '>':
                    336:         options.sort = OPTION_SORT_DEST;
                    337:         printf("Sorting by column destination.\n\n");
                    338:         tick(1);
                    339:         break;
                    340:       default:
                    341:         break;
                    342:     }
                    343:   }
                    344: 
                    345: #if defined(HAVE_TERMIOS_H)
                    346:   tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
                    347: #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
                    348:   ioctl(0, TIOCSETP, &old_tty);
                    349: #elif defined(HAVE_TERMIO_H)
                    350:   ioctl(0, TCSETA, &old_termio);
                    351: #else
                    352:   system("/bin/stty -cbreak echo >/dev/null 2>&1");
                    353: #endif
                    354: }
                    355: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>