⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifstats.c

📁 一个网络流量分析的完整的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***ifstats.c	- the interface statistics moduleWritten by Gerard Paul JavaCopyright (c) Gerard Paul Java 1997-2002This software is open source; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License in the included COPYING file fordetails.	***/#include <curses.h>#include <panel.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <unistd.h>#include <time.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <net/if_arp.h>#include <linux/if_packet.h>#include <net/if.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include <linux/if_ether.h>#include <winops.h>#include <labels.h>#include <listbox.h>#include <msgboxes.h>#include "ifstats.h"#include "ifaces.h"#include "isdntab.h"#include "fltdefs.h"#include "utfilter.h"#include "fltselect.h"#include "packet.h"#include "options.h"#include "log.h"#include "dirs.h"#include "deskman.h"#include "ipcsum.h"#include "attrs.h"#include "serv.h"#include "timer.h"#include "instances.h"#include "mode.h"#include "logvars.h"#include "promisc.h"#include "error.h"#define SCROLLUP 0#define SCROLLDOWN 1extern int exitloop;extern int daemonized;/* from log.c, applicable only to this module */void writegstatlog(struct iftab *table, int unit, unsigned long nsecs,		   FILE * logfile);void writedstatlog(char *ifname, int unit, float activity, float pps,		   float peakactivity, float peakpps,		   float peakactivity_in, float peakpps_in,		   float peakactivity_out, float peakpps_out,		   struct iftotals *ts, unsigned long nsecs,		   FILE * logfile);/* * USR1 log-rotation signal handlers */void rotate_gstat_log(){    rotate_flag = 1;    strcpy(target_logname, GSTATLOG);    signal(SIGUSR1, rotate_gstat_log);}void rotate_dstat_log(){    rotate_flag = 1;    strcpy(target_logname, current_logfile);    signal(SIGUSR1, rotate_dstat_log);}/* * Function to check if an interface is already in the interface list. * This eliminates duplicate interface entries due to aliases */int ifinlist(struct iflist *list, char *ifname){    struct iflist *ptmp = list;    int result = 0;    while ((ptmp != NULL) && (result == 0)) {	result = (strcmp(ifname, ptmp->ifname) == 0);	ptmp = ptmp->next_entry;    }    return result;}/* * Initialize the list of interfaces.  This linked list is used in the * selection boxes as well as in the general interface statistics screen. * * This function parses the /proc/net/dev file and grabs the interface names * from there.  The SIOGIFFLAGS ioctl() call is used to determine whether the * interfaces are active.  Inactive interfaces are omitted from selection * lists. */void initiflist(struct iflist **list){    FILE *fd;    char buf[161];    char ifname[8];    struct iflist *itmp = NULL;    struct iflist *tail = NULL;    unsigned int index = 0;    int resp;    *list = NULL;    fd = open_procnetdev();    if (fd == NULL) {	tx_errbox("Unable to obtain interface list", ANYKEY_MSG, &resp);	return;    }    do {	strcpy(buf, "");	get_next_iface(fd, ifname);	if (strcmp(ifname, "") != 0) {	    if (!(iface_supported(ifname)))		continue;	    if (ifinlist(*list, ifname))	/* ignore entry if already in */		continue;	/* interface list */	    /*	     * Check if the interface is actually up running.  This prevents	     * inactive devices in /proc/net/dev from actually appearing in	     * interface lists used by IPTraf.	     */	    if (!iface_up(ifname))		continue;	    /*	     * At this point, the interface is now sure to be up and running.	     */	    itmp = malloc(sizeof(struct iflist));	    bzero(itmp, sizeof(struct iflist));	    strcpy(itmp->ifname, ifname);	    index++;	    itmp->index = index;	    if (*list == NULL) {		*list = itmp;		itmp->prev_entry = NULL;	    } else {		tail->next_entry = itmp;		itmp->prev_entry = tail;	    }	    tail = itmp;	    itmp->next_entry = NULL;	}    } while (strcmp(ifname, "") != 0);    fclose(fd);}void positionptr(struct iftab *table, struct iflist **ptmp, char *ifname){    struct iflist *plast = NULL;    int ok = 0;    *ptmp = table->head;    while ((*ptmp != NULL) && (!ok)) {	ok = (strcmp((*ptmp)->ifname, ifname) == 0);	if (!ok) {	    if ((*ptmp)->next_entry == NULL)		plast = *ptmp;	    *ptmp = (*ptmp)->next_entry;	}    }    if (*ptmp == NULL) {	*ptmp = malloc(sizeof(struct iflist));	bzero(*ptmp, sizeof(struct iflist));	(*ptmp)->index = plast->index + 1;	plast->next_entry = *ptmp;	(*ptmp)->prev_entry = plast;	(*ptmp)->next_entry = NULL;	strcpy((*ptmp)->ifname, ifname);	if ((*ptmp)->index <= LINES - 4)	    table->lastvisible = *ptmp;    }}void destroyiflist(struct iflist *list){    struct iflist *ctmp;    struct iflist *ptmp;    if (list != NULL) {	ptmp = list;	ctmp = ptmp->next_entry;	do {	    free(ptmp);	    ptmp = ctmp;	    if (ctmp != NULL)		ctmp = ctmp->next_entry;	} while (ptmp != NULL);    }}void no_ifaces_error(void){    write_error("No active interfaces.  Check their status or the /proc filesystem",                daemonized);}void updaterates(struct iftab *table, int unit, time_t starttime,		 time_t now, unsigned int idx){    struct iflist *ptmp = table->firstvisible;    wattrset(table->statwin, HIGHATTR);    do {	wmove(table->statwin, ptmp->index - idx, 52 * COLS / 80);	if (unit == KBITS) {	    ptmp->rate =		((float) (ptmp->spanbr * 8 / 1000)) /		((float) (now - starttime));	    wprintw(table->statwin, "%8.2f kbits/sec", ptmp->rate);	} else {	    ptmp->rate =		((float) (ptmp->spanbr / 1024)) /		((float) (now - starttime));	    wprintw(table->statwin, "%8.2f kbytes/sec", ptmp->rate);	}	if (ptmp->rate > ptmp->peakrate)	    ptmp->peakrate = ptmp->rate;	ptmp->spanbr = 0;	ptmp = ptmp->next_entry;    } while (ptmp != table->lastvisible->next_entry);}void printifentry(struct iflist *ptmp, WINDOW * win, unsigned int idx){    unsigned int target_row;    if ((ptmp->index < idx) || (ptmp->index > idx + (LINES - 5)))	return;    target_row = ptmp->index - idx;    wattrset(win, STDATTR);    wmove(win, target_row, 1);    wprintw(win, "%s", ptmp->ifname);    wattrset(win, HIGHATTR);    wmove(win, target_row, 12 * COLS / 80);    printlargenum(ptmp->total, win);    wmove(win, target_row, 22 * COLS / 80);    printlargenum(ptmp->iptotal, win);    wmove(win, target_row, 32 * COLS / 80);    printlargenum(ptmp->noniptotal, win);    wmove(win, target_row, 42 * COLS / 80);    wprintw(win, "%8lu", ptmp->badtotal);}void preparescreen(struct iftab *table){    struct iflist *ptmp = table->head;    unsigned int i = 1;    unsigned int winht = LINES - 4;    table->firstvisible = table->head;    do {	printifentry(ptmp, table->statwin, 1);	if (i <= winht)	    table->lastvisible = ptmp;	ptmp = ptmp->next_entry;	i++;    } while ((ptmp != NULL) && (i <= winht));}void labelstats(WINDOW * win){    wmove(win, 0, 1);    wprintw(win, " Iface ");    wmove(win, 0, 16 * COLS / 80);    wprintw(win, " Total ");    wmove(win, 0, 29 * COLS / 80);    wprintw(win, " IP ");    wmove(win, 0, 36 * COLS / 80);    wprintw(win, " NonIP ");    wmove(win, 0, 45 * COLS / 80);    wprintw(win, " BadIP ");    wmove(win, 0, 55 * COLS / 80);    wprintw(win, " Activity ");}void initiftab(struct iftab *table){    table->borderwin = newwin(LINES - 2, COLS, 1, 0);    table->borderpanel = new_panel(table->borderwin);    move(LINES - 1, 1);    scrollkeyhelp();    stdexitkeyhelp();    wattrset(table->borderwin, BOXATTR);    box(table->borderwin, ACS_VLINE, ACS_HLINE);    labelstats(table->borderwin);    table->statwin = newwin(LINES - 4, COLS - 2, 2, 1);    table->statpanel = new_panel(table->statwin);    tx_stdwinset(table->statwin);    wtimeout(table->statwin, -1);    wattrset(table->statwin, STDATTR);    tx_colorwin(table->statwin);    wattrset(table->statwin, BOXATTR);    wmove(table->borderwin, LINES - 3, 32 * COLS / 80);    wprintw(table->borderwin,	    " Total, IP, NonIP, and BadIP are packet counts ");}/* * Scrolling routines for the general interface statistics window */void scrollgstatwin(struct iftab *table, int direction, unsigned int *idx){    char buf[255];    sprintf(buf, "%%%dc", COLS - 2);    wattrset(table->statwin, STDATTR);    if (direction == SCROLLUP) {	if (table->lastvisible->next_entry != NULL) {	    wscrl(table->statwin, 1);	    table->lastvisible = table->lastvisible->next_entry;	    table->firstvisible = table->firstvisible->next_entry;	    (*idx)++;	    wmove(table->statwin, LINES - 5, 0);	    scrollok(table->statwin, 0);	    wprintw(table->statwin, buf, ' ');	    scrollok(table->statwin, 1);	    printifentry(table->lastvisible, table->statwin, *idx);	}    } else {	if (table->firstvisible != table->head) {	    wscrl(table->statwin, -1);	    table->firstvisible = table->firstvisible->prev_entry;	    table->lastvisible = table->lastvisible->prev_entry;	    (*idx)--;	    wmove(table->statwin, 0, 0);	    wprintw(table->statwin, buf, ' ');	    printifentry(table->firstvisible, table->statwin, *idx);	}    }}void pagegstatwin(struct iftab *table, int direction, int *idx){    int i = 1;    if (direction == SCROLLUP) {	while ((i <= LINES - 5)	       && (table->lastvisible->next_entry != NULL)) {	    i++;	    scrollgstatwin(table, direction, idx);	}    } else {	while ((i <= LINES - 5) && (table->firstvisible != table->head)) {	    i++;	    scrollgstatwin(table, direction, idx);	}    }}/* * The general interface statistics function */void ifstats(const struct OPTIONS *options, struct filterstate *ofilter,    int facilitytime){    int logging = options->logging;    struct iftab table;    char buf[MAX_PACKET_SIZE];    char *packet;    int pkt_result = 0;    struct sockaddr_ll fromaddr;    unsigned short linktype;        unsigned sport, dport;        struct iflist *ptmp = NULL;    unsigned int idx = 1;    int fd;    FILE *logfile = NULL;    int br;    char ifname[10];    int ch;    struct timeval tv;    unsigned long starttime = 0;    unsigned long statbegin = 0;    unsigned long now = 0;    unsigned long long unow = 0;    unsigned long startlog = 0;    unsigned long 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",	     daemonized);	return;    }    initiflist(&(table.head));    if (table.head == NULL) {        no_ifaces_error();        unmark_facility(GSTATIDFILE, "");        return;    }        initiftab(&table);    open_socket(&fd);    if (fd < 0) {	unmark_facility(GSTATIDFILE, "");	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';        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 ********");    if (table.head != NULL) {	preparescreen(&table);	update_panels();	doupdate();        isdnfd = -1;	exitloop = 0;	gettimeofday(&tv, NULL);	starttime = startlog = statbegin = tv.tv_sec;	while (!exitloop) {	    getpacket(fd, buf, &fromaddr, &ch, &br, ifname, table.statwin);	    if (ch != ERR) {		switch (ch) {		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 (br > 0) {                pkt_result = processpacket(buf, &packet, &br, NULL, &sport, &dport,                    &fromaddr, &linktype, ofilter, ifname, NULL);		if (pkt_result == INVALID_PACKET)		    continue;				positionptr(&table, &ptmp, ifname);		ptmp->total++;		ptmp->spanbr += br;		ptmp->br += br;		if (fromaddr.sll_protocol == ETH_P_IP) {		    ptmp->iptotal++;		                    if (pkt_result == CHECKSUM_ERROR) {			(ptmp->badtotal)++;			continue;	            }		} else {		    (ptmp->noniptotal)++;		}		printifentry(ptmp, table.statwin, idx);	    }	    gettimeofday(&tv, NULL);	    now = tv.tv_sec;	    unow = tv.tv_sec * 1e+6 + tv.tv_usec;	    if ((now - starttime) >= 5) {		updaterates(&table, options->actmode, starttime, now, idx);		printelapsedtime(statbegin, now, LINES - 3, 1,				 table.borderwin);		starttime = now;	    }	    if (((now - startlog) >= options->logspan) && (logging)) {		writegstatlog(&table, options->actmode,			      time((time_t *) 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;	    }	    check_rotate_flag(&logfile, logging);	    if ((facilitytime != 0)		&& (((now - statbegin) / 60) >= facilitytime))		exitloop = 1;	}	close(fd);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -