4 * Based on ui.c from the original iftop sources.
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.
19 #if defined(HAVE_TERMIOS_H)
21 #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
22 #include <sys/ioctl.h>
24 #elif defined(HAVE_TERMIO_H)
25 #include <sys/ioctl.h>
31 #include "sorted_list.h"
33 #include "ui_common.h"
35 /* Width of the host column in the output */
36 #define PRINT_WIDTH 40
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];
48 static char *labellong;
53 label = (char *)calloc(PRINT_WIDTH + 1, 1);
58 labellong = (char *)calloc(PRINT_WIDTH + 1 + 9, 1);
61 if (options.paused ) {
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");
70 for (j = 0; j < PRINT_WIDTH + 52; j++) {
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 */
80 /* Get the connection information */
81 host_pair_line* screen_line = (host_pair_line*)nn->data;
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);
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);
93 /* Cumulative sent data per connection */
94 readable_size(screen_line->total_sent, buf0_10, 10, 1024, 1);
95 printf(" %10s\n", buf0_10);
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);
103 /* Cumulative received data per connection */
104 readable_size(screen_line->total_recv, buf0_10, 10, 1024, 1);
105 printf(" %10s\n", buf0_10);
109 for (j = 0; j < PRINT_WIDTH + 52; j++) {
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' : ' ');
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' : ' ');
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' : ' ');
137 for (j = 0; j < PRINT_WIDTH + 52; j++) {
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);
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);
156 /* Double divider line */
157 for (j = 0; j < PRINT_WIDTH + 52; j++) {
165 * Text interface data structure initializations.
169 screen_hash = addr_hash_create();
170 service_hash = serv_hash_create();
171 serv_hash_initialise(service_hash);
173 printf("Listening on %s\n", options.interface);
178 * Tick function indicating screen refresh
180 void tui_tick(int print) {
188 * Main UI loop. Code any interactive character inputs here.
192 extern sig_atomic_t foad;
194 #if defined(HAVE_TERMIOS_H)
195 struct termios new_termios, old_termios;
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;
206 ioctl(STDIN_FILENO, TIOCGETP, &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;
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);
220 system("/bin/stty cbreak -echo >/dev/null 2>&1");
223 while ((i = getchar()) != 'q' && foad == 0) {
229 options.dnsresolution ^= 1;
230 printf("DNS resolution is %s.\n\n", options.dnsresolution ? "ON" : "OFF");
234 options.portresolution ^= 1;
235 printf("Port resolution is %s.\n\n", options.portresolution ? "ON" : "OFF");
239 options.aggregate_src ^= 1;
240 printf("%s source host\n\n", options.aggregate_src ? "Hide" : "Show");
244 options.aggregate_dest ^= 1;
245 printf("%s destination host\n\n", options.aggregate_dest ? "Hide" : "Show");
249 if (options.showports == OPTION_PORTS_OFF) {
250 options.showports = OPTION_PORTS_SRC;
252 else if (options.showports == OPTION_PORTS_DEST) {
253 options.showports = OPTION_PORTS_ON;
255 else if(options.showports == OPTION_PORTS_ON) {
256 options.showports = OPTION_PORTS_DEST;
259 options.showports = OPTION_PORTS_OFF;
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" : "");
269 if (options.showports == OPTION_PORTS_OFF) {
270 options.showports = OPTION_PORTS_DEST;
272 else if (options.showports == OPTION_PORTS_SRC) {
273 options.showports = OPTION_PORTS_ON;
275 else if(options.showports == OPTION_PORTS_ON) {
276 options.showports = OPTION_PORTS_SRC;
279 options.showports = OPTION_PORTS_OFF;
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" : "");
290 (options.showports == 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" : "");
302 if (options.paused) {
303 printf("Pausing... press 'P' again to continue.\n");
306 printf("Continuing.\n\n");
311 options.freezeorder ^= 1;
312 printf("Order %s.\n\n", options.freezeorder ? "frozen" : "unfrozen");
316 options.sort = OPTION_SORT_DIV1;
317 printf("Sorting by column 1.\n\n");
321 options.sort = OPTION_SORT_DIV2;
322 printf("Sorting by column 2.\n\n");
326 options.sort = OPTION_SORT_DIV3;
327 printf("Sorting by column 3.\n\n");
331 options.sort = OPTION_SORT_SRC;
332 printf("Sorting by column source.\n\n");
336 options.sort = OPTION_SORT_DEST;
337 printf("Sorting by column destination.\n\n");
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);
352 system("/bin/stty -cbreak echo >/dev/null 2>&1");