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

📄 bandwidthd.c

📁 linux下流量查看软件,可以查看到每台机子的具体流量
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "bandwidthd.h"#ifdef HAVE_LIBPQ#include <libpq-fe.h>#endif// We must call regular exit to write out profile data, but child forks are supposed to usually// call _exit?#ifdef PROFILE#define _exit(x) exit(x)#endif/*#ifdef DEBUG#define fork() (0)#endif*/// ****************************************************************************************// ** Global Variables// ****************************************************************************************static pcap_t *pd;unsigned int GraphIntervalCount = 0;unsigned int IpCount = 0;unsigned int SubnetCount = 0;time_t IntervalStart;int RotateLogs = FALSE;    struct SubnetData SubnetTable[SUBNET_NUM];struct IPData IpTable[IP_NUM];int DataLink;int IP_Offset;struct IPDataStore *IPDataStore = NULL;extern int bdconfig_parse(void);extern FILE *bdconfig_in;struct config config;pid_t workerchildpids[NR_WORKER_CHILDS];void signal_handler(int sig)	{	switch (sig) 		{		case SIGHUP:			signal(SIGHUP, signal_handler);			RotateLogs++;			if (config.tag == '1') 				{				int i;				/* signal children */				for (i=0; i < NR_WORKER_CHILDS; i++) 					kill(workerchildpids[i], SIGHUP);				}			break;		case SIGTERM:			if (config.tag == '1') 				{				int i;				/* send term signal to children */				for (i=0; i < NR_WORKER_CHILDS; i++) 					kill(workerchildpids[i], SIGTERM);				}			// TODO: Might want to make sure we're not in the middle of wrighting out a log file			exit(0);			break;		}	}void bd_CollectingData(char *filename)	{	FILE *index;	index = fopen(filename, "wt");		if (index)		{		fprintf(index, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");		fprintf(index, "<HTML><HEAD><TITLE>Bandwidthd</TITLE>\n");		if (config.meta_refresh)			fprintf(index, "<META HTTP-EQUIV=\"REFRESH\" content=\"%u\">\n",					config.meta_refresh);		fprintf(index, "<META HTTP-EQUIV=\"EXPIRES\" content=\"-1\">\n");		fprintf(index, "<META HTTP-EQUIV=\"PRAGMA\" content=\"no-cache\">\n");		fprintf(index, "</HEAD>\n<BODY><center><img src=\"logo.gif\" ALT=\"Logo\"><BR>\n");		fprintf(index, "<BR>\n - <a href=\"index.html\">Daily</a> -- <a href=\"index2.html\">Weekly</a> -- ");		fprintf(index, "<a href=\"index3.html\">Monthly</a> -- <a href=\"index4.html\">Yearly</a><BR>\n");		fprintf(index, "</CENTER><BR>bandwidthd has nothing to graph.  This message should be replaced by graphs in a few minutes.  If it's not, please see the section titled \"Known Bugs and Troubleshooting\" in the README");				fprintf(index, "</BODY></HTML>\n");		fclose(index);		}	else		{		syslog(LOG_ERR, "Cannot open %s for writing", filename);		exit(1);		}	}int WriteOutWebpages(long int timestamp){	struct IPDataStore *DataStore = IPDataStore;	struct SummaryData **SummaryData;	int NumGraphs = 0;	pid_t graphpid;	int Counter;	/* Did we catch any packets since last time? */	if (!DataStore) return -1;	// break off from the main line so we don't miss any packets while we graph	graphpid = fork();	switch (graphpid) {		case 0: /* we're the child, graph. */			{#ifdef PROFILE			// Got this incantation from a message board.  Don't forget to set			// GMON_OUT_PREFIX in the shell			extern void _start(void), etext(void);			syslog(LOG_INFO, "Calling profiler startup...");			monstartup((u_long) &_start, (u_long) &etext);#endif          	signal(SIGHUP, SIG_IGN);			    	    nice(4); // reduce priority so I don't choke out other tasks			// Count Number of IP's in datastore			for (DataStore = IPDataStore, Counter = 0; DataStore; Counter++, DataStore = DataStore->Next);			// +1 because we don't want to accidently allocate 0			SummaryData = malloc(sizeof(struct SummaryData *)*Counter+1);			DataStore = IPDataStore;			while (DataStore) // Is not null				{				if (DataStore->FirstBlock->NumEntries > 0)					{					SummaryData[NumGraphs] = (struct SummaryData *) malloc(sizeof(struct SummaryData));					GraphIp(DataStore, SummaryData[NumGraphs++], timestamp+LEAD*config.range);					}			    DataStore = DataStore->Next;				}			MakeIndexPages(NumGraphs, SummaryData);				_exit(0);			}		break;		case -1:			syslog(LOG_ERR, "Forking grapher child failed!");			return -2;		break;		default: /* parent + successful fork, assume graph success */			return 0;		break;	}}void setchildconfig (int level) {	static unsigned long long graph_cutoff;	switch (level) {		case 0:			config.range = RANGE1;			config.interval = INTERVAL1;			config.tag = '1';			graph_cutoff = config.graph_cutoff;		break;		case 1:			// Overide skip_intervals for children			config.skip_intervals = CONFIG_GRAPHINTERVALS;			config.range = RANGE2;			config.interval = INTERVAL2;			config.tag = '2';			config.graph_cutoff = graph_cutoff*(RANGE2/RANGE1);			break;		case 2:			// Overide skip_intervals for children			config.skip_intervals = CONFIG_GRAPHINTERVALS;			config.range = RANGE3;			config.interval = INTERVAL3;			config.tag = '3';			config.graph_cutoff = graph_cutoff*(RANGE3/RANGE1);		break;		case 3:			// Overide skip_intervals for children			config.skip_intervals = CONFIG_GRAPHINTERVALS;			config.range = RANGE4;			config.interval = INTERVAL4;			config.tag = '4';			config.graph_cutoff = graph_cutoff*(RANGE4/RANGE1);		break;		default:			syslog(LOG_ERR, "setchildconfig got an invalid level argument: %d", level);			_exit(1);	}}void makepidfile(pid_t pid) 	{	FILE *pidfile;	pidfile = fopen("/var/run/bandwidthd.pid", "wt");	if (pidfile) 		{		if (fprintf(pidfile, "%d\n", pid) == 0) 			{			syslog(LOG_ERR, "Bandwidthd: failed to write '%d' to /var/run/bandwidthd.pid", pid);			fclose(pidfile);			unlink("/var/run/bandwidthd.pid");			}		else			fclose(pidfile);				}	else		syslog(LOG_ERR, "Could not open /var/run/bandwidthd.pid for write");	}int main(int argc, char **argv)    {    struct bpf_program fcode;    u_char *pcap_userdata = 0;#ifdef HAVE_PCAP_FINDALLDEVS	pcap_if_t *Devices;#endif	char Error[PCAP_ERRBUF_SIZE];	struct stat StatBuf;	int i;	int ForkBackground = TRUE;	int ListDevices = FALSE;	int Counter;	config.dev = NULL;	config.filter = "ip";	config.skip_intervals = CONFIG_GRAPHINTERVALS;	config.graph_cutoff = CONFIG_GRAPHCUTOFF;	config.promisc = TRUE;	config.graph = TRUE;	config.output_cdf = FALSE;	config.recover_cdf = FALSE;	config.meta_refresh = CONFIG_METAREFRESH;	config.output_database = FALSE;	config.db_connect_string = NULL;	config.sensor_id = "unset";  	openlog("bandwidthd", LOG_CONS, LOG_DAEMON);	if (stat("./etc/bandwidthd.conf", &StatBuf))		{		chdir(INSTALL_DIR);		if (stat("./etc/bandwidthd.conf", &StatBuf))			{			printf("Cannot find ./etc/bandwidthd.conf or %s/etc/bandwidthd.conf\n", INSTALL_DIR);			syslog(LOG_ERR, "Cannot find ./etc/bandwidthd.conf or %s/etc/bandwidthd.conf", INSTALL_DIR);			exit(1);			}		}	bdconfig_in = fopen("./etc/bandwidthd.conf", "rt");	if (!bdconfig_in)		{		syslog(LOG_ERR, "Cannot open bandwidthd.conf");		printf("Cannot open ./etc/bandwidthd.conf\n");		exit(1);		}	bdconfig_parse();	/*	// Scary	printf("Estimated max ram utilization\nDataPoints = %.0f/%ld = %.0f\nIPData = %d * DataPoints = %.1f (%.2fKBytes) per IP\nIP_NUM = %d\nTotal = %.1fMBytes * 4 to 8 = %.1fMBytes to %.1fMBytes\n", 		RANGE1, INTERVAL1, RANGE1/INTERVAL1,				sizeof(struct IPData), 		(float) sizeof(struct IPData)*(RANGE1/INTERVAL1), 		(float) (sizeof(struct IPData)*(RANGE1/INTERVAL1))/1024.0,		IP_NUM, 		(float)((sizeof(struct IPData)*(RANGE1/INTERVAL1)*IP_NUM)/1024.0)/1024.0,		(float)4*((sizeof(struct IPData)*(RANGE1/INTERVAL1)*IP_NUM)/1024.0)/1024.0,		(float)8*((sizeof(struct IPData)*(RANGE1/INTERVAL1)*IP_NUM)/1024.0)/1024.0);	printf("Sizeof unsigned long: %d, sizeof unsigned long long: %d\n%lu, %llu\n",		sizeof(unsigned long), sizeof (unsigned long long),		(unsigned long) (0-1), (unsigned long long) (0-1));		exit(1);	*/	for(Counter = 1; Counter < argc; Counter++)		{		if (argv[Counter][0] == '-')			{			switch(argv[Counter][1])				{				case 'D':					ForkBackground = FALSE;					break;				case 'l':					ListDevices = TRUE; 			 		break;				default:					printf("Improper argument: %s\n", argv[Counter]);					exit(1);				}			}		}#ifdef HAVE_PCAP_FINDALLDEVS	pcap_findalldevs(&Devices, Error);	if (config.dev == NULL && Devices->name)		config.dev = strdup(Devices->name);	if (ListDevices)		{			while(Devices)			{			printf("Description: %s\nName: \"%s\"\n\n", Devices->description, Devices->name);			Devices = Devices->next;			}		exit(0);		}#else	if (ListDevices)		{		printf("List devices is not supported by you version of libpcap\n");		exit(0);		}#endif		if (config.graph)		{		bd_CollectingData("htdocs/index.html");		bd_CollectingData("htdocs/index2.html");		bd_CollectingData("htdocs/index3.html");		bd_CollectingData("htdocs/index4.html");		}	/* detach from console. */	if (ForkBackground)		if (fork2())			exit(0);	makepidfile(getpid());	setchildconfig(0); /* initialize first (day graphing) process config */	if (config.graph || config.output_cdf)		{		/* fork processes for week, month and year graphing. */		for (i=0; i<NR_WORKER_CHILDS; i++) 			{			workerchildpids[i] = fork();			/* initialize children and let them start doing work,			 * while parent continues to fork children.			 */			if (workerchildpids[i] == 0) 				{ /* child */				setchildconfig(i+1);				break;				}			if (workerchildpids[i] == -1) 				{ /* fork failed */				syslog(LOG_ERR, "Failed to fork graphing child (%d)", i);				/* i--; ..to retry? -> possible infinite loop */				continue;				}			}	    if(config.recover_cdf)		    RecoverDataFromCDF();		}	    IntervalStart = time(NULL);	syslog(LOG_INFO, "Opening %s", config.dev);		pd = pcap_open_live(config.dev, 100, config.promisc, 1000, Error);        if (pd == NULL) 			{			syslog(LOG_ERR, "%s", Error);			exit(0);			}    if (pcap_compile(pd, &fcode, config.filter, 1, 0) < 0)		{        pcap_perror(pd, "Error");		printf("Malformed libpcap filter string in bandwidthd.conf\n");		syslog(LOG_ERR, "Malformed libpcap filter string in bandwidthd.conf");		exit(1);		}    if (pcap_setfilter(pd, &fcode) < 0)        pcap_perror(pd, "Error");	switch (DataLink = pcap_datalink(pd))		{		default:			if (config.dev)				printf("Unknown Datalink Type %d, defaulting to ethernet\nPlease forward this error message and a packet sample (captured with \"tcpdump -i %s -s 2000 -n -w capture.cap\") to hinkle@derbyworks.com\n", DataLink, config.dev);			else				printf("Unknown Datalink Type %d, defaulting to ethernet\nPlease forward this error message and a packet sample (captured with \"tcpdump -s 2000 -n -w capture.cap\") to hinkle@derbyworks.com\n", DataLink);			syslog(LOG_INFO, "Unkown datalink type, defaulting to ethernet");		case DLT_EN10MB:			syslog(LOG_INFO, "Packet Encoding: Ethernet");			IP_Offset = 14; //IP_Offset = sizeof(struct ether_header);			break;	#ifdef DLT_LINUX_SLL 		case DLT_LINUX_SLL:			syslog(LOG_INFO, "Packet Encoding: Linux Cooked Socket");			IP_Offset = 16;			break;#endif#ifdef DLT_RAW		case DLT_RAW:			printf("Untested Datalink Type %d\nPlease report to hinkle@derbyworks.net if bandwidthd works for you\non this interface\n", DataLink);			printf("Packet Encoding:\n\tRaw\n");			syslog(LOG_INFO, "Untested packet encoding: Raw");			IP_Offset = 0;			break;#endif		case DLT_IEEE802:			printf("Untested Datalink Type %d\nPlease report to hinkle@derbyworks.net if bandwidthd works for you\non this interface\n", DataLink);			printf("Packet Encoding:\nToken Ring\n");			syslog(LOG_INFO, "Untested packet encoding: Token Ring");

⌨️ 快捷键说明

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