Beispiel #1
0
static void writeethlog(struct ethtabent *list, unsigned long nsecs, FILE *fd)
{
	char atime[TIME_TARGET_MAX];
	struct ethtabent *ptmp = list;

	genatime(time(NULL), atime);

	fprintf(fd, "\n*** LAN traffic log, generated %s\n\n", atime);

	while (ptmp != NULL) {
		if (ptmp->type == 0) {
			if (ptmp->un.desc.linktype == ARPHRD_ETHER)
				fprintf(fd, "\nEthernet address: %s",
					ptmp->un.desc.ascaddr);
			else if (ptmp->un.desc.linktype == ARPHRD_FDDI)
				fprintf(fd, "\nFDDI address: %s",
					ptmp->un.desc.ascaddr);

			if (ptmp->un.desc.withdesc)
				fprintf(fd, " (%s)", ptmp->un.desc.desc);

			fprintf(fd, "\n");
		} else {
			fprintf(fd,
				"\tIncoming total %llu packets, %llu bytes; %llu IP packets\n",
				ptmp->un.figs.inpcount, ptmp->un.figs.inbcount,
				ptmp->un.figs.inippcount);
			fprintf(fd,
				"\tOutgoing total %llu packets, %llu bytes; %llu IP packets\n",
				ptmp->un.figs.outpcount,
				ptmp->un.figs.outbcount,
				ptmp->un.figs.outippcount);

			fprintf(fd, "\tAverage rates: ");
			char buf_in[32];
			char buf_out[32];
			rate_print(ptmp->un.figs.inbcount / nsecs, buf_in, sizeof(buf_in));
			rate_print(ptmp->un.figs.outbcount / nsecs, buf_out, sizeof(buf_out));
			fprintf(fd, "%s incoming, %s outgoing\n",
				buf_in, buf_out);

			if (nsecs > 5) {
				rate_print(rate_get_average(&ptmp->un.figs.inrate),
					   buf_in, sizeof(buf_in));
				rate_print(rate_get_average(&ptmp->un.figs.outrate),
					   buf_out, sizeof(buf_out));
				fprintf(fd,
					"\tLast 5-second rates: %s incoming, %s outgoing\n",
					buf_in, buf_out);
			}
		}

		ptmp = ptmp->next_entry;
	}

	fprintf(fd, "\nRunning time: %lu seconds\n", nsecs);
	fflush(fd);
}
Beispiel #2
0
static void printrates(struct ethtab *table, unsigned int target_row,
		       struct ethtabent *ptmp)
{
	char buf[32];

	rate_print_no_units(rate_get_average(&ptmp->un.figs.inrate),
		   buf, sizeof(buf));
	wmove(table->tabwin, target_row, 32 * COLS / 80);
	wprintw(table->tabwin, "%s", buf);

