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

📄 bandwidthd.c

📁 linux下流量查看软件,可以查看到每台机子的具体流量
💻 C
📖 第 1 页 / 共 3 页
字号:
			IP_Offset = 22;			break;		}	if (ForkBackground)		{                                           		fclose(stdin);		fclose(stdout);		fclose(stderr);		}	signal(SIGHUP, signal_handler);	signal(SIGTERM, signal_handler);	if (IPDataStore)  // If there is data in the datastore draw some initial graphs		{		syslog(LOG_INFO, "Drawing initial graphs");		WriteOutWebpages(IntervalStart+config.interval);		}    if (pcap_loop(pd, -1, PacketCallback, pcap_userdata) < 0) {        syslog(LOG_ERR, "Bandwidthd: pcap_loop: %s",  pcap_geterr(pd));        exit(1);        }    pcap_close(pd);    exit(0);            }   void PacketCallback(u_char *user, const struct pcap_pkthdr *h, const u_char *p)    {    unsigned int counter;    u_int caplen = h->caplen;    const struct ip *ip;    uint32_t srcip;    uint32_t dstip;    struct IPData *ptrIPData;    if (h->ts.tv_sec > IntervalStart + config.interval)  // Then write out this intervals data and possibly kick off the grapher        {        GraphIntervalCount++;        CommitData(IntervalStart+config.interval);		IpCount = 0;        IntervalStart=h->ts.tv_sec;        }    caplen -= IP_Offset;  // We're only measuring ip size, so pull off the ethernet header    p += IP_Offset; // Move the pointer past the datalink header    ip = (const struct ip *)p; // Point ip at the ip header	if (ip->ip_v != 4) // then not an ip packet so skip it		return;    srcip = ntohl(*(uint32_t *) (&ip->ip_src));    dstip = ntohl(*(uint32_t *) (&ip->ip_dst));	    for (counter = 0; counter < SubnetCount; counter++)        {	 		// Packets from a monitored subnet to a monitored subnet will be		// credited to both ip's        if (SubnetTable[counter].ip == (srcip & SubnetTable[counter].mask))            {            ptrIPData = FindIp(srcip);  // Return or create this ip's data structure			if (ptrIPData)	            Credit(&(ptrIPData->Send), ip);            ptrIPData = FindIp(0);  // Totals			if (ptrIPData)	            Credit(&(ptrIPData->Send), ip);            }            if (SubnetTable[counter].ip == (dstip & SubnetTable[counter].mask))            {            ptrIPData = FindIp(dstip);    		if (ptrIPData)		        Credit(&(ptrIPData->Receive), ip);            ptrIPData = FindIp(0);    		if (ptrIPData)		        Credit(&(ptrIPData->Receive), ip);            }                                }    }inline void Credit(struct Statistics *Stats, const struct ip *ip)    {    unsigned long size;    const struct tcphdr *tcp;    uint16_t sport, dport;    size = ntohs(ip->ip_len);    Stats->total += size;        switch(ip->ip_p)        {        case 6:     // TCP            tcp = (struct tcphdr *)(ip+1);			tcp = (struct tcphdr *) ( ((char *)tcp) + ((ip->ip_hl-5)*4) ); // Compensate for IP Options            Stats->tcp += size;            sport = ntohs(tcp->TCPHDR_SPORT);            dport = ntohs(tcp->TCPHDR_DPORT);			            if (sport == 80 || dport == 80 || sport == 443 || dport == 443)                Stats->http += size;				if (sport == 20 || dport == 20 || sport == 21 || dport == 21)				Stats->ftp += size;            if (sport == 1044|| dport == 1044||		// Direct File Express				sport == 1045|| dport == 1045|| 	// ''  <- Dito Marks                sport == 1214|| dport == 1214||		// Grokster, Kaza, Morpheus				sport == 4661|| dport == 4661||		// EDonkey 2000				sport == 4662|| dport == 4662||     // ''				sport == 4665|| dport == 4665||     // ''				sport == 5190|| dport == 5190||		// Song Spy				sport == 5500|| dport == 5500||		// Hotline Connect				sport == 5501|| dport == 5501||		// ''				sport == 5502|| dport == 5502||		// ''				sport == 5503|| dport == 5503||		// ''				sport == 6346|| dport == 6346||		// Gnutella Engine				sport == 6347|| dport == 6347||		// ''				sport == 6666|| dport == 6666||		// Yoink				sport == 6667|| dport == 6667||		// ''				sport == 7788|| dport == 7788||		// Budy Share				sport == 8888|| dport == 8888||		// AudioGnome, OpenNap, Swaptor				sport == 8889|| dport == 8889||		// AudioGnome, OpenNap				sport == 28864|| dport == 28864||	// hotComm								sport == 28865|| dport == 28865)	// hotComm                Stats->p2p += size;            break;        case 17:            Stats->udp += size;            break;        case 1:             Stats->icmp += size;            break;        }    }// TODO:  Throw away old data!void DropOldData(long int timestamp) 	// Go through the ram datastore and dump old data	{	struct IPDataStore *DataStore;	struct IPDataStore *PrevDataStore;		struct DataStoreBlock *DeletedBlock;		PrevDataStore = NULL;    DataStore = IPDataStore;	// Progress through the linked list until we reach the end	while(DataStore)  // we have data		{		// If the First block is out of date, purge it, if it is the only block		// purge the node        while(DataStore->FirstBlock->LatestTimestamp < timestamp - config.range)			{            if ((!DataStore->FirstBlock->Next) && PrevDataStore) // There is no valid block of data for this ip, so unlink the whole ip				{ 												// Don't bother unlinking the ip if it's the first one, that's to much																// Trouble				PrevDataStore->Next = DataStore->Next;	// Unlink the node				free(DataStore->FirstBlock->Data);      // Free the memory				free(DataStore->FirstBlock);				free(DataStore);																DataStore = PrevDataStore->Next;	// Go to the next node				if (!DataStore) return; // We're done				}							else if (!DataStore->FirstBlock->Next)				{				// There is no valid block of data for this ip, and we are 				// the first ip, so do nothing 				break; // break out of this loop so the outside loop increments us				} 			else // Just unlink this block				{				DeletedBlock = DataStore->FirstBlock;				DataStore->FirstBlock = DataStore->FirstBlock->Next;	// Unlink the block				free(DeletedBlock->Data);				free(DeletedBlock);			    }			}		PrevDataStore = DataStore;						DataStore = DataStore->Next;		}	}void StoreIPDataInPostgresql(struct IPData IncData[])	{#ifdef HAVE_LIBPQ	struct IPData *IPData;	unsigned int counter;	struct Statistics *Stats;    PGresult   *res;	static PGconn *conn = NULL;	static char sensor_id[50];	const char *paramValues[10];	char *sql1; 	char *sql2;	char Values[10][50];	if (!config.output_database == DB_PGSQL)		return;	paramValues[0] = Values[0];	paramValues[1] = Values[1];	paramValues[2] = Values[2];	paramValues[3] = Values[3];		paramValues[4] = Values[4];	paramValues[5] = Values[5];	paramValues[6] = Values[6];	paramValues[7] = Values[7];	paramValues[8] = Values[8];	paramValues[9] = Values[9];	// ************ Inititialize the db if it's not already	if (!conn)		{		/* Connect to the database */    	conn = PQconnectdb(config.db_connect_string);	    /* Check to see that the backend connection was successfully made */    	if (PQstatus(conn) != CONNECTION_OK)        	{	       	syslog(LOG_ERR, "Connection to database '%s' failed: %s", config.db_connect_string, PQerrorMessage(conn));    	    PQfinish(conn);        	conn = NULL;	        return;    	    }		strncpy(Values[0], config.sensor_id, 50);		res = PQexecParams(conn, "select sensor_id from sensors where sensor_name = $1;",			1,       /* one param */            NULL,    /* let the backend deduce param type */   	        paramValues,       	    NULL,    /* don't need param lengths since text */           	NULL,    /* default to all text params */            0);      /* ask for binary results */		   		if (PQresultStatus(res) != PGRES_TUPLES_OK)       		{        	syslog(LOG_ERR, "Postresql SELECT failed: %s", PQerrorMessage(conn));    	    PQclear(res);   	    	PQfinish(conn);    	    conn = NULL;       		return;	        }		if (PQntuples(res))			{			strncpy(sensor_id, PQgetvalue(res, 0, 0), 50);			PQclear(res);			}		else			{			// Insert new sensor id			PQclear(res);			res = PQexecParams(conn, "insert into sensors (sensor_name, last_connection) VALUES ($1, now());",				1,       /* one param */    	        NULL,    /* let the backend deduce param type */   	    	    paramValues,       	    	NULL,    /* don't need param lengths since text */				NULL,    /* default to all text params */            	0);      /* ask for binary results */    		if (PQresultStatus(res) != PGRES_COMMAND_OK)        		{	        	syslog(LOG_ERR, "Postresql INSERT failed: %s", PQerrorMessage(conn));	    	    PQclear(res);    	    	PQfinish(conn);	    	    conn = NULL;        		return;		        }			PQclear(res);			res = PQexecParams(conn, "select sensor_id from sensors where sensor_name = $1;",				1,       /* one param */        	    NULL,    /* let the backend deduce param type */   	        	paramValues,	       	    NULL,    /* don't need param lengths since text */    	       	NULL,    /* default to all text params */        	    0);      /* ask for binary results */			   		if (PQresultStatus(res) != PGRES_TUPLES_OK)    	   		{        		syslog(LOG_ERR, "Postresql SELECT failed: %s", PQerrorMessage(conn));    	    	PQclear(res);	   	    	PQfinish(conn);    		    conn = NULL;       			return;	        	}			strncpy(sensor_id, PQgetvalue(res, 0, 0), 50);			PQclear(res);			}			}	// Begin transaction	// **** Perform inserts	res = PQexecParams(conn, "BEGIN;",			0,       /* zero param */    	    NULL,    /* let the backend deduce param type */   	    	NULL,	    	NULL,    /* don't need param lengths since text */			NULL,    /* default to all text params */       		0);      /* ask for binary results */ 	if (PQresultStatus(res) != PGRES_COMMAND_OK)    	{	    syslog(LOG_ERR, "Postresql BEGIN failed: %s", PQerrorMessage(conn));	    PQclear(res);    	PQfinish(conn);	    conn = NULL;        return;		}								PQclear(res);	strncpy(Values[0], sensor_id, 50);	res = PQexecParams(conn, "update sensors set last_connection = now() where sensor_id = $1;",			1,       /* one param */    	    NULL,    /* let the backend deduce param type */   	    	paramValues,	    	NULL,    /* don't need param lengths since text */			NULL,    /* default to all text params */       		0);      /* ask for binary results */ 	if (PQresultStatus(res) != PGRES_COMMAND_OK)    	{	    syslog(LOG_ERR, "Postresql UPDATE failed: %s", PQerrorMessage(conn));	    PQclear(res);    	PQfinish(conn);	    conn = NULL;        return;		}								PQclear(res);	Values[0][49] = '\0';	snprintf(Values[1], 50, "%llu", config.interval);	for (counter=0; counter < IpCount; counter++)		{        IPData = &IncData[counter];		if (IPData->ip == 0)			{			// This optimization allows us to quickly draw totals graphs for a sensor			sql1 = "INSERT INTO bd_tx_total_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);";			sql2 = "INSERT INTO bd_rx_total_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);";			}		else			{			sql1 = "INSERT INTO bd_tx_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);";			sql2 = "INSERT INTO bd_rx_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);"; 			}        HostIp2CharIp(IPData->ip, Values[2]);		Stats = &(IPData->Send);		if (Stats->total > 512) // Don't log empty sets			{			// Log data in kilobytes			snprintf(Values[3], 50, "%llu", (long long unsigned int)((((double)Stats->total)/1024.0) + 0.5));			snprintf(Values[4], 50, "%llu", (long long unsigned int)((((double)Stats->icmp)/1024.0) + 0.5));			snprintf(Values[5], 50, "%llu", (long long unsigned int)((((double)Stats->udp)/1024.0) + 0.5));			snprintf(Values[6], 50, "%llu", (long long unsigned int)((((double)Stats->tcp)/1024.0) + 0.5));			snprintf(Values[7], 50, "%llu", (long long unsigned int)((((double)Stats->ftp)/1024.0) + 0.5));			snprintf(Values[8], 50, "%llu", (long long unsigned int)((((double)Stats->http)/1024.0) + 0.5));			snprintf(Values[9], 50, "%llu", (long long unsigned int)((((double)Stats->p2p)/1024.0) + 0.5));			res = PQexecParams(conn, sql1,				10,       /* nine param */	            NULL,    /* let the backend deduce param type */    	        paramValues,        	    NULL,    /* don't need param lengths since text */            	NULL,    /* default to all text params */	            1);      /* ask for binary results */    		if (PQresultStatus(res) != PGRES_COMMAND_OK)        		{	        	syslog(LOG_ERR, "Postresql INSERT failed: %s", PQerrorMessage(conn));	    	    PQclear(res);    	    	PQfinish(conn);	    	    conn = NULL;        		return;		        }			PQclear(res);			}		Stats = &(IPData->Receive);		if (Stats->total > 512) // Don't log empty sets			{			snprintf(Values[3], 50, "%llu", (long long unsigned int)((((double)Stats->total)/1024.0) + 0.5));			snprintf(Values[4], 50, "%llu", (long long unsigned int)((((double)Stats->icmp)/1024.0) + 0.5));			snprintf(Values[5], 50, "%llu", (long long unsigned int)((((double)Stats->udp)/1024.0) + 0.5));			snprintf(Values[6], 50, "%llu", (long long unsigned int)((((double)Stats->tcp)/1024.0) + 0.5));			snprintf(Values[7], 50, "%llu", (long long unsigned int)((((double)Stats->ftp)/1024.0) + 0.5));			snprintf(Values[8], 50, "%llu", (long long unsigned int)((((double)Stats->http)/1024.0) + 0.5));			snprintf(Values[9], 50, "%llu", (long long unsigned int)((((double)Stats->p2p)/1024.0) + 0.5));			res = PQexecParams(conn, sql2,				10,       /* seven param */            	NULL,    /* let the backend deduce param type */	            paramValues,    	        NULL,    /* don't need param lengths since text */        	    NULL,    /* default to all text params */            	1);      /* ask for binary results */	    	if (PQresultStatus(res) != PGRES_COMMAND_OK)    	    	{	    	    syslog(LOG_ERR, "Postresql INSERT failed: %s", PQerrorMessage(conn));    	    	PQclear(res);	        	PQfinish(conn);		        conn = NULL;        		return;	        	}			PQclear(res);			}				}	// Commit transaction	res = PQexecParams(conn, "COMMIT;",			0,       /* zero param */    	    NULL,    /* let the backend deduce param type */   	    	NULL,	    	NULL,    /* don't need param lengths since text */			NULL,    /* default to all text params */       		0);      /* ask for binary results */ 	if (PQresultStatus(res) != PGRES_COMMAND_OK)

⌨️ 快捷键说明

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