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_unit);
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_unit);
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_unit);
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_unit);
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_unit);
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_unit);
145 readable_size(peakrecv / RESOLUTION, buf1_10, 10, 1024, options.bandwidth_unit);
146 readable_size(peaktotal / RESOLUTION, buf2_10, 10, 1024, options.bandwidth_unit);
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 /* Dropped packets */
157 snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Dropped packets:");
158 readable_size(history_totals.lost_packets, buf0_10, 10, 1024, options.bandwidth_unit);
159 printf("%s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
161 /* Double divider line */
162 for (j = 0; j < PRINT_WIDTH + 52; j++) {
170 * Text interface data structure initializations.
174 screen_hash = addr_hash_create();
175 service_hash = serv_hash_create();
176 serv_hash_initialise(service_hash);
178 printf("Listening on %s\n", options.interface);
183 * Tick function indicating screen refresh
185 void tui_tick(int print) {
193 * Main UI loop. Code any interactive character inputs here.
197 extern sig_atomic_t foad;
199 #if defined(HAVE_TERMIOS_H)
200 struct termios new_termios, old_termios;
202 tcgetattr(STDIN_FILENO, &old_termios);
203 new_termios = old_termios;
204 new_termios.c_lflag &= ~(ICANON|ECHO);
205 new_termios.c_cc[VMIN] = 1;
206 new_termios.c_cc[VTIME] = 0;
207 tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
208 #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
209 struct sgttyb new_tty, old_tty;
211 ioctl(STDIN_FILENO, TIOCGETP, &old_tty);
213 new_tty.sg_flags &= ~(ICANON|ECHO);
214 ioctl(STDIN_FILENO, TIOCSETP, &new_tty);
215 #elif defined(HAVE_TERMIO_H)
216 struct termio new_termio, old_termio;
218 ioctl(0, TCGETA, &old_termio);
219 new_termio = old_termio;
220 new_termio.c_lflag &= ~(ICANON|ECHO);
221 new_termio.c_cc[VMIN] = 1;
222 new_termio.c_cc[VTIME] = 0;
223 ioctl(0, TCSETA, &new_termio);
225 system("/bin/stty cbreak -echo >/dev/null 2>&1");
228 while ((i = getchar()) != 'q' && foad == 0) {
234 options.dnsresolution ^= 1;
235 printf("DNS resolution is %s.\n\n", options.dnsresolution ? "ON" : "OFF");
239 options.portresolution ^= 1;
240 printf("Port resolution is %s.\n\n", options.portresolution ? "ON" : "OFF");
244 options.aggregate_src ^= 1;
245 printf("%s source host\n\n", options.aggregate_src ? "Hide" : "Show");
249 options.aggregate_dest ^= 1;
250 printf("%s destination host\n\n", options.aggregate_dest ? "Hide" : "Show");
254 if (options.showports == OPTION_PORTS_OFF) {
255 options.showports = OPTION_PORTS_SRC;
257 else if (options.showports == OPTION_PORTS_DEST) {
258 options.showports = OPTION_PORTS_ON;
260 else if(options.showports == OPTION_PORTS_ON) {
261 options.showports = OPTION_PORTS_DEST;
264 options.showports = OPTION_PORTS_OFF;
266 printf("Showing ports:%s%s%s%s.\n\n",
267 options.showports == OPTION_PORTS_SRC ? " src" : "",
268 options.showports == OPTION_PORTS_DEST ? " dest" : "",
269 options.showports == OPTION_PORTS_ON ? " both" : "",
270 options.showports == OPTION_PORTS_OFF ? " none" : "");
274 if (options.showports == OPTION_PORTS_OFF) {
275 options.showports = OPTION_PORTS_DEST;
277 else if (options.showports == OPTION_PORTS_SRC) {
278 options.showports = OPTION_PORTS_ON;
280 else if(options.showports == OPTION_PORTS_ON) {
281 options.showports = OPTION_PORTS_SRC;
284 options.showports = OPTION_PORTS_OFF;
286 printf("Showing ports:%s%s%s%s.\n\n",
287 options.showports == OPTION_PORTS_SRC ? " src" : "",
288 options.showports == OPTION_PORTS_DEST ? " dest" : "",
289 options.showports == OPTION_PORTS_ON ? " both" : "",
290 options.showports == OPTION_PORTS_OFF ? " none" : "");
295 (options.showports == OPTION_PORTS_OFF) ?
298 printf("Showing ports:%s%s%s%s.\n\n",
299 options.showports == OPTION_PORTS_SRC ? " src" : "",
300 options.showports == OPTION_PORTS_DEST ? " dest" : "",
301 options.showports == OPTION_PORTS_ON ? " both" : "",
302 options.showports == OPTION_PORTS_OFF ? " none" : "");
307 if (options.paused) {
308 printf("Pausing... press 'P' again to continue.\n");
311 printf("Continuing.\n\n");
316 options.freezeorder ^= 1;
317 printf("Order %s.\n\n", options.freezeorder ? "frozen" : "unfrozen");
321 options.sort = OPTION_SORT_DIV1;
322 printf("Sorting by column 1.\n\n");
326 options.sort = OPTION_SORT_DIV2;
327 printf("Sorting by column 2.\n\n");
331 options.sort = OPTION_SORT_DIV3;
332 printf("Sorting by column 3.\n\n");
336 options.sort = OPTION_SORT_SRC;
337 printf("Sorting by column source.\n\n");
341 options.sort = OPTION_SORT_DEST;
342 printf("Sorting by column destination.\n\n");
350 #if defined(HAVE_TERMIOS_H)
351 tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
352 #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
353 ioctl(0, TIOCSETP, &old_tty);
354 #elif defined(HAVE_TERMIO_H)
355 ioctl(0, TCSETA, &old_termio);
357 system("/bin/stty -cbreak echo >/dev/null 2>&1");