Ejemplo n.º 1
0
static void destroyethtab(struct ethtab *table)
{
	struct ethtabent *ptemp = table->head;
	struct ethtabent *cnext = NULL;

	if (table->head != NULL)
		cnext = table->head->next_entry;

	while (ptemp != NULL) {
		if (ptemp->type == 1) {
			rate_destroy(&ptemp->un.figs.outrate);
			rate_destroy(&ptemp->un.figs.inrate);
		}
		free(ptemp);
		ptemp = cnext;

		if (cnext != NULL)
			cnext = cnext->next_entry;
	}
}
Ejemplo n.º 2
0
/*
 * Kill the entire TCP table
 */
void destroytcptable(struct tcptable *table)
{
	struct tcptableent *ctemp;
	struct tcptableent *c_next_entry;
	struct tcp_hashentry *hashtemp;
	struct tcp_hashentry *hashtemp_next;

	unsigned int i;

	/*
	 * Destroy main TCP table
	 */

	if (table->head != NULL) {
		ctemp = table->head;
		c_next_entry = table->head->next_entry;

		while (ctemp != NULL) {
			rate_destroy(&ctemp->rate);
			free(ctemp);
			ctemp = c_next_entry;

			if (c_next_entry != NULL)
				c_next_entry = c_next_entry->next_entry;
		}
	}
	/*
	 * Destroy list of closed entries
	 */

	destroy_closed_entries(table);

	/*
	 * Destroy hash table
	 */

	for (i = 0; i <= ENTRIES_IN_HASH_TABLE - 1; i++) {
		if (table->hash_table[i] != NULL) {
			hashtemp = table->hash_table[i];
			hashtemp_next = table->hash_table[i]->next_entry;

			while (hashtemp != NULL) {
				free(hashtemp);
				hashtemp = hashtemp_next;

				if (hashtemp_next != NULL)
					hashtemp_next =
					    hashtemp_next->next_entry;
			}
		}
	}
}
Ejemplo n.º 3
0
static void destroyiflist(struct iflist *list)
{
	struct iflist *ctmp;
	struct iflist *ptmp;

	if (list != NULL) {
		ptmp = list;
		ctmp = ptmp->next_entry;

		do {
			rate_destroy(&ptmp->rate);
			free(ptmp);
			ptmp = ctmp;
			if (ctmp != NULL)
				ctmp = ctmp->next_entry;
		} while (ptmp != NULL);
	}
}
Ejemplo n.º 4
0
static void destroy_tcp_entry(struct tcptable *table, struct tcptableent *ptmp)
{
	if (ptmp->prev_entry != NULL)
		ptmp->prev_entry->next_entry = ptmp->next_entry;
	else
		table->head = ptmp->next_entry;

	if (ptmp->next_entry != NULL)
		ptmp->next_entry->prev_entry = ptmp->prev_entry;
	else
		table->tail = ptmp->prev_entry;

	rate_destroy(&ptmp->rate);
	free(ptmp);

	if (table->head == NULL) {
		table->firstvisible = NULL;
		table->lastvisible = NULL;
	}
}
Ejemplo n.º 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();
}