	rate_print_no_units(rate_get_average(&ptmp->un.figs.outrate),
		   buf, sizeof(buf));
	wmove(table->tabwin, target_row, 69 * COLS / 80);
	wprintw(table->tabwin, "%s", buf);
}
Beispiel #3
0
static void writegstatlog(struct iftab *table, int unit, unsigned long nsecs,
			  FILE *fd)
{
	struct iflist *ptmp = table->head;
	char atime[TIME_TARGET_MAX];

	genatime(time(NULL), atime);
	fprintf(fd, "\n*** General interface statistics log generated %s\n\n",
		atime);

	while (ptmp != NULL) {

		fprintf(fd,
			"%s: %llu total, %llu IP, %llu non-IP, %lu IP checksum errors",
			ptmp->ifname, ptmp->total, ptmp->iptotal,
			ptmp->noniptotal, ptmp->badtotal);

		if (nsecs > 5) {
			char buf[64];

			rate_print(ptmp->br / nsecs, unit, buf, sizeof(buf));
			fprintf(fd, ", average activity %s", buf);
			rate_print(ptmp->peakrate, unit, buf, sizeof(buf));
			fprintf(fd, ", peak activity %s", buf);
			rate_print(rate_get_average(&ptmp->rate), unit, buf, sizeof(buf));
			fprintf(fd, ", last 5-second average activity %s", buf);
		}
		fprintf(fd, "\n");

		ptmp = ptmp->next_entry;
	}

	fprintf(fd, "\n%lu seconds running time\n", nsecs);
	fflush(fd);
}
Beispiel #4
0
static void updaterates(struct iftab *table, int unit, unsigned long msecs,
			unsigned int idx)
{
	struct iflist *ptmp = table->firstvisible;
	unsigned long rate;
	char buf[64];

	wattrset(table->statwin, HIGHATTR);
	do {
		rate_add_rate(&ptmp->rate, ptmp->spanbr, msecs);
		rate = rate_get_average(&ptmp->rate);
		rate_print(rate, unit, buf, sizeof(buf));
		wmove(table->statwin, ptmp->index - idx, 63 * COLS / 80);
		wprintw(table->statwin, "%s", buf);

		if (rate > ptmp->peakrate)
			ptmp->peakrate = rate;

		ptmp->spanbr = 0;
		ptmp = ptmp->next_entry;
	} while (ptmp != table->lastvisible->next_entry);
}
Beispiel #5
0
/*
 * The detailed interface statistics function
 */
void detstats(char *iface, time_t facilitytime)
{
	int logging = options.logging;

	WINDOW *statwin;
	PANEL *statpanel;

	int pkt_result = 0;

	FILE *logfile = NULL;

	unsigned int iplen = 0;

	struct ifcounts ifcounts;

	int ch;

	struct timeval tv;
	struct timeval start_tv;
	struct timeval updtime;
	time_t starttime;
	time_t now;
	time_t statbegin;
	time_t startlog;

	struct proto_counter span;

	struct rate rate;
	struct rate rate_in;
	struct rate rate_out;
	unsigned long peakactivity = 0;
	unsigned long peakactivity_in = 0;
	unsigned long peakactivity_out = 0;

	struct rate pps_rate;
	struct rate pps_rate_in;
	struct rate pps_rate_out;
	unsigned long peakpps = 0;
	unsigned long peakpps_in = 0;
	unsigned long peakpps_out = 0;

	int fd;

	if (!dev_up(iface)) {
		err_iface_down();
		return;
	}

	LIST_HEAD(promisc);
	if (options.promisc) {
		promisc_init(&promisc, iface);
		promisc_set_list(&promisc);
	}

	move(LINES - 1, 1);
	stdexitkeyhelp();
	statwin = newwin(LINES - 2, COLS, 1, 0);
	statpanel = new_panel(statwin);
	tx_stdwinset(statwin);
	wtimeout(statwin, -1);
	wattrset(statwin, BOXATTR);
	tx_colorwin(statwin);
	tx_box(statwin, ACS_VLINE, ACS_HLINE);
	wmove(statwin, 0, 1);
	wprintw(statwin, " Statistics for %s ", iface);
	wattrset(statwin, STDATTR);
	update_panels();
	doupdate();

	memset(&ifcounts, 0, sizeof(struct ifcounts));

	if (logging) {
		if (strcmp(current_logfile, "") == 0) {
			snprintf(current_logfile, 64, "%s-%s.log", DSTATLOG,
				 iface);

			if (!daemonized)
				input_logfile(current_logfile, &logging);
		}
	}

	if (logging) {
		opentlog(&logfile, current_logfile);

		if (logfile == NULL)
			logging = 0;
	}
	if (logging) {
		signal(SIGUSR1, rotate_dstat_log);

		rotate_flag = 0;
		writelog(logging, logfile,
			 "******** Detailed interface statistics started ********");
	}

	printdetlabels(statwin);
	printdetails(&ifcounts, statwin);
	update_panels();
	doupdate();

	memset(&span, 0, sizeof(span));
	rate_alloc(&rate, 5);
	rate_alloc(&rate_in, 5);
	rate_alloc(&rate_out, 5);

	rate_alloc(&pps_rate, 5);
	rate_alloc(&pps_rate_in, 5);
	rate_alloc(&pps_rate_out, 5);

	gettimeofday(&tv, NULL);
	start_tv = tv;
	updtime = tv;
	starttime = startlog = statbegin = tv.tv_sec;

	leaveok(statwin, TRUE);

	fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	if(fd == -1) {
		write_error("Unable to obtain monitoring socket");
		goto err;
	}
	if(dev_bind_ifname(fd, iface) == -1) {
		write_error("Unable to bind interface on the socket");
		goto err_close;
	}

	exitloop = 0;

	PACKET_INIT(pkt);

	/*
	 * Data-gathering loop
	 */

	while (!exitloop) {
		gettimeofday(&tv, NULL);
		now = tv.tv_sec;

		if ((now - starttime) >= 1) {
			char buf[64];
			unsigned long activity, activity_in, activity_out;
			unsigned long pps, pps_in, pps_out;
			unsigned long msecs;

			wattrset(statwin, BOXATTR);
			printelapsedtime(statbegin, now, LINES - 3, 1, statwin);

			msecs = timeval_diff_msec(&tv, &start_tv);

			rate_add_rate(&rate, span.proto_total.pc_bytes, msecs);
			activity = rate_get_average(&rate);
			rate_add_rate(&rate_in, span.proto_in.pc_bytes, msecs);
			activity_in = rate_get_average(&rate_in);
			rate_add_rate(&rate_out, span.proto_out.pc_bytes, msecs);
			activity_out = rate_get_average(&rate_out);

			rate_add_rate(&pps_rate, span.proto_total.pc_packets, msecs);
			pps = rate_get_average(&pps_rate);
			rate_add_rate(&pps_rate_in, span.proto_in.pc_packets, msecs);
			pps_in = rate_get_average(&pps_rate_in);
			rate_add_rate(&pps_rate_out, span.proto_out.pc_packets, msecs);
			pps_out = rate_get_average(&pps_rate_out);

			memset(&span, 0, sizeof(span));
			starttime = now;
			start_tv = tv;

			wattrset(statwin, HIGHATTR);
			rate_print(activity, buf, sizeof(buf));
			mvwprintw(statwin, 14, 19, "%s", buf);
			rate_print_pps(pps, buf, sizeof(buf));
			mvwprintw(statwin, 15, 19, "%s", buf);
			rate_print(activity_in, buf, sizeof(buf));
			mvwprintw(statwin, 17, 19, "%s", buf);
			rate_print_pps(pps_in, buf, sizeof(buf));
			mvwprintw(statwin, 18, 19, "%s", buf);
			rate_print(activity_out, buf, sizeof(buf));
			mvwprintw(statwin, 20, 19, "%s", buf);
			rate_print_pps(pps_out, buf, sizeof(buf));
			mvwprintw(statwin, 21, 19, "%s", buf);

			if (activity > peakactivity)
				peakactivity = activity;

			if (activity_in > peakactivity_in)
				peakactivity_in = activity_in;

			if (activity_out > peakactivity_out)
				peakactivity_out = activity_out;

			if (pps > peakpps)
				peakpps = pps;

			if (pps_in > peakpps_in)
				peakpps_in = pps_in;

			if (pps_out > peakpps_out)
				peakpps_out = pps_out;
		}
		if (logging) {
			check_rotate_flag(&logfile);
			if ((now - startlog) >= options.logspan) {
				writedstatlog(iface,
					      peakactivity, peakpps,
					      peakactivity_in, peakpps_in,
					      peakactivity_out, peakpps_out,
					      &ifcounts, time(NULL) - statbegin,
					      logfile);

				startlog = now;
			}
		}

		if (screen_update_needed(&tv, &updtime)) {
			printdetails(&ifcounts, statwin);
			update_panels();
			doupdate();

			updtime = tv;
		}

		if ((facilitytime != 0)
		    && (((now - statbegin) / 60) >= facilitytime))
			exitloop = 1;

		if (packet_get(fd, &pkt, &ch, statwin) == -1) {
			write_error("Packet receive failed");
			exitloop = 1;
			break;
		}

		switch (ch) {
		case ERR:
			/* no key ready, do nothing */
			break;
		case 12:
		case 'l':
		case 'L':
			tx_refresh_screen();
			break;

		case 'Q':
		case 'q':
		case 'X':
		case 'x':
		case 24:
		case 27:
			exitloop = 1;
			break;
		}
		if (pkt.pkt_len <= 0)
			continue;

		int outgoing;

		pkt_result =
			packet_process(&pkt, NULL, NULL, NULL,
				       MATCH_OPPOSITE_USECONFIG,
				       options.v6inv4asv6);

		if (pkt_result != PACKET_OK
		    && pkt_result != MORE_FRAGMENTS)
			continue;

		outgoing = (pkt.pkt_pkttype == PACKET_OUTGOING);
		update_proto_counter(&ifcounts.total, outgoing, pkt.pkt_len);
		if (pkt.pkt_pkttype == PACKET_BROADCAST) {
			update_pkt_counter(&ifcounts.bcast, pkt.pkt_len);
		}

		update_proto_counter(&span, outgoing, pkt.pkt_len);

		/* account network layer protocol */
		switch(pkt.pkt_protocol) {
		case ETH_P_IP:
			if (pkt_result == CHECKSUM_ERROR) {
				update_pkt_counter(&ifcounts.bad, pkt.pkt_len);
				continue;
			}

			iplen = ntohs(pkt.iphdr->tot_len);

			update_proto_counter(&ifcounts.ipv4, outgoing, iplen);
			break;
		case ETH_P_IPV6:
			iplen = ntohs(pkt.ip6_hdr->ip6_plen) + 40;

			update_proto_counter(&ifcounts.ipv6, outgoing, iplen);
			break;
		default:
			update_proto_counter(&ifcounts.nonip, outgoing, iplen);
			continue;
		}

		__u8 ip_protocol = pkt_ip_protocol(&pkt);

		/* account transport layer protocol */
		switch (ip_protocol) {
		case IPPROTO_TCP:
			update_proto_counter(&ifcounts.tcp, outgoing, iplen);
			break;
		case IPPROTO_UDP:
			update_proto_counter(&ifcounts.udp, outgoing, iplen);
			break;
		case IPPROTO_ICMP:
		case IPPROTO_ICMPV6:
			update_proto_counter(&ifcounts.icmp, outgoing, iplen);
			break;
		default:
			update_proto_counter(&ifcounts.other, outgoing, iplen);
			break;
		}
	}

err_close:
	close(fd);

err:
	rate_destroy(&pps_rate_out);
	rate_destroy(&pps_rate_in);
	rate_destroy(&pps_rate);

	rate_destroy(&rate_out);
	rate_destroy(&rate_in);
	rate_destroy(&rate);

	if (options.promisc) {
		promisc_restore_list(&promisc);
		promisc_destroy(&promisc);
	}

	if (logging) {
		signal(SIGUSR1, SIG_DFL);
		writedstatlog(iface,
			      peakactivity, peakpps, peakactivity_in,
			      peakpps_in, peakactivity_out, peakpps_out,
			      &ifcounts, time(NULL) - statbegin,
			      logfile);
		writelog(logging, logfile,
			 "******** Detailed interface statistics stopped ********");
		fclose(logfile);
	}

	del_panel(statpanel);
	delwin(statwin);
	strcpy(current_logfile, "");
	pkt_cleanup();
	update_panels();
	doupdate();
}