Example #1
0
void packet_size_breakdown(struct OPTIONS *options, char *ifname,
                           int facilitytime, struct filterstate *ofilter)
{
    WINDOW *win;
    PANEL *panel;
    WINDOW *borderwin;
    PANEL *borderpanel;

    struct ifstat_brackets brackets[20];
    unsigned int interval;

    int ch;

    int fd;

    char buf[MAX_PACKET_SIZE];
    int br;
    char *ipacket;
    char iface[10];
    unsigned int mtu;

    struct sockaddr_ll fromaddr;
    unsigned short linktype;
    int pkt_result;

    struct timeval tv;
    unsigned long starttime, startlog, timeint;
    unsigned long now;
    unsigned long long unow;
    unsigned long updtime = 0;
    unsigned long long updtime_usec = 0;

    int logging = options->logging;
    FILE *logfile = NULL;

    struct promisc_states *promisc_list;

    char msgstring[80];

    if (!facility_active(PKTSIZEIDFILE, ifname))
        mark_facility(PKTSIZEIDFILE, "Packet size breakdown", ifname);
    else {
        snprintf(msgstring, 80,
                 "Packet sizes already being monitored on %s", ifname);
        write_error(msgstring, daemonized);
        return;
    }

    if (!iface_supported(ifname)) {
        err_iface_unsupported();
        unmark_facility(PKTSIZEIDFILE, ifname);
        return;
    }
    if (!iface_up(ifname)) {
        err_iface_down();
        unmark_facility(PKTSIZEIDFILE, ifname);
        return;
    }
    borderwin = newwin(LINES - 2, COLS, 1, 0);
    borderpanel = new_panel(borderwin);

    wattrset(borderwin, BOXATTR);
    tx_box(borderwin, ACS_VLINE, ACS_HLINE);
    mvwprintw(borderwin, 0, 1, " Packet Distribution by Size ");

    win = newwin(LINES - 4, COLS - 2, 2, 1);
    panel = new_panel(win);

    tx_stdwinset(win);
    wtimeout(win, -1);
    wattrset(win, STDATTR);
    tx_colorwin(win);

    move(LINES - 1, 1);
    stdexitkeyhelp();

    initialize_brackets(ifname, brackets, &interval, &mtu, win);

    mvwprintw(win, 1, 1, "Packet size brackets for interface %s", ifname);
    wattrset(win, BOXATTR);

    mvwprintw(win, 4, 1, "Packet Size (bytes)");
    mvwprintw(win, 4, 26, "Count");
    mvwprintw(win, 4, 36, "Packet Size (bytes)");
    mvwprintw(win, 4, 60, "Count");
    wattrset(win, HIGHATTR);

    if (logging) {
        if (strcmp(current_logfile, "") == 0) {
            snprintf(current_logfile, 80, "%s-%s.log", PKTSIZELOG, ifname);

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

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

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

    writelog(logging, logfile,
             "******** Packet size distribution facility started ********");

    exitloop = 0;
    gettimeofday(&tv, NULL);
    starttime = startlog = timeint = tv.tv_sec;

    open_socket(&fd);

    if (fd < 0) {
        unmark_facility(PKTSIZEIDFILE, ifname);
        return;
    }

    if ((first_active_facility()) && (options->promisc)) {
        init_promisc_list(&promisc_list);
        save_promisc_list(promisc_list);
        srpromisc(1, promisc_list);
        destroy_promisc_list(&promisc_list);
    }

    adjust_instance_count(PROCCOUNTFILE, 1);
    active_facility_countfile[0] = '\0';

    do {
        gettimeofday(&tv, NULL);
        now = tv.tv_sec;
        unow = tv.tv_sec * 1e+6 + tv.tv_usec;

        if (((options->updrate != 0)
             && (now - updtime >= options->updrate))
            || ((options->updrate == 0)
                && (unow - updtime_usec >= DEFAULT_UPDATE_DELAY))) {
            update_panels();
            doupdate();
            updtime = now;
            updtime_usec = unow;
        }
        if (now - timeint >= 5) {
            printelapsedtime(starttime, now, LINES - 3, 1, borderwin);
            timeint = now;
        }
        if ((now - startlog >= options->logspan) && (logging)) {
            write_size_log(brackets, now - starttime, ifname, mtu,
                           logfile);
            startlog = now;
        }
        check_rotate_flag(&logfile, logging);

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

        getpacket(fd, buf, &fromaddr, &ch, &br, iface, win);

        if (ch != ERR) {
            switch (ch) {
            case 12:
            case 'l':
            case 'L':
                tx_refresh_screen();
                break;
            case 'x':
            case 'X':
            case 'q':
            case 'Q':
            case 27:
            case 24:
                exitloop = 1;
            }
        }
        if (br > 0) {
            pkt_result =
                processpacket(buf, &ipacket, &br, NULL, NULL, NULL,
                              &fromaddr, &linktype, ofilter,
                              MATCH_OPPOSITE_USECONFIG, iface, ifname);

            if (pkt_result != PACKET_OK)
                continue;

            update_size_distrib(br, brackets, interval, win);
        }
    } while (!exitloop);

    if (logging) {
        signal(SIGUSR1, SIG_DFL);
        write_size_log(brackets, now - starttime, ifname, mtu, logfile);
        writelog(logging, logfile,
                 "******** Packet size distribution facility stopped ********");
        fclose(logfile);
    }
    close(fd);

    if ((options->promisc) && (is_last_instance())) {
        load_promisc_list(&promisc_list);
        srpromisc(0, promisc_list);
        destroy_promisc_list(&promisc_list);
    }

    adjust_instance_count(PROCCOUNTFILE, -1);

    del_panel(panel);
    delwin(win);
    del_panel(borderpanel);
    delwin(borderwin);
    unmark_facility(PKTSIZEIDFILE, ifname);
    strcpy(current_logfile, "");
}
Example #2
0
void hostmon(const struct OPTIONS *options, time_t facilitytime, char *ifptr,
	     struct filterstate *ofilter)
{
	int logging = options->logging;
	struct ethtab table;
	struct ethtabent *entry;

	char scratch_saddr[ETH_ALEN];
	char scratch_daddr[ETH_ALEN];
	unsigned int idx = 1;
	int is_ip;
	int ch;

	char *ifname = ifptr;

	struct timeval tv;
	time_t starttime;
	time_t now = 0;
	unsigned long long unow = 0;
	time_t statbegin = 0;
	time_t startlog = 0;
	time_t updtime = 0;
	unsigned long long updtime_usec = 0;

	struct eth_desc *list = NULL;

	FILE *logfile = NULL;

	int pkt_result;

	WINDOW *sortwin;
	PANEL *sortpanel;
	int keymode = 0;

	int instance_id;

	int fd;

	struct promisc_states *promisc_list;

	if (!facility_active(LANMONIDFILE, ifptr))
		mark_facility(LANMONIDFILE, "LAN monitor", ifptr);
	else {
		write_error("LAN station monitor already running on %s",
			 gen_iface_msg(ifptr));
		return;
	}

	if (ifptr != NULL) {
		if (!dev_up(ifptr)) {
			err_iface_down();
			unmark_facility(LANMONIDFILE, ifptr);
			return;
		}
	}

	if ((first_active_facility()) && (options->promisc)) {
		init_promisc_list(&promisc_list);
		save_promisc_list(promisc_list);
		srpromisc(1, promisc_list);
		destroy_promisc_list(&promisc_list);
	}

	adjust_instance_count(PROCCOUNTFILE, 1);
	instance_id = adjust_instance_count(LANMONCOUNTFILE, 1);

	hostmonhelp();

	initethtab(&table, options->actmode);

	/* Ethernet description list */
	struct eth_desc *elist = load_eth_desc(ARPHRD_ETHER);

	/* FDDI description list */
	struct eth_desc *flist = load_eth_desc(ARPHRD_FDDI);

	if (logging) {
		if (strcmp(current_logfile, "") == 0) {
			strncpy(current_logfile,
				gen_instance_logname(LANLOG, instance_id), 80);

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

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

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

		rotate_flag = 0;
		writelog(logging, logfile,
			 "******** LAN traffic monitor started ********");
	}

	leaveok(table.tabwin, TRUE);

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

	exitloop = 0;
	gettimeofday(&tv, NULL);
	starttime = statbegin = startlog = tv.tv_sec;

	PACKET_INIT(pkt);

	do {
		gettimeofday(&tv, NULL);
		now = tv.tv_sec;
		unow = tv.tv_sec * 1000000ULL + tv.tv_usec;

		if ((now - starttime) >= 5) {
			printelapsedtime(statbegin, now, LINES - 3, 15,
					 table.borderwin);
			updateethrates(&table, options->actmode, starttime, now,
				       idx);
			starttime = now;
		}
		if (logging) {
			check_rotate_flag(&logfile);
			if ((now - startlog) >= options->logspan) {
				writeethlog(table.head, options->actmode,
					    now - statbegin, logfile);
				startlog = now;
			}
		}
		if (((options->updrate != 0)
		     && (now - updtime >= options->updrate))
		    || ((options->updrate == 0)
			&& (unow - updtime_usec >= DEFAULT_UPDATE_DELAY))) {
			update_panels();
			doupdate();
			updtime = now;
			updtime_usec = unow;
		}

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

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

		if (ch != ERR) {
			if (keymode == 0) {
				switch (ch) {
				case KEY_UP:
					scrollethwin(&table, SCROLLDOWN, &idx);
					break;
				case KEY_DOWN:
					scrollethwin(&table, SCROLLUP, &idx);
					break;
				case KEY_PPAGE:
				case '-':
					pageethwin(&table, SCROLLDOWN, &idx);
					break;
				case KEY_NPAGE:
				case ' ':
					pageethwin(&table, SCROLLUP, &idx);
					break;
				case 12:
				case 'l':
				case 'L':
					tx_refresh_screen();
					break;
				case 's':
				case 'S':
					show_hostsort_keywin(&sortwin,
							     &sortpanel);
					keymode = 1;
					break;
				case 'q':
				case 'Q':
				case 'x':
				case 'X':
				case 27:
				case 24:
					exitloop = 1;
				}
			} else if (keymode == 1) {
				del_panel(sortpanel);
				delwin(sortwin);
				sort_hosttab(&table, &idx, ch);
				keymode = 0;
			}
		}
		if (pkt.pkt_len > 0) {
			char ifnamebuf[IFNAMSIZ];

			pkt_result =
			    packet_process(&pkt, NULL, NULL, NULL,
					  ofilter,
					  MATCH_OPPOSITE_USECONFIG,
					  0);

			if (pkt_result != PACKET_OK)
				continue;

			if (!ifptr) {
				/* we're capturing on "All interfaces", */
				/* so get the name of the interface */
				/* of this packet */
				int r = dev_get_ifname(pkt.pkt_ifindex, ifnamebuf);
				if (r != 0) {
					write_error("Unable to get interface name");
					break;	/* can't get interface name, get out! */
				}
				ifname = ifnamebuf;
			}

			/* get HW addresses */
			switch (pkt.pkt_hatype) {
			case ARPHRD_ETHER: {
				struct ethhdr *hdr_eth =
					(struct ethhdr *)pkt.pkt_buf;
				memcpy(scratch_saddr, hdr_eth->h_source,
				       ETH_ALEN);
				memcpy(scratch_daddr, hdr_eth->h_dest,
				       ETH_ALEN);
				list = elist;
				break; }
			case ARPHRD_FDDI: {
				struct fddihdr *hdr_fddi =
					(struct fddihdr *)pkt.pkt_buf;
				memcpy(scratch_saddr, hdr_fddi->saddr,
				       FDDI_K_ALEN);
				memcpy(scratch_daddr, hdr_fddi->daddr,
				       FDDI_K_ALEN);
				list = flist;
				break; }
			case ARPHRD_IEEE802:
			case ARPHRD_IEEE802_TR: {
				struct trh_hdr *hdr_trh =
					(struct trh_hdr *)pkt.pkt_buf;
				memcpy(scratch_saddr, hdr_trh->saddr,
				       TR_ALEN);
				memcpy(scratch_daddr, hdr_trh->daddr,
				       TR_ALEN);
				list = flist;
				break; }
			default:
				/* unknown link protocol */
				continue;
			}

			switch(pkt.pkt_protocol) {
			case ETH_P_IP:
			case ETH_P_IPV6:
				is_ip = 1;
				break;
			default:
				is_ip = 0;
				break;
			}

			/* Check source address entry */
			entry = in_ethtable(&table, pkt.pkt_hatype,
					scratch_saddr);

			if (!entry)
				entry = addethentry(&table, pkt.pkt_hatype,
						ifname, scratch_saddr, list);

			if (entry != NULL) {
				updateethent(entry, pkt.pkt_len, is_ip, 1);
				if (!entry->prev_entry->un.desc.printed)
					printethent(&table, entry->prev_entry,
						    idx);

				printethent(&table, entry, idx);
			}

			/* Check destination address entry */
			entry = in_ethtable(&table, pkt.pkt_hatype,
					scratch_daddr);
			if (!entry)
				entry = addethentry(&table, pkt.pkt_hatype,
						ifname, scratch_daddr, list);

			if (entry != NULL) {
				updateethent(entry, pkt.pkt_len, is_ip, 0);
				if (!entry->prev_entry->un.desc.printed)
					printethent(&table, entry->prev_entry,
						    idx);

				printethent(&table, entry, idx);
			}
		}
	} while (!exitloop);

err_close:
	close(fd);

err:
	if ((options->promisc) && (is_last_instance())) {
		load_promisc_list(&promisc_list);
		srpromisc(0, promisc_list);
		destroy_promisc_list(&promisc_list);
	}

	adjust_instance_count(PROCCOUNTFILE, -1);
	adjust_instance_count(LANMONCOUNTFILE, -1);

	if (logging) {
		signal(SIGUSR1, SIG_DFL);
		writeethlog(table.head, options->actmode,
			    time(NULL) - statbegin, logfile);
		writelog(logging, logfile,
			 "******** LAN traffic monitor stopped ********");
		fclose(logfile);
	}


	del_panel(table.tabpanel);
	delwin(table.tabwin);
	del_panel(table.borderpanel);
	delwin(table.borderwin);
	update_panels();
	doupdate();
	destroyethtab(&table);

	free_eth_desc(elist);
	free_eth_desc(flist);

	unmark_facility(LANMONIDFILE, ifptr);
	strcpy(current_logfile, "");
}
Example #3
0
void ifstats(const struct OPTIONS *options, struct filterstate *ofilter,
	     time_t facilitytime)
{
	int logging = options->logging;
	struct iftab table;

	int pkt_result = 0;

	struct iflist *ptmp = NULL;

	unsigned int idx = 1;

	FILE *logfile = NULL;

	int ch;

	int fd;

	struct timeval tv;
	time_t starttime = 0;
	time_t statbegin = 0;
	time_t now = 0;
	struct timeval start_tv;
	unsigned long long unow = 0;
	time_t startlog = 0;
	time_t updtime = 0;
	unsigned long long updtime_usec = 0;

	struct promisc_states *promisc_list;

	if (!facility_active(GSTATIDFILE, ""))
		mark_facility(GSTATIDFILE, "general interface statistics", "");
	else {
		write_error("General interface stats already active in another process");
		return;
	}

	initiflist(&(table.head));
	if (table.head == NULL) {
		no_ifaces_error();
		unmark_facility(GSTATIDFILE, "");
		return;
	}

	initiftab(&table);

	if ((first_active_facility()) && (options->promisc)) {
		init_promisc_list(&promisc_list);
		save_promisc_list(promisc_list);
		srpromisc(1, promisc_list);
		destroy_promisc_list(&promisc_list);
	}

	adjust_instance_count(PROCCOUNTFILE, 1);

	if (logging) {
		if (strcmp(current_logfile, "") == 0) {
			strcpy(current_logfile, GSTATLOG);

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

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

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

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

	preparescreen(&table);

	update_panels();
	doupdate();

	fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	if(fd == -1) {
		write_error("Unable to obtain monitoring socket");
		goto err;
	}

	//isdnfd = -1;
	exitloop = 0;
	gettimeofday(&tv, NULL);
	start_tv = tv;
	starttime = startlog = statbegin = tv.tv_sec;

	PACKET_INIT(pkt);

	while (!exitloop) {
		gettimeofday(&tv, NULL);
		now = tv.tv_sec;
		unow = tv.tv_sec * 1000000ULL + tv.tv_usec;

		if ((now - starttime) >= 1) {
			unsigned long msecs;

			msecs = timeval_diff_msec(&tv, &start_tv);
			updaterates(&table, options->actmode, msecs, idx);
			printelapsedtime(statbegin, now, LINES - 3, 1,
					 table.borderwin);
			starttime = now;
			start_tv = tv;
		}
		if (logging) {
			check_rotate_flag(&logfile);
			if ((now - startlog) >= options->logspan) {
				writegstatlog(&table, options->actmode,
					      time(NULL) - statbegin,
					      logfile);
				startlog = now;
			}
		}
		if (((options->updrate != 0)
		     && (now - updtime >= options->updrate))
		    || ((options->updrate == 0)
			&& (unow - updtime_usec >= DEFAULT_UPDATE_DELAY))) {
			update_panels();
			doupdate();
			updtime = now;
			updtime_usec = unow;
		}

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

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

		switch (ch) {
		case ERR:
			/* no key ready, do nothing */
			break;
		case KEY_UP:
			scrollgstatwin(&table, SCROLLDOWN, &idx);
			break;
		case KEY_DOWN:
			scrollgstatwin(&table, SCROLLUP, &idx);
			break;
		case KEY_PPAGE:
		case '-':
			pagegstatwin(&table, SCROLLDOWN, &idx);
			break;
		case KEY_NPAGE:
		case ' ':
			pagegstatwin(&table, SCROLLUP, &idx);
			break;
		case 12:
		case 'l':
		case 'L':
			tx_refresh_screen();
			break;
		case 'Q':
		case 'q':
		case 'X':
		case 'x':
		case 27:
		case 24:
			exitloop = 1;
			break;
		}
		if (pkt.pkt_len <= 0)
			continue;

		pkt_result = packet_process(&pkt, NULL, NULL, NULL,
					   ofilter,
					   MATCH_OPPOSITE_USECONFIG,
					   options->v6inv4asv6);

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

		ptmp = positionptr(table.head, pkt.pkt_ifindex);
		if (!ptmp)
			continue;

		ptmp->total++;

		ptmp->spanbr += pkt.pkt_len;
		ptmp->br += pkt.pkt_len;

		if (pkt.pkt_protocol == ETH_P_IP) {
			ptmp->iptotal++;

			if (pkt_result == CHECKSUM_ERROR) {
				(ptmp->badtotal)++;
				continue;
			}
		} else if (pkt.pkt_protocol == ETH_P_IPV6) {
			ptmp->ip6total++;
		} else {
			(ptmp->noniptotal)++;
		}
		printifentry(ptmp, table.statwin, idx);
	}
	close(fd);

err:
	if ((options->promisc) && (is_last_instance())) {
		load_promisc_list(&promisc_list);
		srpromisc(0, promisc_list);
		destroy_promisc_list(&promisc_list);
	}

	adjust_instance_count(PROCCOUNTFILE, -1);

	del_panel(table.statpanel);
	delwin(table.statwin);
	del_panel(table.borderpanel);
	delwin(table.borderwin);
	update_panels();
	doupdate();

	if (logging) {
		signal(SIGUSR1, SIG_DFL);
		writegstatlog(&table, options->actmode,
			      time(NULL) - statbegin, logfile);
		writelog(logging, logfile,
			 "******** General interface statistics stopped ********");
		fclose(logfile);
	}
	destroyiflist(table.head);
	pkt_cleanup();
	unmark_facility(GSTATIDFILE, "");
	strcpy(current_logfile, "");
}