#include "../include/traffic.h"
#define lpp (LINES - 6) /* Lines per page to display IP qtatistics */
void print_field(u_short y, u_short x, struct host *h, u_char col);
void help();
u_int column_width(u_char col);
void
show_stats(int sig)
{
u_int i; /* Counter variable */
struct host *host; /* Pointer host structure */
/* Initialize */
total.last_in = total.last_out = 0;
total.last_pkt_in = total.last_pkt_out = 0;
total.last_tcp_in = total.last_udp_in = total.last_icmp_in = 0;
total.last_tcp_out = total.last_udp_out = total.last_icmp_out = 0;
/* Proccess all hosts statistics */
for (i = 0; i < h_num; i++) {
host = &hosts[i]; /* To make code more clear */
/* Update total transfers */
host->tot_in += host->last_in = host->in;
host->tot_out += host->last_out = host->out;
host->tot_tcp_in += host->last_tcp_in = host->tcp_in;
host->tot_udp_in += host->last_udp_in = host->udp_in;
host->tot_icmp_in += host->last_icmp_in = host->icmp_in;
host->tot_tcp_out += host->last_tcp_out = host->tcp_out;
host->tot_udp_out += host->last_udp_out = host->udp_out;
host->tot_icmp_out += host->last_icmp_out = host->icmp_out;
/* Summarize */
total.last_in += host->last_in;
total.last_out += host->last_out;
total.last_tcp_in += host->last_tcp_in;
total.last_udp_in += host->last_udp_in;
total.last_icmp_in += host->last_icmp_in;
total.last_tcp_out += host->last_tcp_out;
total.last_udp_out += host->last_udp_out;
total.last_icmp_out += host->last_icmp_out;
/* Check maximum transfers */
if (host->in > host->max_in)
host->max_in = host->in;
if (host->out > host->max_out)
host->max_out = host->out;
host->in = 0;
host->out = 0;
host->tcp_in = host->udp_in = host->icmp_in = 0;
host->tcp_out = host->udp_out = host->icmp_out = 0;
/* Update packets counters */
host->tot_pkt_in += host->last_pkt_in = host->pkt_in;
host->tot_pkt_out += host->last_pkt_out = host->pkt_out;
/* Summarize */
total.last_pkt_in += host->pkt_in;
total.last_pkt_out += host->pkt_out;
/* Check maximum packets */
if (host->pkt_in > host->max_pkt_in)
host->max_pkt_in = host->pkt_in;
if (host->pkt_out > host->max_pkt_out)
host->max_pkt_out = host->pkt_out;
host->pkt_in = 0;
host->pkt_out = 0;
}
/* Summarize */
total.tot_in += total.last_in;
total.tot_out += total.last_out;
/* Summarize */
total.tot_pkt_in += total.last_pkt_in;
total.tot_pkt_out += total.last_pkt_out;
/* Summarize - Check maximum transfers */
if (total.last_in > total.max_in)
total.max_in = total.last_in;
if (total.last_out > total.max_out)
total.max_out = total.last_out;
/* Summarize - Check maximum packets */
if (total.last_pkt_in > total.max_pkt_in)
total.max_pkt_in = total.last_pkt_in;
if (total.last_pkt_out > total.max_pkt_out)
total.max_pkt_out = total.last_pkt_out;
opt.times++;
/* Lock */
if (m_packet)
m_display = 1;
if ((opt.logfile != NULL) && m_packet)
m_file = 1;
if (m_packet)
return;
/* If logging enabled then log */
if ((opt.logfile != NULL) && !m_file)
log_file();
/* Display on screen */
if (!opt.daemon)
display();
}
void
display()
{
extern WINDOW *win; /* Pointer to ncurses window */
extern struct options opt; /* Options */
extern struct host *hosts; /* Pointer to host info array */
extern u_int h_num; /* Number of watched hosts */
u_int i; /* Counter variable */
char *buf; /* Pointer to buffor */
u_char next=1; /* Position of next column */
u_long active=0; /* Active hosts counter */
/* Erase window */
werase(win);
if ( opt.mode == MODE_STAT) {
/* Print info */
mvwprintw( win, 0, 0, "Traffic Analyzer (c) Krzysztof \"Msciciel\" Pawlowski 2002, 2004");
/* sort */
switch(opt.sort) {
case COL_IP:
qsort(hosts, h_num, sizeof(struct host), cmp_ip);
break;
case COL_DATA:
qsort(hosts, h_num, sizeof(struct host), cmp_data_cur);
break;
case COL_DATA_MAX:
qsort(hosts, h_num, sizeof(struct host), cmp_data_max);
break;
case COL_DATA_TOT:
case COL_DATA_AVG:
qsort(hosts, h_num, sizeof(struct host), cmp_data_tot);
break;
case COL_PKT:
qsort(hosts, h_num, sizeof(struct host), cmp_pkt_cur);
break;
case COL_PKT_TOT:
case COL_PKT_AVG:
qsort(hosts, h_num, sizeof(struct host), cmp_pkt_tot);
break;
case COL_PKT_MAX:
qsort(hosts, h_num, sizeof(struct host), cmp_pkt_max);
break;
case COL_MAC:
qsort(hosts, h_num, sizeof(struct host), cmp_mac);
break;
case COL_HOSTNAME:
qsort(hosts, h_num, sizeof(struct host), cmp_hostname);
break;
case COL_TCP:
qsort(hosts, h_num, sizeof(struct host), cmp_tcp);
break;
case COL_UDP:
qsort(hosts, h_num, sizeof(struct host), cmp_udp);
break;
case COL_ICMP:
qsort(hosts, h_num, sizeof(struct host), cmp_icmp);
break;
case COL_TCP_TOT:
qsort(hosts, h_num, sizeof(struct host), cmp_tcp_tot);
break;
case COL_UDP_TOT:
qsort(hosts, h_num, sizeof(struct host), cmp_udp_tot);
break;
case COL_ICMP_TOT:
qsort(hosts, h_num, sizeof(struct host), cmp_icmp_tot);
break;
}
/* Print columns */
for(i=0; i < MAX_COL; i++)
if (opt.columns[i] != 0) {
next += print_col(opt.columns[i], next) + 2;
if ( next >= COLS )
opt.columns[i] = 0;
}
/* Calculate number of active hosts */
for(i=0; i < h_num; i++)
if ((hosts[i].last_in > 0) || (hosts[i].last_out > 0))
active++;
/* Print footer */
mvwprintw( win, LINES - 1, 1, "Device: %s | Unit: %s / %s | Refresh: %ds | Time: %2dh %2dm %2ds | From / To | Active: %d"
, opt.dev, opt.unit_name, opt.unit_t_name, opt.delay
, opt.times * opt.delay / 3600
, ((opt.times * opt.delay) % 3600) / 60
, (opt.times * opt.delay) % 60
, active );
}
/* Print help */
else if ( opt.mode == MODE_HELP)
help();
wrefresh(win);
/* Exit if timeout has been reached */
if (((opt.times * opt.delay) >= opt.timeout) && (opt.timeout > 0)) {
endwin();
exit(0);
}
}
/* Print column */
int
print_col(u_char col, u_char pos)
{
int i,j;
struct host *host; /* Pointer host structure */
u_short len; /* Column width */
/* Get column width */
len = column_width(col);
/* Print header */
switch (col) {
case COL_IP:
mvwprintw( win, 2, pos + (len - 4 ) / 2, "Host");
break;
case COL_DATA:
mvwprintw( win, 2, pos + (len - 4 ) / 2, "Data");
break;
case COL_DATA_MAX:
mvwprintw( win, 2, pos + (len - 8 ) / 2, "Data Max");
break;
case COL_DATA_AVG:
mvwprintw( win, 2, pos + (len - 8 ) / 2, "Data Avg");
break;
case COL_DATA_TOT:
mvwprintw( win, 2, pos + (len - 8 ) / 2, "Data Total");
break;
case COL_PKT:
mvwprintw( win, 2, pos + (len - 7 ) / 2, "Packets");
break;
case COL_PKT_TOT:
mvwprintw( win, 2, pos + (len - 13 ) / 2, "Packets Total");
break;
case COL_PKT_AVG:
mvwprintw( win, 2, pos + (len - 11 ) / 2, "Packets Avg");
break;
case COL_PKT_MAX:
mvwprintw( win, 2, pos + (len - 11 ) / 2, "Packets Max");
break;
case COL_MAC:
mvwprintw( win, 2, pos + (len - 3 ) / 2, "MAC");
break;
case COL_HOSTNAME:
mvwprintw( win, 2, pos + (len - 8 ) / 2, "Hostname");
break;
case COL_TCP:
mvwprintw( win, 2, pos + (len - 3 ) / 2, "TCP");
break;
case COL_UDP:
mvwprintw( win, 2, pos + (len - 3 ) / 2, "UDP");
break;
case COL_ICMP:
mvwprintw( win, 2, pos + (len - 4 ) / 2, "ICMP");
break;
case COL_TCP_TOT:
mvwprintw( win, 2, pos + (len - 9 ) / 2, "TCP Total");
break;
case COL_UDP_TOT:
mvwprintw( win, 2, pos + (len - 9 ) / 2, "UDP Total");
break;
case COL_ICMP_TOT:
mvwprintw( win, 2, pos + (len - 10 ) / 2, "ICMP Total");
break;
};
/* Print fields */
for (i = opt.page * lpp, j=0; i < h_num && i < opt.page * lpp + lpp - 2 * opt.total; i++, j++) {
print_field(4 + j, pos, &hosts[i], col);
}
/* Print summarize line */
if (opt.total) {
if (col == COL_IP)
mvwprintw( win, LINES - 3, 1, "%s", "TOTAL");
else
print_field(LINES - 3, pos, &total, col);
}
return len;
}
/* Print field */
void print_field(u_short y, u_short x, struct host *h, u_char col)
{
extern struct options opt;
extern WINDOW *win;
switch(col) {
/* Print data column */
case COL_DATA:
if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
mvwprintw( win, y, x, "%7d / %7d ", (int)(h->last_in * opt.unit / opt.delay)
, (int)(h->last_out * opt.unit / opt.delay));
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
mvwprintw( win, y, x, "%6.1f / %6.1f ", h->last_in * opt.unit / opt.delay
, h->last_out * opt.unit / opt.delay );
else if (cmp(opt.unit_name,"MB") || cmp(opt.unit_name,"mBit"))
mvwprintw( win, y, x, "%5.3f / %5.3f ", h->last_in * opt.unit / opt.delay
, h->last_out * opt.unit / opt.delay );
else
mvwprintw( win, y, x, "%8.5f / %8.5f ", h->last_in * opt.unit / opt.delay
, h->last_out * opt.unit / opt.delay );
break;
/* Print IP column */
case COL_IP:
mvwprintw( win, y, 1, "%s", inet_ntoa(h->ip));
break;
/* Print data maximum column */
case COL_DATA_MAX:
if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
mvwprintw( win, y, x, "%7d / %7d ", (int)(h->max_in * opt.unit / opt.delay)
, (int)(h->max_out * opt.unit / opt.delay));
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
mvwprintw( win, y, x, "%6.1f / %6.1f ", h->max_in * opt.unit / opt.delay
, h->max_out * opt.unit / opt.delay );
else if (cmp(opt.unit_name,"MB") || cmp(opt.unit_name,"mBit"))
mvwprintw( win, y, x, "%5.3f / %5.3f", h->max_in * opt.unit / opt.delay
, h->max_out * opt.unit / opt.delay);
else
mvwprintw( win, y, x, "%8.5f / %8.5f", h->max_in * opt.unit / opt.delay
, h->max_out * opt.unit / opt.delay);
break;
/* Print data average column */
case COL_DATA_AVG:
if (opt.times > 0) {
if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
mvwprintw( win, y, x, "%7d / %7d", (int)(h->tot_in * opt.unit / (opt.times * opt.delay))
, (int)(h->tot_out * opt.unit / (opt.times * opt.delay)));
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
mvwprintw( win, y, x, "%6.1f / %6.1f", h->tot_in * opt.unit / (opt.times * opt.delay)
, h->tot_out * opt.unit / (opt.times * opt.delay));
else if (cmp(opt.unit_name,"MB") || cmp(opt.unit_name,"mBit"))
mvwprintw( win, y, x, "%5.3f / %5.3f", h->tot_in * opt.unit / (opt.times * opt.delay)
, h->tot_out * opt.unit / (opt.times * opt.delay));
else
mvwprintw( win, y, x, "%8.5f / %8.5f", h->tot_in * opt.unit / (opt.times * opt.delay)
, h->tot_out * opt.unit / (opt.times * opt.delay));
}
break;
/* Print data total column */
case COL_DATA_TOT:
if (cmp(opt.unit_t_name,"B") || cmp(opt.unit_t_name,"Bit"))
mvwprintw( win, y, x, "%9d / %9d ", (int)(h->tot_in * opt.unit_t)
, (int)(h->tot_out * opt.unit_t));
else if (cmp(opt.unit_t_name,"KB") || cmp(opt.unit_t_name,"kBit"))
mvwprintw( win, y, x, "%9.1f / %9.1f ", h->tot_in * opt.unit_t
, h->tot_out * opt.unit_t);
else if (cmp(opt.unit_t_name,"MB") || cmp(opt.unit_t_name,"mBit"))
mvwprintw( win, y, x, "%8.1f / %8.1f ", h->tot_in * opt.unit_t
, h->tot_out * opt.unit_t);
else
mvwprintw( win, y, x, "%8.3f / %8.3f ", h->tot_in * opt.unit_t
, h->tot_out * opt.unit_t);
break;
/* Print packet current column */
case COL_PKT:
mvwprintw( win, y, x, "%5d / %5d ", (int)(h->last_pkt_in / opt.delay)
, (int)(h->last_pkt_out / opt.delay));
break;
/* Print packet average column */
case COL_PKT_AVG:
if (opt.times > 0)
mvwprintw( win, y, x, "%5d / %5d ", (int)(h->tot_pkt_in / (opt.delay * opt.times))
, (int)(h->tot_pkt_out / (opt.delay * opt.times)));
break;
/* Print packet maximum column */
case COL_PKT_MAX:
mvwprintw( win, y, x, "%5d / %5d ", (int)(h->max_pkt_in / opt.delay)
, (int)(h->max_pkt_out / opt.delay));
break;
/* Print packet current column */
case COL_PKT_TOT:
mvwprintw( win, y, x, "%8d / %8d ", (int)h->tot_pkt_in
, (int)h->tot_pkt_out);
break;
/* Print MAC address column */
case COL_MAC:
mvwprintw( win, y, x, "%18s ", h->mac);
break;
/* Print hostname column */
case COL_HOSTNAME:
mvwprintw( win, y, x, "%32s ", h->hostname);
break;
/* Print TCP column */
case COL_TCP:
if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
mvwprintw( win, y, x, "%7d / %7d ", (int)(h->last_tcp_in * opt.unit / opt.delay)
, (int)(h->last_tcp_out * opt.unit / opt.delay));
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
mvwprintw( win, y, x, "%6.1f / %6.1f ", h->last_tcp_in * opt.unit / opt.delay
, h->last_tcp_out * opt.unit / opt.delay );
else
mvwprintw( win, y, x, "%5.3f / %5.3f ", h->last_tcp_in * opt.unit / opt.delay
, h->last_tcp_out * opt.unit / opt.delay );
break;
/* Print UDP column */
case COL_UDP:
if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
mvwprintw( win, y, x, "%7d / %7d ", (int)(h->last_udp_in * opt.unit / opt.delay)
, (int)(h->last_udp_out * opt.unit / opt.delay));
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
mvwprintw( win, y, x, "%6.1f / %6.1f ", h->last_udp_in * opt.unit / opt.delay
, h->last_udp_out * opt.unit / opt.delay );
else
mvwprintw( win, y, x, "%5.3f / %5.3f ", h->last_udp_in * opt.unit / opt.delay
, h->last_udp_out * opt.unit / opt.delay );
break;
/* Print ICMP column */
case COL_ICMP:
if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
mvwprintw( win, y, x, "%7d / %7d ", (int)(h->last_icmp_in * opt.unit / opt.delay)
, (int)(h->last_icmp_out * opt.unit / opt.delay));
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
mvwprintw( win, y, x, "%6.1f / %6.1f ", h->last_icmp_in * opt.unit / opt.delay
, h->last_icmp_out * opt.unit / opt.delay );
else
mvwprintw( win, y, x, "%5.3f / %5.3f ", h->last_icmp_in * opt.unit / opt.delay
, h->last_icmp_out * opt.unit / opt.delay );
break;
/* Print TCP total column */
case COL_TCP_TOT:
if (cmp(opt.unit_t_name,"B") || cmp(opt.unit_t_name,"Bit"))
mvwprintw( win, y, x, "%9d / %9d ", (int)(h->tot_tcp_in * opt.unit_t)
, (int)(h->tot_tcp_out * opt.unit_t));
else if (cmp(opt.unit_t_name,"KB") || cmp(opt.unit_t_name,"kBit"))
mvwprintw( win, y, x, "%9.1f / %9.1f ", h->tot_tcp_in * opt.unit_t
, h->tot_tcp_out * opt.unit_t);
else
mvwprintw( win, y, x, "%8.1f / %8.1f ", h->tot_tcp_in * opt.unit_t
, h->tot_tcp_out * opt.unit_t);
break;
/* Print UDP total column */
case COL_UDP_TOT:
if (cmp(opt.unit_t_name,"B") || cmp(opt.unit_t_name,"Bit"))
mvwprintw( win, y, x, "%9d / %9d ", (int)(h->tot_udp_in * opt.unit_t)
, (int)(h->tot_udp_out * opt.unit_t));
else if (cmp(opt.unit_t_name,"KB") || cmp(opt.unit_t_name,"kBit"))
mvwprintw( win, y, x, "%9.1f / %9.1f ", h->tot_udp_in * opt.unit_t
, h->tot_udp_out * opt.unit_t);
else
mvwprintw( win, y, x, "%8.1f / %8.1f ", h->tot_udp_in * opt.unit_t
, h->tot_udp_out * opt.unit_t);
break;
/* Print ICMP total column */
case COL_ICMP_TOT:
if (cmp(opt.unit_t_name,"B") || cmp(opt.unit_t_name,"Bit"))
mvwprintw( win, y, x, "%9d / %9d ", (int)(h->tot_icmp_in * opt.unit_t)
, (int)(h->tot_icmp_out * opt.unit_t));
else if (cmp(opt.unit_t_name,"KB") || cmp(opt.unit_t_name,"kBit"))
mvwprintw( win, y, x, "%9.1f / %9.1f ", h->tot_icmp_in * opt.unit_t
, h->tot_icmp_out * opt.unit_t);
else
mvwprintw( win, y, x, "%8.1f / %8.1f ", h->tot_icmp_in * opt.unit_t
, h->tot_icmp_out * opt.unit_t);
break;
};
}
/* Display help */
void help()
{
extern WINDOW *win;
wprintw(win, "Keys:\n\
a + <column> - add column\n\
d + <column> - remove column\n\
u + <unit> - change data unit size\n\
U + <unit> - change total data unit size\n\
s + <column> - sort\n\
t - total line\n\
r - reset statistics\n\
? - help\n\
q - quit\n\
\n\
Columns:\n\
h - host ip\n\
c - current data transfer\n\
a - average data transfer\n\
m - maximum data transfer\n\
s - total data transfer\n\
p - current packets flow\n\
o - average packets flow\n\
m - maximum packets flow\n\
P - total packets flow\n\
M - MAC address\n\
H - hostname\n\
t - TCP data flow\n\
u - UDP data flow\n\
i - ICMP date flow\n\
T - Total TCP data flow\n\
U - Total UDP data flow\n\
I - Total ICMP date flow\n\
\n\
Units:\n\
b - Bits\n\
B - Bytes\n\
k - Kilobits\n\
K - Kilobytes\n\
m - Megabits\n\
M - Megabytes\n\
g - Gigabits\n\
G - Gigabytes\n");
}
/* Get column width */
u_int column_width(u_char col)
{
extern struct options opt;
switch(col) {
case COL_DATA:
case COL_DATA_MAX:
case COL_DATA_AVG:
case COL_TCP:
case COL_UDP:
case COL_ICMP:
if (cmp(opt.unit_name,"G") || cmp(opt.unit_name,"gBit"))
return 19;
else if (cmp(opt.unit_name,"B") || cmp(opt.unit_name,"Bit"))
return 17;
else if (cmp(opt.unit_name,"KB") || cmp(opt.unit_name,"kBit"))
return 15;
else
return 13;
case COL_DATA_TOT:
case COL_TCP_TOT:
case COL_UDP_TOT:
case COL_ICMP_TOT:
if (cmp(opt.unit_t_name,"B") || cmp(opt.unit_t_name,"Bit"))
return 21;
else if (cmp(opt.unit_t_name,"KB") || cmp(opt.unit_t_name,"kBit"))
return 21;
else
return 17;
case COL_IP:
return 15;
case COL_PKT:
case COL_PKT_AVG:
case COL_PKT_MAX:
return 13;
case COL_PKT_TOT:
return 19;
case COL_MAC:
return 19;
case COL_HOSTNAME:
return 32;
default:
return 0;
}
}
syntax highlighted by Code2HTML, v. 0.9.1