/[smecontribs]/rpms/bandwidthd/contribs10/bandwidthd-mysql.patch
ViewVC logotype

Annotation of /rpms/bandwidthd/contribs10/bandwidthd-mysql.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Oct 21 11:20:48 2020 UTC (4 years ago) by brianr
Branch: MAIN
CVS Tags: bandwidthd-2_0_1_1-9_el7_sme, bandwidthd-2_0_1_1-7_el7_sme, bandwidthd-2_0_1_1-5_el7_sme, bandwidthd-2_0_1_1-8_el7_sme, bandwidthd-2_0_1_1-6_el7_sme, HEAD
Initial import

1 brianr 1.1 diff -ruN bandwidthd/bandwidthd.c bandwidthd-mysql-20050912/bandwidthd.c
2     --- bandwidthd/bandwidthd.c 2005-09-23 16:08:12.000000000 +0200
3     +++ bandwidthd-mysql-20050912/bandwidthd.c 2005-08-31 02:20:59.000000000 +0200
4     @@ -4,6 +4,11 @@
5     #include <libpq-fe.h>
6     #endif
7    
8     +#ifdef HAVE_LIBMYSQLCLIENT
9     +#include <mysql.h>
10     +#include <errmsg.h>
11     +#endif
12     +
13     // We must call regular exit to write out profile data, but child forks are supposed to usually
14     // call _exit?
15     #ifdef PROFILE
16     @@ -261,6 +266,7 @@
17     int Counter;
18     char *bd_conf = NULL;
19     struct in_addr addr, addr2;
20     + char *tmp;
21    
22     signal(SIGHUP, SIG_IGN);
23     signal(SIGTERM, SIG_IGN);
24     @@ -303,11 +309,16 @@
25     config.output_cdf = FALSE;
26     config.recover_cdf = FALSE;
27     config.meta_refresh = CONFIG_METAREFRESH;
28     - config.output_database = FALSE;
29     - config.db_connect_string = NULL;
30     + config.output_database = DB_NONE;
31     + config.pgsql_connect_string = NULL;
32     config.sensor_id = "unset";
33     config.log_dir = LOG_DIR;
34     config.htdocs_dir = HTDOCS_DIR;
35     + config.mysql_host = NULL;
36     + config.mysql_user = NULL;
37     + config.mysql_pass = NULL;
38     + config.mysql_dbname = NULL;
39     + config.mysql_port = 0;
40    
41     openlog("bandwidthd", LOG_CONS, LOG_DAEMON);
42    
43     @@ -350,7 +361,9 @@
44     {
45     addr.s_addr = ntohl(SubnetTable[Counter].ip);
46     addr2.s_addr = ntohl(SubnetTable[Counter].mask);
47     - syslog(LOG_INFO, "Monitoring subnet %s with netmask %s", inet_ntoa(addr), inet_ntoa(addr2));
48     + tmp = strdup(inet_ntoa(addr));
49     + syslog(LOG_INFO, "Monitoring subnet %s with netmask %s", tmp, inet_ntoa(addr2));
50     + free(tmp);
51     }
52    
53     #ifdef HAVE_PCAP_FINDALLDEVS
54     @@ -679,7 +692,7 @@
55     while(DataStore->FirstBlock->LatestTimestamp < timestamp - config.range)
56     {
57     if ((!DataStore->FirstBlock->Next) && PrevDataStore) // There is no valid block of data for this ip, so unlink the whole ip
58     - { // Don't bother unlinking the ip if it's the first one, that's to much
59     + { // Don't bother unlinking the ip if it's the first one, that's too much
60     // Trouble
61     PrevDataStore->Next = DataStore->Next; // Unlink the node
62     free(DataStore->FirstBlock->Data); // Free the memory
63     @@ -747,7 +760,7 @@
64     }
65     PQclear(res);
66    
67     - res = PQexec(conn, "CREATE TABLE bd_rx_total_log (sensor_id int, ip inet, timestamp timestamp with time zone DEFAULT now(), sample_duration int, total int, icmp int, udp int, tcp int, ftp int, http int, p2p int); create index bd_rx_total_log_sensor_id_timestamp_ip_idx on bd_rx_total_log (sensor_id, timestamp);");
68     + res = PQexec(conn, "CREATE TABLE bd_rx_total_log (sensor_id int, ip inet, timestamp timestamp with time zone DEFAULT now(), sample_duration int, total int, icmp int, udp int, tcp int, ftp int, http int, p2p int); create index bd_rx_total_log_sensor_id_timestamp_idx on bd_rx_total_log (sensor_id, timestamp);");
69     if (PQresultStatus(res) != PGRES_COMMAND_OK)
70     {
71     syslog(LOG_ERR, "Postresql create table failed: %s", PQerrorMessage(conn));
72     @@ -757,7 +770,7 @@
73     }
74     PQclear(res);
75    
76     - res = PQexec(conn, "CREATE TABLE bd_tx_total_log (sensor_id int, ip inet, timestamp timestamp with time zone DEFAULT now(), sample_duration int, total int, icmp int, udp int, tcp int, ftp int, http int, p2p int); create index bd_tx_total_log_sensor_id_timestamp_ip_idx on bd_tx_total_log (sensor_id, timestamp);");
77     + res = PQexec(conn, "CREATE TABLE bd_tx_total_log (sensor_id int, ip inet, timestamp timestamp with time zone DEFAULT now(), sample_duration int, total int, icmp int, udp int, tcp int, ftp int, http int, p2p int); create index bd_tx_total_log_sensor_id_timestamp_idx on bd_tx_total_log (sensor_id, timestamp);");
78     if (PQresultStatus(res) != PGRES_COMMAND_OK)
79     {
80     syslog(LOG_ERR, "Postresql create table failed: %s", PQerrorMessage(conn));
81     @@ -812,16 +825,16 @@
82     paramValues[8] = Values[8];
83     paramValues[9] = Values[9];
84    
85     - // ************ Inititialize the db if it's not already
86     + // ************ Initialize the db if it's not already
87     if (!conn)
88     {
89     /* Connect to the database */
90     - conn = PQconnectdb(config.db_connect_string);
91     + conn = PQconnectdb(config.pgsql_connect_string);
92    
93     /* Check to see that the backend connection was successfully made */
94     if (PQstatus(conn) != CONNECTION_OK)
95     {
96     - syslog(LOG_ERR, "Connection to database '%s' failed: %s", config.db_connect_string, PQerrorMessage(conn));
97     + syslog(LOG_ERR, "Connection to database '%s' failed: %s", config.pgsql_connect_string, PQerrorMessage(conn));
98     PQfinish(conn);
99     conn = NULL;
100     return;
101     @@ -1036,10 +1049,515 @@
102     #endif
103     }
104    
105     +#ifdef HAVE_LIBMYSQLCLIENT
106     +
107     +MYSQL *CheckMysqlTables(MYSQL *conn)
108     +{
109     + MYSQL_RES *res;
110     + int ret;
111     +
112     + ret = mysql_query(conn, "SHOW TABLES LIKE 'sensors'");
113     + if (ret) {
114     + syslog(LOG_ERR, "MySQL SHOW TABLES failed: %s", mysql_error(conn));
115     + mysql_close(conn);
116     + return(NULL);
117     + }
118     +
119     + res = mysql_store_result(conn);
120     + if (!res) {
121     + syslog(LOG_ERR, "MySQL store_result failed: %s", mysql_error(conn));
122     + mysql_close(conn);
123     + return(NULL);
124     + }
125     +
126     + if (mysql_num_rows(res) != 1) {
127     + mysql_free_result(res);
128     +
129     + ret = mysql_query(conn, "CREATE TABLE bd_rx_log (sensor_id INT, ip INT UNSIGNED, timestamp TIMESTAMP, sample_duration INT, total INT, icmp INT, udp INT, tcp INT, ftp INT, http INT, p2p INT, INDEX bd_rx_log_sensors_id_ip_timestamp_idx (sensor_id, ip, timestamp), INDEX bd_rx_log_sensor_id_timestamp_idx (sensor_id, timestamp)) TYPE=innodb");
130     + if (ret) {
131     + syslog(LOG_ERR, "MySQL CREATE TABLE failed: %s", mysql_error(conn));
132     + mysql_close(conn);
133     + return(NULL);
134     + }
135     +
136     + ret = mysql_query(conn, "CREATE TABLE bd_tx_log (sensor_id INT, ip INT UNSIGNED, timestamp TIMESTAMP, sample_duration INT, total INT, icmp INT, udp INT, tcp INT, ftp INT, http INT, p2p INT, INDEX bd_tx_log_sensors_id_ip_timestamp_idx (sensor_id, ip, timestamp), INDEX bd_tx_log_sensor_id_timestamp_idx (sensor_id, timestamp)) TYPE=innodb");
137     + if (ret) {
138     + syslog(LOG_ERR, "MySQL CREATE TABLE failed: %s", mysql_error(conn));
139     + mysql_close(conn);
140     + return(NULL);
141     + }
142     +
143     + ret = mysql_query(conn, "CREATE TABLE bd_rx_total_log (sensor_id INT, ip INT UNSIGNED, timestamp TIMESTAMP, sample_duration INT, total INT, icmp INT, udp INT, tcp INT, ftp INT, http INT, p2p INT, INDEX bd_rx_total_log_sensors_id_timestamp_idx (sensor_id, timestamp)) TYPE=innodb");
144     + if (ret) {
145     + syslog(LOG_ERR, "MySQL CREATE TABLE failed: %s", mysql_error(conn));
146     + mysql_close(conn);
147     + return(NULL);
148     + }
149     +
150     + ret = mysql_query(conn, "CREATE TABLE bd_tx_total_log (sensor_id INT, ip INT UNSIGNED, timestamp TIMESTAMP, sample_duration INT, total INT, icmp INT, udp INT, tcp INT, ftp INT, http INT, p2p INT, INDEX bd_tx_total_log_sensors_id_timestamp_idx (sensor_id, timestamp)) TYPE=innodb");
151     + if (ret) {
152     + syslog(LOG_ERR, "MySQL CREATE TABLE failed: %s", mysql_error(conn));
153     + mysql_close(conn);
154     + return(NULL);
155     + }
156     +
157     + ret = mysql_query(conn, "CREATE TABLE sensors (sensor_id INT PRIMARY KEY AUTO_INCREMENT, sensor_name VARCHAR(255) UNIQUE NOT NULL, last_connection TIMESTAMP) TYPE=innodb");
158     + if (ret) {
159     + syslog(LOG_ERR, "MySQL CREATE TABLE failed: %s", mysql_error(conn));
160     + mysql_close(conn);
161     + return(NULL);
162     + }
163     + }
164     + else
165     + mysql_free_result(res);
166     +
167     + return(conn);
168     +}
169     +
170     +// MySQL prepared statements queries
171     +#define MYSQL_TX_TOTAL "INSERT INTO bd_tx_total_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES(?, ?, 0, ?, ?, ?, ?, ?, ?, ?)"
172     +#define MYSQL_TX "INSERT INTO bd_tx_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
173     +#define MYSQL_RX_TOTAL "INSERT INTO bd_rx_total_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES(?, ?, 0, ?, ?, ?, ?, ?, ?, ?)"
174     +#define MYSQL_RX "INSERT INTO bd_rx_log (sensor_id, sample_duration, ip, total, icmp, udp, tcp, ftp, http, p2p) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
175     +
176     +void MysqlStmtsClose(MYSQL_STMT **stmts)
177     +{
178     + mysql_stmt_close(stmts[0]);
179     + mysql_stmt_close(stmts[1]);
180     + mysql_stmt_close(stmts[2]);
181     + mysql_stmt_close(stmts[3]);
182     +}
183     +
184     +MYSQL *MysqlStmtsInit(MYSQL *conn, MYSQL_STMT **stmts,
185     + unsigned long long *data, my_ulonglong *sensor_id, uint32_t *ip)
186     +{
187     + unsigned int Counter;
188     + MYSQL_BIND binds[10];
189     +
190     + stmts[0] = mysql_stmt_init(conn);
191     + if(!stmts[0]) {
192     + syslog(LOG_ERR, "MySQL stmt_init failed: %s", mysql_error(conn));
193     + mysql_close(conn);
194     + return NULL;
195     + }
196     +
197     + stmts[1] = mysql_stmt_init(conn);
198     + if(!stmts[1]) {
199     + syslog(LOG_ERR, "MySQL stmt_init failed: %s", mysql_error(conn));
200     + mysql_stmt_close(stmts[0]);
201     + mysql_close(conn);
202     + return NULL;
203     + }
204     +
205     + stmts[2] = mysql_stmt_init(conn);
206     + if(!stmts[2]) {
207     + syslog(LOG_ERR, "MySQL stmt_init failed: %s", mysql_error(conn));
208     + mysql_stmt_close(stmts[0]);
209     + mysql_stmt_close(stmts[1]);
210     + mysql_close(conn);
211     + return NULL;
212     + }
213     +
214     + stmts[3] = mysql_stmt_init(conn);
215     + if(!stmts[3]) {
216     + syslog(LOG_ERR, "MySQL stmt_init failed: %s", mysql_error(conn));
217     + mysql_stmt_close(stmts[0]);
218     + mysql_stmt_close(stmts[1]);
219     + mysql_stmt_close(stmts[2]);
220     + mysql_close(conn);
221     + return NULL;
222     + }
223     +
224     + if(mysql_stmt_prepare(stmts[0], MYSQL_TX_TOTAL, strlen(MYSQL_TX_TOTAL))) {
225     + syslog(LOG_ERR, "MySQL stmt_prepare failed: %s", mysql_stmt_error(stmts[0]));
226     + MysqlStmtsClose(stmts);
227     + mysql_close(conn);
228     + return NULL;
229     + }
230     +
231     + if(mysql_stmt_prepare(stmts[1], MYSQL_TX, strlen(MYSQL_TX))) {
232     + syslog(LOG_ERR, "MySQL stmt_prepare failed: %s", mysql_stmt_error(stmts[1]));
233     + MysqlStmtsClose(stmts);
234     + mysql_close(conn);
235     + return NULL;
236     + }
237     +
238     + if(mysql_stmt_prepare(stmts[2], MYSQL_RX_TOTAL, strlen(MYSQL_RX_TOTAL))) {
239     + syslog(LOG_ERR, "MySQL stmt_prepare failed: %s", mysql_stmt_error(stmts[2]));
240     + MysqlStmtsClose(stmts);
241     + mysql_close(conn);
242     + return NULL;
243     + }
244     +
245     + if(mysql_stmt_prepare(stmts[3], MYSQL_RX, strlen(MYSQL_RX))) {
246     + syslog(LOG_ERR, "MySQL stmt_prepare failed: %s", mysql_stmt_error(stmts[3]));
247     + MysqlStmtsClose(stmts);
248     + mysql_close(conn);
249     + return NULL;
250     + }
251     +
252     + memset(binds, 0, sizeof(binds));
253     +
254     + // sensor_id
255     + binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
256     + binds[0].buffer = sensor_id;
257     + binds[0].is_unsigned = TRUE;
258     +
259     + // sample_duration
260     + binds[1].buffer_type = MYSQL_TYPE_LONGLONG;
261     + binds[1].buffer = &config.interval;
262     + binds[1].is_unsigned = TRUE;
263     +
264     + // statistics
265     + for(Counter = 2; Counter < 9; Counter++) {
266     + binds[Counter].buffer_type = MYSQL_TYPE_LONGLONG;
267     + binds[Counter].buffer = &data[Counter-2];
268     + binds[Counter].is_unsigned = TRUE;
269     + }
270     +
271     + if(mysql_stmt_bind_param(stmts[0], binds)) {
272     + syslog(LOG_ERR, "MySQL bind_param failed: %s", mysql_stmt_error(stmts[0]));
273     + MysqlStmtsClose(stmts);
274     + mysql_close(conn);
275     + return NULL;
276     + }
277     +
278     + if(mysql_stmt_bind_param(stmts[2], binds)) {
279     + syslog(LOG_ERR, "MySQL bind_param failed: %s", mysql_stmt_error(stmts[2]));
280     + MysqlStmtsClose(stmts);
281     + mysql_close(conn);
282     + return NULL;
283     + }
284     +
285     + // ip
286     + binds[2].buffer_type = MYSQL_TYPE_LONG;
287     + binds[2].buffer = ip;
288     + binds[2].is_unsigned = TRUE;
289     +
290     + for(Counter = 3; Counter < 10; Counter++) {
291     + binds[Counter].buffer_type = MYSQL_TYPE_LONGLONG;
292     + binds[Counter].buffer = &data[Counter-3];
293     + binds[Counter].is_unsigned = TRUE;
294     + }
295     +
296     + if(mysql_stmt_bind_param(stmts[1], binds)) {
297     + syslog(LOG_ERR, "MySQL bind_param failed: %s", mysql_stmt_error(stmts[1]));
298     + MysqlStmtsClose(stmts);
299     + mysql_close(conn);
300     + return NULL;
301     + }
302     +
303     + if(mysql_stmt_bind_param(stmts[3], binds)) {
304     + syslog(LOG_ERR, "MySQL bind_param failed: %s", mysql_stmt_error(stmts[3]));
305     + MysqlStmtsClose(stmts);
306     + mysql_close(conn);
307     + return NULL;
308     + }
309     +
310     + return conn;
311     +}
312     +
313     +#endif // HAVE_LIBMYSQLCLIENT
314     +
315     +void StoreIPDataInMysql(struct IPData IncData[])
316     +{
317     +#ifdef HAVE_LIBMYSQLCLIENT
318     + struct IPData *IPData;
319     + unsigned int Counter;
320     + struct Statistics *Stats;
321     +
322     + static MYSQL *conn = NULL;
323     + static MYSQL mysql;
324     + static MYSQL_STMT *stmts[4];
325     + static my_ulonglong sensor_id;
326     + static unsigned long long data[7];
327     + static uint32_t ip;
328     + MYSQL_RES *res;
329     + MYSQL_ROW row;
330     + unsigned long *lengths;
331     +
332     + int ret;
333     + char sql[1024];
334     + char tmp[20];
335     + char *sensor_name;
336     +
337     + if (!config.output_database == DB_MYSQL)
338     + return;
339     +
340     + // ************ Initialize the db if it's not already
341     + if (!conn) {
342     + if(!mysql_init(&mysql)) {
343     + syslog(LOG_ERR, "Insufficient memory to allocate MYSQL structure");
344     + return;
345     + }
346     +
347     + /* Connect to the database */
348     + conn = mysql_real_connect(&mysql, config.mysql_host, config.mysql_user,
349     + config.mysql_pass, config.mysql_dbname, config.mysql_port, NULL, 0);
350     +
351     + /* Check to see that the backend connection was successfully made */
352     + if (!conn) {
353     + syslog(LOG_ERR, "Connection to database '%s' on '%s' with user '%s' failed: %s",
354     + config.mysql_dbname, config.mysql_host, config.mysql_user, mysql_error(&mysql));
355     + mysql_close(&mysql); // Deallocates memory used by MYSQL structure
356     + return;
357     + }
358     +
359     + conn = CheckMysqlTables(conn);
360     + if (!conn)
361     + return;
362     +
363     + conn = MysqlStmtsInit(conn, stmts, data, &sensor_id, &ip);
364     + if (!conn)
365     + return;
366     +
367     + // Escape sensor_id
368     + sensor_name = (char *) malloc(2*strlen(config.sensor_id)+1);
369     + mysql_real_escape_string(conn, sensor_name, config.sensor_id, strlen(config.sensor_id));
370     +
371     + // Retrieve sensor_id from database
372     + snprintf(sql, sizeof(sql), "SELECT sensor_id FROM sensors WHERE sensor_name='%s'", sensor_name);
373     + ret = mysql_query(conn, sql);
374     + if(ret) {
375     + syslog(LOG_ERR, "MySQL SELECT failed: %s", mysql_error(conn));
376     + free(sensor_name);
377     + MysqlStmtsClose(stmts);
378     + mysql_close(conn);
379     + conn = NULL;
380     + return;
381     + }
382     +
383     + res = mysql_store_result(conn);
384     + if(!res) {
385     + syslog(LOG_ERR, "MySQL store_result failed: %s", mysql_error(conn));
386     + free(sensor_name);
387     + MysqlStmtsClose(stmts);
388     + mysql_close(conn);
389     + conn = NULL;
390     + return;
391     + }
392     +
393     + // Sensor is already in database
394     + if(mysql_num_rows(res)) {
395     + // No longer needed
396     + free(sensor_name);
397     +
398     + row = mysql_fetch_row(res);
399     + if(!row) {
400     + syslog(LOG_ERR, "MySQL fetch_row failed: %s", mysql_error(conn));
401     + mysql_free_result(res);
402     + MysqlStmtsClose(stmts);
403     + mysql_close(conn);
404     + conn = NULL;
405     + return;
406     + }
407     +
408     + if(!row[0]) {
409     + syslog(LOG_ERR, "MySQL NULL value encountered");
410     + mysql_free_result(res);
411     + MysqlStmtsClose(stmts);
412     + mysql_close(conn);
413     + conn = NULL;
414     + return;
415     + }
416     +
417     + lengths = mysql_fetch_lengths(res);
418     + if(!lengths) {
419     + syslog(LOG_ERR, "MySQL fetch_lengths failed: %s", mysql_error(conn));
420     + mysql_free_result(res);
421     + MysqlStmtsClose(stmts);
422     + mysql_close(conn);
423     + return;
424     + }
425     +
426     + snprintf(tmp, sizeof(tmp), "%.*s", (int) lengths[0], row[0]);
427     + sensor_id = atoll(tmp);
428     +
429     + mysql_free_result(res);
430     + } else { // First connection of this sensor, create new entry in sensors table
431     + mysql_free_result(res);
432     + snprintf(sql, sizeof(sql), "INSERT INTO sensors (sensor_name, last_connection, sensor_id) VALUES('%s', NOW(), NULL)", sensor_name);
433     + free(sensor_name);
434     + ret = mysql_query(conn, sql);
435     + if(ret) {
436     + syslog(LOG_ERR, "MySQL INSERT failed: %s", mysql_error(conn));
437     + MysqlStmtsClose(stmts);
438     + mysql_close(conn);
439     + conn = NULL;
440     + return;
441     + }
442     +
443     + sensor_id = mysql_insert_id(conn);
444     + }
445     + }
446     +
447     + // Begin transaction
448     + ret = mysql_query(conn, "BEGIN");
449     + if(ret) {
450     + syslog(LOG_ERR, "MySQL BEGIN failed: %s", mysql_error(conn));
451     + MysqlStmtsClose(stmts);
452     + mysql_close(conn);
453     + conn = NULL;
454     + return;
455     + }
456     +
457     + snprintf(sql, sizeof(sql), "UPDATE sensors SET last_connection = NOW() WHERE sensor_id = %llu", sensor_id);
458     + ret = mysql_query(conn, sql);
459     + if(ret) {
460     + syslog(LOG_ERR, "MySQL UPDATE failed: %s", mysql_error(conn));
461     + MysqlStmtsClose(stmts);
462     + mysql_close(conn);
463     + conn = NULL;
464     + return;
465     + }
466     +
467     + for(Counter = 0; Counter < IpCount; Counter++) {
468     + IPData = &IncData[Counter];
469     +
470     + Stats = &(IPData->Send);
471     + if (Stats->total > 512) {
472     + data[0] = (long long unsigned int) ((((double) Stats->total) / 1024.0) + 0.5);
473     + data[1] = (long long unsigned int) ((((double) Stats->icmp) / 1024.0) + 0.5);
474     + data[2] = (long long unsigned int) ((((double) Stats->udp) / 1024.0) + 0.5);
475     + data[3] = (long long unsigned int) ((((double) Stats->tcp) / 1024.0) + 0.5);
476     + data[4] = (long long unsigned int) ((((double) Stats->ftp) / 1024.0) + 0.5);
477     + data[5] = (long long unsigned int) ((((double) Stats->http) / 1024.0) + 0.5);
478     + data[6] = (long long unsigned int) ((((double) Stats->p2p) / 1024.0) + 0.5);
479     +
480     + if (IPData->ip == 0) {
481     + if(mysql_stmt_execute(stmts[0])) {
482     + syslog(LOG_ERR, "MySQL INSERT failed: %s", mysql_stmt_error(stmts[0]));
483     + if(mysql_stmt_errno(stmts[0]) == CR_SERVER_LOST) {
484     + // First, deallocate memory from previously used prepared statements
485     + MysqlStmtsClose(stmts);
486     + MysqlStmtsInit(conn, stmts, data, &sensor_id, &ip);
487     + if(mysql_stmt_execute(stmts[0])) {
488     + syslog(LOG_ERR, "MySQL INSERT retry failed: %s", mysql_stmt_error(stmts[0]));
489     + MysqlStmtsClose(stmts);
490     + mysql_close(conn);
491     + conn = NULL;
492     + return;
493     + } else
494     + // Not quite reconnect since MySQL library handles it automatically,
495     + // but rather reinitialization of prepared statements
496     + syslog(LOG_ERR, "Reconnect succeded");
497     + } else {
498     + MysqlStmtsClose(stmts);
499     + mysql_close(conn);
500     + conn = NULL;
501     + return;
502     + }
503     + }
504     + }
505     + else {
506     + ip = IPData->ip;
507     + if(mysql_stmt_execute(stmts[1])) {
508     + syslog(LOG_ERR, "MySQL INSERT failed: %s", mysql_stmt_error(stmts[1]));
509     + if(mysql_stmt_errno(stmts[1]) == CR_SERVER_LOST) {
510     + // First, deallocate memory from previously used prepared statements
511     + MysqlStmtsClose(stmts);
512     + MysqlStmtsInit(conn, stmts, data, &sensor_id, &ip);
513     + if(mysql_stmt_execute(stmts[1])) {
514     + syslog(LOG_ERR, "MySQL INSERT retry failed: %s", mysql_stmt_error(stmts[1]));
515     + MysqlStmtsClose(stmts);
516     + mysql_close(conn);
517     + conn = NULL;
518     + return;
519     + } else
520     + // Not quite reconnect since MySQL library handles it automatically,
521     + // but rather reinitialization of prepared statements
522     + syslog(LOG_ERR, "Reconnect succeded");
523     + } else {
524     + MysqlStmtsClose(stmts);
525     + mysql_close(conn);
526     + conn = NULL;
527     + return;
528     + }
529     + }
530     + }
531     + }
532     +
533     + Stats = &(IPData->Receive);
534     + if (Stats->total > 512) {
535     + data[0] = (long long unsigned int) ((((double) Stats->total) / 1024.0) + 0.5);
536     + data[1] = (long long unsigned int) ((((double) Stats->icmp) / 1024.0) + 0.5);
537     + data[2] = (long long unsigned int) ((((double) Stats->udp) / 1024.0) + 0.5);
538     + data[3] = (long long unsigned int) ((((double) Stats->tcp) / 1024.0) + 0.5);
539     + data[4] = (long long unsigned int) ((((double) Stats->ftp) / 1024.0) + 0.5);
540     + data[5] = (long long unsigned int) ((((double) Stats->http) / 1024.0) + 0.5);
541     + data[6] = (long long unsigned int) ((((double) Stats->p2p) / 1024.0) + 0.5);
542     + if (IPData->ip == 0) {
543     + if(mysql_stmt_execute(stmts[2])) {
544     + syslog(LOG_ERR, "MySQL INSERT failed: %s", mysql_stmt_error(stmts[2]));
545     + if(mysql_stmt_errno(stmts[2]) == CR_SERVER_LOST) {
546     + // First, deallocate memory from previously used prepared statements
547     + MysqlStmtsClose(stmts);
548     + MysqlStmtsInit(conn, stmts, data, &sensor_id, &ip);
549     + if(mysql_stmt_execute(stmts[2])) {
550     + syslog(LOG_ERR, "MySQL INSERT retry failed: %s", mysql_stmt_error(stmts[2]));
551     + MysqlStmtsClose(stmts);
552     + mysql_close(conn);
553     + conn = NULL;
554     + return;
555     + } else
556     + // Not quite reconnect since MySQL library handles it automatically,
557     + // but rather reinitialization of prepared statements
558     + syslog(LOG_ERR, "Reconnect succeded");
559     + } else {
560     + MysqlStmtsClose(stmts);
561     + mysql_close(conn);
562     + conn = NULL;
563     + return;
564     + }
565     + }
566     + } else {
567     + ip = IPData->ip;
568     + if(mysql_stmt_execute(stmts[3])) {
569     + syslog(LOG_ERR, "MySQL INSERT failed: %s", mysql_stmt_error(stmts[3]));
570     + if(mysql_stmt_errno(stmts[3]) == CR_SERVER_LOST) {
571     + // First, deallocate memory from previously used prepared statements
572     + MysqlStmtsClose(stmts);
573     + MysqlStmtsInit(conn, stmts, data, &sensor_id, &ip);
574     + if(mysql_stmt_execute(stmts[3])) {
575     + syslog(LOG_ERR, "MySQL INSERT retry failed: %s", mysql_stmt_error(stmts[3]));
576     + MysqlStmtsClose(stmts);
577     + mysql_close(conn);
578     + conn = NULL;
579     + return;
580     + } else
581     + // Not quite reconnect since MySQL library handles it automatically,
582     + // but rather reinitialization of prepared statements
583     + syslog(LOG_ERR, "Reconnect succeded");
584     + } else {
585     + MysqlStmtsClose(stmts);
586     + mysql_close(conn);
587     + conn = NULL;
588     + return;
589     + }
590     + }
591     + }
592     + }
593     + }
594     +
595     + ret = mysql_query(conn, "COMMIT");
596     + if(ret) {
597     + syslog(LOG_ERR, "MySQL COMMIT failed: %s", mysql_error(conn));
598     + MysqlStmtsClose(stmts);
599     + mysql_close(conn);
600     + conn = NULL;
601     + return;
602     + }
603     +#else
604     + syslog(LOG_ERR, "MySQL logging selected but MySQL support is not compiled into binary. Please check the documentation in README, distributed with this software.");
605     +#endif // HAVE_LIBMYSQLCLIENT
606     +}
607     +
608     void StoreIPDataInDatabase(struct IPData IncData[])
609     {
610     if (config.output_database == DB_PGSQL)
611     - StoreIPDataInPostgresql(IncData);
612     + StoreIPDataInPostgresql(IncData);
613     + else if (config.output_database == DB_MYSQL)
614     + StoreIPDataInMysql(IncData);
615     }
616    
617     void StoreIPDataInCDF(struct IPData IncData[])
618     diff -ruN bandwidthd/bandwidthd.h bandwidthd-mysql-20050912/bandwidthd.h
619     --- bandwidthd/bandwidthd.h 2005-09-23 16:08:12.000000000 +0200
620     +++ bandwidthd-mysql-20050912/bandwidthd.h 2005-08-28 16:22:19.000000000 +0200
621     @@ -1,3 +1,6 @@
622     +#ifndef BANDWIDTHD_H
623     +#define BANDWIDTHD_H
624     +
625     #ifdef HAVE_CONFIG_H
626     #include "config.h"
627     #endif
628     @@ -100,8 +103,8 @@
629    
630     #define MAX_FILENAME 1024
631    
632     +#define DB_NONE 0
633     #define DB_PGSQL 1
634     -// No mysql support yet
635     #define DB_MYSQL 2
636    
637     struct config
638     @@ -119,10 +122,15 @@
639     char tag;
640     unsigned int meta_refresh;
641     int output_database;
642     - char *db_connect_string;
643     + char *pgsql_connect_string;
644     char *sensor_id;
645     char *log_dir;
646     char *htdocs_dir;
647     + char *mysql_host;
648     + char *mysql_user;
649     + char *mysql_pass;
650     + char *mysql_dbname;
651     + unsigned int mysql_port;
652     };
653    
654     struct SubnetData
655     @@ -226,3 +234,5 @@
656     // ************ Misc
657     inline void DstCredit(uint32_t ipaddr, unsigned int psize);
658     void MakeIndexPages(int NumGraphs, struct SummaryData *SummaryData[]);
659     +
660     +#endif // BANDWIDTHD_H
661     diff -ruN bandwidthd/CHANGELOG bandwidthd-mysql-20050912/CHANGELOG
662     --- bandwidthd/CHANGELOG 2005-09-23 16:08:12.000000000 +0200
663     +++ bandwidthd-mysql-20050912/CHANGELOG 2005-08-20 19:09:17.000000000 +0200
664     @@ -1,3 +1,6 @@
665     +Config option 'output_database' to select database type
666     +Netmask is now correctly displayed in syslog
667     +MySQL support
668     Make file tweaks
669     Adhere more strictly to GNU coding standards for directories
670     Optional htdocs and log file locations specified at configure time
671     diff -ruN bandwidthd/configure.in bandwidthd-mysql-20050912/configure.in
672     --- bandwidthd/configure.in 2005-09-23 16:08:12.000000000 +0200
673     +++ bandwidthd-mysql-20050912/configure.in 2005-08-30 23:18:22.000000000 +0200
674     @@ -45,11 +45,14 @@
675     # Required for openbsd png library
676     AC_CHECK_LIB(m, pow)
677    
678     +# Required for linux png library
679     +AC_CHECK_LIB(z, deflate)
680     +
681     # Required for gd under netbsd
682     AC_CHECK_LIB(iconv, libiconv_open)
683    
684     # Required Libraries
685     -AC_CHECK_LIB(png, png_read_info, ,[AC_MSG_ERROR([Bandwidthd requires but cannot libpng])])
686     +AC_CHECK_LIB(png, png_read_info, ,[AC_MSG_ERROR([Bandwidthd requires but cannot find libpng])])
687     AC_CHECK_LIB(gd, gdImageCreate, ,[AC_MSG_ERROR([Bandwidthd requires but cannot find libgd])])
688     AC_CHECK_LIB(pcap, pcap_open_live, ,
689     [AC_CHECK_LIB(wpcap, pcap_open_live, ,[AC_MSG_ERROR([Bandwidthd requires but cannot find libpcap])])])
690     @@ -58,7 +61,16 @@
691     AC_CHECK_FILE(/usr/lib, LDFLAGS="$LDFLAGS -L/usr/lib")
692     AC_CHECK_FILE(/usr/include/pgsql, CPPFLAGS="$CPPFLAGS -I/usr/include/pgsql")
693     AC_CHECK_LIB(pq, PQconnectdb,
694     - [AC_CHECK_LIB(pq,PQexecParams, ,AC_MSG_WARN([libpq exists but is too old... bandwidthd requires support for PQexecParams]))])
695     + [AC_CHECK_LIB(pq,PQexecParams, ,AC_MSG_ERROR([libpq exists but is too old... bandwidthd requires support for PQexecParams]))])
696     +
697     +# MySQL support
698     +AC_CHECK_PROG(MYSQL_CONFIG, mysql_config, yes, no)
699     +if test "$MYSQL_CONFIG" = "yes"; then
700     + CPPFLAGS="$CFLAGS `mysql_config --include`"
701     + LDFLAGS="$LDFLAGS `mysql_config --libs`"
702     +fi
703     +AC_CHECK_LIB(mysqlclient, mysql_real_connect,
704     + [AC_CHECK_LIB(mysqlclient, mysql_stmt_init, ,AC_MSG_ERROR([bandwidthd requires MySQL prepared statements (MySQL 4.1.x)]))])
705    
706     # Checks for header files.
707     AC_HEADER_DIRENT
708     @@ -77,6 +89,9 @@
709     AC_CHECK_HEADERS([arpa/inet.h errno.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/socket.h sys/time.h sys/wait.h syslog.h unistd.h],,
710     [AC_MSG_ERROR([Bandwidthd cannot find some header files])])
711    
712     +if test "$ac_cv_lib_mysqlclient_mysql_stmt_init" = "yes"; then
713     + AC_CHECK_HEADERS(mysql.h errmsg.h, ,[AC_MSG_ERROR([Bandwidthd cannot find MySQL headers])])
714     +fi
715    
716     #Headers missing on cygwin
717     AC_CHECK_HEADERS([arpa/nameser.h])
718     diff -ruN bandwidthd/conf.l bandwidthd-mysql-20050912/conf.l
719     --- bandwidthd/conf.l 2005-09-23 16:08:12.000000000 +0200
720     +++ bandwidthd-mysql-20050912/conf.l 2005-08-20 19:09:17.000000000 +0200
721     @@ -26,8 +26,17 @@
722     filter { return TOKFILTER; }
723     meta_refresh { return TOKMETAREFRESH; }
724     pgsql_connect_string { return TOKPGSQLCONNECTSTRING; }
725     +mysql_host { return TOKMYSQLHOST; }
726     +mysql_user { return TOKMYSQLUSER; }
727     +mysql_pass { return TOKMYSQLPASS; }
728     +mysql_dbname { return TOKMYSQLDBNAME; }
729     +mysql_port { return TOKMYSQLPORT; }
730     sensor_id { return TOKSENSORID; }
731     htdocs_dir { return TOKHTDOCSDIR; }
732     log_dir { return TOKLOGDIR; }
733     +none { return TOKNONE; }
734     +pgsql { return TOKPGSQL; }
735     +mysql { return TOKMYSQL; }
736     +output_database { return TOKOUTPUTDATABASE; }
737     . { return TOKJUNK; }
738     %%
739     diff -ruN bandwidthd/conf.y bandwidthd-mysql-20050912/conf.y
740     --- bandwidthd/conf.y 2005-09-23 16:08:12.000000000 +0200
741     +++ bandwidthd-mysql-20050912/conf.y 2005-08-20 19:09:17.000000000 +0200
742     @@ -34,6 +34,8 @@
743     %token TOKJUNK TOKSUBNET TOKDEV TOKSLASH TOKSKIPINTERVALS TOKGRAPHCUTOFF
744     %token TOKPROMISC TOKOUTPUTCDF TOKRECOVERCDF TOKGRAPH TOKNEWLINE TOKFILTER
745     %token TOKMETAREFRESH TOKPGSQLCONNECTSTRING TOKSENSORID TOKHTDOCSDIR TOKLOGDIR
746     +%token TOKMYSQLHOST TOKMYSQLUSER TOKMYSQLPASS TOKMYSQLDBNAME TOKMYSQLPORT
747     +%token TOKNONE TOKPGSQL TOKMYSQL TOKOUTPUTDATABASE
748     %union
749     {
750     int number;
751     @@ -81,6 +83,18 @@
752     htdocs_dir
753     |
754     log_dir
755     + |
756     + mysql_host
757     + |
758     + mysql_user
759     + |
760     + mysql_pass
761     + |
762     + mysql_dbname
763     + |
764     + mysql_port
765     + |
766     + output_database
767     ;
768    
769     subnet:
770     @@ -227,9 +241,60 @@
771     pgsql_connect_string:
772     TOKPGSQLCONNECTSTRING string
773     {
774     - config.db_connect_string = $2;
775     + config.pgsql_connect_string = $2;
776     + }
777     + ;
778     +
779     +mysql_host:
780     + TOKMYSQLHOST string
781     + {
782     + config.mysql_host = $2;
783     + }
784     + ;
785     +
786     +mysql_user:
787     + TOKMYSQLUSER string
788     + {
789     + config.mysql_user = $2;
790     + }
791     + ;
792     +
793     +mysql_pass:
794     + TOKMYSQLPASS string
795     + {
796     + config.mysql_pass = $2;
797     + }
798     + ;
799     +
800     +mysql_dbname:
801     + TOKMYSQLDBNAME string
802     + {
803     + config.mysql_dbname = $2;
804     + }
805     + ;
806     +
807     +mysql_port:
808     + TOKMYSQLPORT NUMBER
809     + {
810     + config.mysql_port = $2;
811     + }
812     + ;
813     +
814     +output_database:
815     + TOKOUTPUTDATABASE TOKNONE
816     + {
817     + config.output_database = DB_NONE;
818     + }
819     + |
820     + TOKOUTPUTDATABASE TOKPGSQL
821     + {
822     config.output_database = DB_PGSQL;
823     }
824     + |
825     + TOKOUTPUTDATABASE TOKMYSQL
826     + {
827     + config.output_database = DB_MYSQL;
828     + }
829     ;
830    
831     sensor_id:
832     diff -ruN bandwidthd/graph.c bandwidthd-mysql-20050912/graph.c
833     --- bandwidthd/graph.c 2005-09-23 16:08:12.000000000 +0200
834     +++ bandwidthd-mysql-20050912/graph.c 2005-08-19 20:17:17.000000000 +0200
835     @@ -707,8 +707,8 @@
836     snprintf(Buffer, 30, "Sent %.1f KBytes", (double)SummaryData->TotalSent/1024.0);
837     else snprintf(Buffer, 30, "Sent %.1f MBytes", (double)SummaryData->TotalSent/(1024.0*1024.0));
838    
839     - gdImageString(im, gdFontSmall, XOFFSET+5, YHEIGHT-20, Buffer, black);
840     - gdImageString(im, gdFontSmall, XWIDTH/2+XOFFSET/2, YHEIGHT-20, Buffer2, black);
841     + gdImageString(im, gdFontSmall, XOFFSET+5, YHEIGHT-20, (unsigned char *) Buffer, black);
842     + gdImageString(im, gdFontSmall, XWIDTH/2+XOFFSET/2, YHEIGHT-20, (unsigned char *) Buffer2, black);
843    
844     if (ReceivedPeak < 1024/8)
845     snprintf(Buffer2, 50, "Peak Receive Rate: %.1f Bits/sec", (double)ReceivedPeak*8);
846     @@ -722,8 +722,8 @@
847     snprintf(Buffer, 30, "Received %.1f KBytes", (double)SummaryData->TotalReceived/1024.0);
848     else snprintf(Buffer, 30, "Received %.1f MBytes", (double)SummaryData->TotalReceived/(1024.0*1024.0));
849    
850     - gdImageString(im2, gdFontSmall, XOFFSET+5, YHEIGHT-20, Buffer, black2);
851     - gdImageString(im2, gdFontSmall, XWIDTH/2+XOFFSET/2, YHEIGHT-20, Buffer2, black2);
852     + gdImageString(im2, gdFontSmall, XOFFSET+5, YHEIGHT-20, (unsigned char *) Buffer, black2);
853     + gdImageString(im2, gdFontSmall, XWIDTH/2+XOFFSET/2, YHEIGHT-20, (unsigned char *) Buffer2, black2);
854    
855     return(YMax);
856     }
857     @@ -772,7 +772,7 @@
858    
859     gdImageLine(im, XOFFSET, y, XWIDTH, y, black);
860     snprintf(buffer, 20, "%4.1f %cbits/s", (float)(8.0*YTic)/Divisor, YLegend);
861     - gdImageString(im, gdFontSmall, 3, y-7, buffer, black);
862     + gdImageString(im, gdFontSmall, 3, y-7, (unsigned char *) buffer, black);
863    
864     YTic += YStep;
865     }
866     @@ -824,7 +824,7 @@
867    
868     timestruct = localtime((time_t *)&MarkTime);
869     strftime(buffer, 100, "%a, %b %d", timestruct);
870     - gdImageString(im, gdFontSmall, x-30, YHEIGHT-YOFFSET+10, buffer, black);
871     + gdImageString(im, gdFontSmall, x-30, YHEIGHT-YOFFSET+10, (unsigned char *) buffer, black);
872    
873     // Calculate Next x
874     MarkTime += (24*60*60);
875     @@ -858,7 +858,7 @@
876    
877     timestruct = localtime((time_t *)&MarkTime);
878     strftime(buffer, 100, "%b", timestruct);
879     - gdImageString(im, gdFontSmall, x-6, YHEIGHT-YOFFSET+10, buffer, black);
880     + gdImageString(im, gdFontSmall, x-6, YHEIGHT-YOFFSET+10, (unsigned char *) buffer, black);
881    
882     // Calculate Next x
883     timestruct->tm_mon++;
884     diff -ruN bandwidthd/INSTALL.Unix bandwidthd-mysql-20050912/INSTALL.Unix
885     --- bandwidthd/INSTALL.Unix 2005-09-23 16:08:12.000000000 +0200
886     +++ bandwidthd-mysql-20050912/INSTALL.Unix 2005-08-20 19:50:28.000000000 +0200
887     @@ -1,16 +1,42 @@
888     #### INSTALLATION #
889    
890     -You need 3 dependencies to make Bandwidthd work:
891     +You need one dependency to make Bandwidthd work:
892    
893     libpcap from http://www.tcpdump.org/
894     -libpng from http://www.libpng.org/
895     +
896     +Chances are you already have it, if in doubt
897     +just run configure and see what it complains about.
898     +
899     +Additionally you will need at least one of the following three:
900     +
901     +1.
902     libgd from http://www.boutell.com/gd/
903     +linpng from http://www.libpng.org/
904     +
905     +This will enable bandwidthd to make static graphs
906     +at specified time interval.
907    
908     -Chances are you already have all three, if in doubt
909     -just run configure and see what it complains about. If
910     -you are missing libpng, make sure you re-install libgd
911     +If you are missing libpng, make sure you re-install libgd
912     after you install it.
913    
914     +2.
915     +MySQL from http://www.mysql.com/
916     +PHP from http://www.php.net/
917     +Apache from http://www.apache.org/
918     +
919     +This will enable bandwidthd to store statistics in MySQL,
920     +graphs will be created on demand by webpage in PHP.
921     +
922     +3.
923     +PostgreSQL from http://www.postgresql.org/
924     +PHP from http://www.php.net/
925     +Apache from http://www.apache.org/
926     +
927     +This will enable bandwidthd to store statistics in PostgreSQL,
928     +graphs will be created on demand by webpage in PHP.
929     +
930     +
931     +
932     Configure and install the Bandwidthd source:
933    
934     ./configure && make install
935     diff -ruN bandwidthd/README bandwidthd-mysql-20050912/README
936     --- bandwidthd/README 2005-09-23 16:08:12.000000000 +0200
937     +++ bandwidthd-mysql-20050912/README 2005-08-20 19:09:17.000000000 +0200
938     @@ -172,7 +172,7 @@
939     Bandwidthd uses very little ram and CPU. In addition, multiple sensors can record
940     to the same database.
941    
942     -2. The database system. Currently Bandwidthd only supports Postgresql.
943     +2. The database system. Currently Bandwidthd supports PostgreSQL and MySQL.
944    
945     3. The webserver and php application. Bundled with Bandwidthd in the "phphtdocs"
946     directory is a php application that reports on and graphs the contents of the database.
947     @@ -189,8 +189,8 @@
948    
949     INSTRUCTIONS
950    
951     -As a prerequisite for these instructions, you must have Postgresql installed and working,
952     -as well as a web server that supports php.
953     +As a prerequisite for these instructions, you must have PostgreSQL or MySQL installed
954     +and working, as well as a web server that supports php.
955    
956     Setup:
957     1. Create a database for Bandwidthd. You will need to create users that can access the
958     @@ -198,9 +198,25 @@
959    
960     2. Add the following lines to your bandwidthd.conf file:
961    
962     +If you want to use PostgreSQL
963     +# Database type, possible values, pgsql, mysql or none
964     +output_database pgsql
965     # Standard postgres connect string, just like php, see postgres docs for
966     # details
967     pgsql_connect_string "user = someuser dbname = mydb host = databaseserver.com"
968     +
969     +
970     +If you want to use MySQL:
971     +# Database type, possible values, pgsql, mysql or none
972     +output_database mysql
973     +mysql_host "localhost"
974     +mysql_user "bandwidthd"
975     +mysql_pass "password"
976     +mysql_dbname "bandwidthd"
977     +# Port 0 means, that the default port is used
978     +#mysql_port 0
979     +
980     +And some common options:
981     # Arbitrary sensor name, I recommend the sensors fully qualified domain
982     # name
983     sensor_id "sensor1.mycompany.com"
984     @@ -217,24 +233,30 @@
985    
986     Web Server Setup:
987     1. Copy the contents of phphtdocs into your web tree some where.
988     -2. Edit config.conf to set your db connect string
989     +2. Edit config.conf to set your db type and parameters.
990    
991     You should now be able to access the web application and see you graphs. All graphing
992     is done by graph.php, all parameters are passed to it in it's url. You can create
993     custom urls to pull custom graphs from your own index pages, or use the canned
994     reporting system.
995    
996     -In addition, you should schedule bd_pgsql_purge.sh to run every so often. I recomend
997     -running it weekly. This script outputs sql statements that aggregate the older
998     -data points in your database in order to reduce the amount of data that needs to
999     -be slogged through in order to generate yearly, monthly, and weekly graphs.
1000     +In addition, you should schedule bd_pgsql_purge.sh or bd_mysql_purge.sh to run every
1001     +so often. I recomend running it weekly. This script outputs sql statements that
1002     +aggregate the older data points in your database in order to reduce the amount
1003     +of data that needs to be slogged through in order to generate yearly, monthly,
1004     +and weekly graphs.
1005    
1006     -Example:
1007     +Example for PostgreSQL:
1008     bd_pgsql_purge.sh | psql bandwidthd postgres
1009     -
1010     Will connect to the bandwidthd database on local host as the user postgres and summarize
1011     the data.
1012    
1013     +Example for MySQL:
1014     +bd_mysql_purge.sh | mysql -umysql -ppass bandwidthd
1015     +Will connect to the bandwidthd database on localhost as the user mysql
1016     +with password pass and summarize the data.
1017     +
1018     +
1019     # KNOWN BUGS AND TROUBLESHOOTING #
1020    
1021     If Bandwidthd shows you nothing but a message saying "Bandwidthd has nothing to graph",
1022     diff -ruN bandwidthd/etc/bandwidthd.conf bandwidthd-mysql-20050912/etc/bandwidthd.conf
1023     --- bandwidthd/etc/bandwidthd.conf 2005-09-23 16:08:12.000000000 +0200
1024     +++ bandwidthd-mysql-20050912/etc/bandwidthd.conf 2005-08-20 19:09:17.000000000 +0200
1025     @@ -57,5 +57,27 @@
1026     #Set the static html output directory
1027     #htdocs_dir "/usr/local/var/bandwidthd/htdocs"
1028    
1029     +####################################################
1030     +# Database options
1031     +# You should probably change both output_cdf and graph to false
1032     +# if you are using database.
1033    
1034     +# Database type, possible values, pgsql, mysql or none
1035     +#output_database none
1036    
1037     +# Arbitrary sensor name, I recommend the sensors fully qualified domain
1038     +# name
1039     +#sensor_id "sensor1"
1040     +
1041     +# PostgreSQL
1042     +# Standard postgres connect string, just like php, see postgres docs for
1043     +# details
1044     +#pgsql_connect_string "user = someuser dbname = mydb host = databaseserver.com"
1045     +
1046     +# MySQL
1047     +#mysql_host "localhost"
1048     +#mysql_user "bandwidthd"
1049     +#mysql_pass "password"
1050     +#mysql_dbname "bandwidthd"
1051     +# Port 0 means, that the default port is used
1052     +#mysql_port 0
1053     diff -ruN bandwidthd/phphtdocs/bd_mysql_purge.sh bandwidthd-mysql-20050912/phphtdocs/bd_mysql_purge.sh
1054     --- bandwidthd/phphtdocs/bd_mysql_purge.sh 1970-01-01 01:00:00.000000000 +0100
1055     +++ bandwidthd-mysql-20050912/phphtdocs/bd_mysql_purge.sh 2005-09-09 14:14:26.000000000 +0200
1056     @@ -0,0 +1,59 @@
1057     +echo -e "bd_rx_log \n bd_tx_log \n bd_rx_total_log \n bd_tx_total_log" | while read TABLE;
1058     +do
1059     +cat << EOF
1060     +BEGIN;
1061     +
1062     +INSERT INTO $TABLE (sensor_id, ip, timestamp, sample_duration, total, icmp, udp, tcp, ftp, http, p2p)
1063     +SELECT sensor_id, ip,
1064     +IF(EXTRACT(hour FROM timestamp) >= 12, DATE_FORMAT(timestamp, "%y-%m-%d 00:00:00") + INTERVAL 12 hour,
1065     + DATE_FORMAT(timestamp, "%y-%m-%d 00:00:00")) + INTERVAL 12 hour,
1066     +60*60*12, SUM(total), SUM(icmp), SUM(udp), SUM(tcp), SUM(ftp), SUM(http), SUM(p2p)
1067     +FROM $TABLE
1068     +WHERE sample_duration < 60*60*12
1069     +AND timestamp < NOW() - INTERVAL 35 day
1070     +GROUP BY sensor_id, ip,
1071     +IF(EXTRACT(hour FROM timestamp) >= 12, DATE_FORMAT(timestamp, "%y-%m-%d 00:00:00") + INTERVAL 12 hour,
1072     + DATE_FORMAT(timestamp, "%y-%m-%d 00:00:00"));
1073     +
1074     +DELETE FROM $TABLE WHERE sample_duration < 60*60*12 AND timestamp < NOW() - INTERVAL 35 day;
1075     +
1076     +COMMIT;
1077     +
1078     +
1079     +BEGIN;
1080     +
1081     +INSERT INTO $TABLE (sensor_id, ip, timestamp, sample_duration, total, icmp, udp, tcp, ftp, http, p2p)
1082     +SELECT sensor_id, ip,
1083     +DATE_FORMAT(timestamp,"%y-%m-%d %H:00:00") + INTERVAL 1 hour,
1084     +60*60, SUM(total), SUM(icmp), SUM(udp), SUM(tcp), SUM(ftp), SUM(http), SUM(p2p)
1085     +FROM $TABLE
1086     +WHERE sample_duration < 60*60
1087     +AND timestamp < NOW() - INTERVAL 7 day
1088     +GROUP BY sensor_id, ip, DATE_FORMAT(timestamp,"%y-%m-%d %H:00:00");
1089     +
1090     +DELETE FROM $TABLE WHERE sample_duration < 60*60 AND timestamp < NOW() - INTERVAL 7 day;
1091     +
1092     +COMMIT;
1093     +
1094     +
1095     +BEGIN;
1096     +
1097     +INSERT INTO $TABLE (sensor_id, ip, timestamp, sample_duration, total, icmp, udp, tcp, ftp, http, p2p)
1098     +SELECT sensor_id, ip,
1099     +DATE_FORMAT(timestamp,"%y-%m-%d %H:00:00") + INTERVAL TRUNCATE(EXTRACT(minute FROM timestamp),-1) minute
1100     ++ INTERVAL 10 minute,
1101     +10*60, SUM(total), SUM(icmp), SUM(udp), SUM(tcp), SUM(ftp), SUM(http), SUM(p2p)
1102     +FROM $TABLE
1103     +WHERE sample_duration < 10*60
1104     +AND timestamp < NOW() - INTERVAL 2 day
1105     +GROUP BY sensor_id, ip,
1106     +DATE_FORMAT(timestamp,"%y-%m-%d %H:00:00") + INTERVAL TRUNCATE(EXTRACT(minute FROM timestamp),-1) minute;
1107     +
1108     +DELETE FROM $TABLE WHERE sample_duration < 10*60 AND timestamp < NOW() - INTERVAL 2 day;
1109     +
1110     +COMMIT;
1111     +
1112     +OPTIMIZE TABLE $TABLE;
1113     +ANALYZE TABLE $TABLE;
1114     +EOF
1115     +done
1116     diff -ruN bandwidthd/phphtdocs/config.conf bandwidthd-mysql-20050912/phphtdocs/config.conf
1117     --- bandwidthd/phphtdocs/config.conf 2005-09-23 16:08:12.000000000 +0200
1118     +++ bandwidthd-mysql-20050912/phphtdocs/config.conf 2005-08-20 20:48:03.000000000 +0200
1119     @@ -3,5 +3,17 @@
1120     define("DFLT_HEIGHT", 256);
1121     define("DFLT_INTERVAL", INT_DAILY);
1122    
1123     -$db_connect_string = "user = root dbname = bandwidthd"
1124     -?>
1125     \ No newline at end of file
1126     +// Select type of database you are using
1127     +// Possible values are DB_PGSQL and DB_MYSQL
1128     +$dbtype = DB_MYSQL;
1129     +
1130     +// Configuration for PostgreSQL
1131     +$pgsql_connect_string = "user = root dbname = bandwidthd";
1132     +
1133     +// Configuration for MySQL
1134     +// You can specify port after semicolon, for example "localhost:4067"
1135     +$mysql_host = "localhost";
1136     +$mysql_user = "bandwidthd";
1137     +$mysql_pass = "password";
1138     +$mysql_dbname = "bandwidthd";
1139     +?>
1140     diff -ruN bandwidthd/phphtdocs/details.php bandwidthd-mysql-20050912/phphtdocs/details.php
1141     --- bandwidthd/phphtdocs/details.php 2005-09-23 16:08:12.000000000 +0200
1142     +++ bandwidthd-mysql-20050912/phphtdocs/details.php 2005-09-09 15:48:24.000000000 +0200
1143     @@ -26,7 +26,7 @@
1144    
1145     $db = ConnectDb();
1146    
1147     -if ($ip == "0.0.0.0/0")
1148     +if ($ip == "0.0.0.0/0" || $ip == "0/0")
1149     {
1150     $rxtable = "bd_rx_total_log";
1151     $txtable = "bd_tx_total_log";
1152     @@ -37,7 +37,43 @@
1153     $txtable = "bd_tx_log";
1154     }
1155    
1156     -$sql = "select rx.scale as rxscale, tx.scale as txscale, tx.total+rx.total as total, tx.total as sent,
1157     +if($dbtype == DB_PGSQL) {
1158     + $res = pg_query("SELECT sensor_id FROM sensors WHERE sensor_name='".bd_escape_string($sensor_name)."'");
1159     + if(pg_num_rows($res) != 1) {
1160     + echo "No such sensor\n";
1161     + exit;
1162     + }
1163     + $o = pg_fetch_object($res);
1164     + $sensor_id = $o->sensor_id;
1165     +} else if($dbtype == DB_MYSQL) {
1166     + $res = mysql_query("SELECT sensor_id FROM sensors WHERE sensor_name='".bd_escape_string($sensor_name)."'");
1167     + if(mysql_num_rows($res) != 1) {
1168     + echo "No such sensor\n";
1169     + exit;
1170     + }
1171     + $o = mysql_fetch_object($res);
1172     + $sensor_id = $o->sensor_id;
1173     +} else {
1174     + echo "Unknown database type\n";
1175     + exit;
1176     +}
1177     +
1178     +if($dbtype == DB_PGSQL) {
1179     + $sql_ip = "and ip <<= '$ip'";
1180     +} else if($dbtype == DB_MYSQL) {
1181     + $p = parse_addr($ip);
1182     + if($p["mask"] == ip2long("255.255.255.255")) {
1183     + $sql_ip = "and ip = ".sprintf("%u", $p["ip"]);
1184     + } else if($p["mask"] == 0) {
1185     + $sql_ip = "";
1186     + } else {
1187     + $net = $p["ip"] & $p["mask"];
1188     + $bcast = $net | ~$p["mask"];
1189     + $sql_ip = "and ip between ".sprintf("%u", $net)." and ".sprintf("%u",$bcast);
1190     + }
1191     +}
1192     +
1193     +$pg_sql = "select rx.scale as rxscale, tx.scale as txscale, tx.total+rx.total as total, tx.total as sent,
1194     rx.total as received, tx.tcp+rx.tcp as tcp, tx.udp+rx.udp as udp,
1195     tx.icmp+rx.icmp as icmp, tx.http+rx.http as http,
1196     tx.p2p+rx.p2p as p2p, tx.ftp+rx.ftp as ftp
1197     @@ -45,25 +81,52 @@
1198    
1199     (SELECT ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1200     sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1201     -from sensors, $txtable
1202     -where sensor_name = '$sensor_name'
1203     -and sensors.sensor_id = ".$txtable.".sensor_id
1204     -and ip <<= '$ip'
1205     +from $txtable
1206     +where sensor_id = $sensor_id
1207     +$sql_ip
1208     group by ip) as tx,
1209    
1210     (SELECT ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1211     sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1212     -from sensors, $rxtable
1213     -where sensor_name = '$sensor_name'
1214     -and sensors.sensor_id = ".$rxtable.".sensor_id
1215     -and ip <<= '$ip'
1216     +from $rxtable
1217     +where sensor_id = $sensor_id
1218     +$sql_ip
1219     group by ip) as rx
1220    
1221     where tx.ip = rx.ip;";
1222     -//echo "</center><pre>$sql</pre><center>";exit(0);
1223     -$result = pg_query($sql);
1224     +
1225     +$my_sql = "select rx.scale as rxscale, tx.scale as txscale, tx.total+rx.total as total, tx.total as sent,
1226     +rx.total as received, tx.tcp+rx.tcp as tcp, tx.udp+rx.udp as udp,
1227     +tx.icmp+rx.icmp as icmp, tx.http+rx.http as http,
1228     +tx.p2p+rx.p2p as p2p, tx.ftp+rx.ftp as ftp
1229     +from
1230     +
1231     +(SELECT inet_ntoa(ip) as ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1232     +sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1233     +from $txtable
1234     +where sensor_id = $sensor_id
1235     +$sql_ip
1236     +group by ip) as tx,
1237     +
1238     +(SELECT inet_ntoa(ip) as ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1239     +sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1240     +from $rxtable
1241     +where sensor_id = $sensor_id
1242     +$sql_ip
1243     +group by ip) as rx
1244     +
1245     +where tx.ip = rx.ip";
1246     +//echo "</center><pre>$my_sql</pre><center>";exit(0);
1247     +if($dbtype == DB_PGSQL)
1248     + $result = pg_query($pg_sql);
1249     +else if($dbtype == DB_MYSQL)
1250     + $result = mysql_query($my_sql);
1251     echo "<table width=100% border=1 cellspacing=0><tr><td>Ip<td>Name<td>Total<td>Sent<td>Received<td>tcp<td>udp<td>icmp<td>http<td>p2p<td>ftp";
1252     -$r = pg_fetch_array($result);
1253     +
1254     +if($dbtype == DB_PGSQL)
1255     + $r = pg_fetch_array($result);
1256     +else if($dbtype == DB_MYSQL)
1257     + $r = mysql_fetch_array($result);
1258     echo "<tr><td>";
1259     if (strpos($ip, "/") === FALSE)
1260     echo "$ip<td>".gethostbyaddr($ip);
1261     diff -ruN bandwidthd/phphtdocs/graph.php bandwidthd-mysql-20050912/phphtdocs/graph.php
1262     --- bandwidthd/phphtdocs/graph.php 2005-09-23 16:08:12.000000000 +0200
1263     +++ bandwidthd-mysql-20050912/phphtdocs/graph.php 2005-09-09 15:48:24.000000000 +0200
1264     @@ -3,7 +3,7 @@
1265    
1266     // Returns x location of any given timestamp
1267     function ts2x($ts)
1268     - {
1269     +{
1270     global $timestamp, $width, $interval;
1271     return(($ts-$timestamp)*(($width-XOFFSET) / $interval) + XOFFSET);
1272     }
1273     @@ -27,12 +27,26 @@
1274    
1275     foreach ($Count as $key => $number)
1276     {
1277     + if(!isset($a_total[$key]))
1278     + $a_total[$key] = 0;
1279     $a_total[$key] += $total[$key];
1280     + if(!isset($a_icmp[$key]))
1281     + $a_icmp[$key] = 0;
1282     $a_icmp[$key] += $icmp[$key];
1283     + if(!isset($a_udp[$key]))
1284     + $a_udp[$key] = 0;
1285     $a_udp[$key] += $udp[$key];
1286     + if(!isset($a_tcp[$key]))
1287     + $a_tcp[$key] = 0;
1288     $a_tcp[$key] += $tcp[$key];
1289     + if(!isset($a_ftp[$key]))
1290     + $a_ftp[$key] = 0;
1291     $a_ftp[$key] += $ftp[$key];
1292     + if(!isset($a_http[$key]))
1293     + $a_http[$key] = 0;
1294     $a_http[$key] += $http[$key];
1295     + if(!isset($a_p2p[$key]))
1296     + $a_p2p[$key] = 0;
1297     $a_p2p[$key] += $p2p[$key];
1298    
1299     if ($a_total[$key] > $YMax)
1300     @@ -112,14 +126,58 @@
1301     $a_http = array();
1302     $a_p2p = array();
1303    
1304     -$sql = "select *, extract(epoch from timestamp) as ts from sensors, $table where sensors.sensor_id = ".$table.".sensor_id and ip <<= '$ip' and sensor_name = '$sensor_name' and timestamp > $timestamp::abstime and timestamp < ".($timestamp+$interval)."::abstime order by ip;";
1305     -//echo $sql."<br>"; exit(1);
1306     -$result = pg_query($sql);
1307     +if($dbtype == DB_PGSQL) {
1308     + $res = pg_query("SELECT sensor_id FROM sensors WHERE sensor_name='".bd_escape_string($sensor_name)."'");
1309     + if(pg_num_rows($res) != 1) {
1310     + echo "No such sensor\n";
1311     + exit;
1312     + }
1313     + $o = pg_fetch_object($res);
1314     + $sensor_id = $o->sensor_id;
1315     +} else if($dbtype == DB_MYSQL) {
1316     + $res = mysql_query("SELECT sensor_id FROM sensors WHERE sensor_name='".bd_escape_string($sensor_name)."'");
1317     + if(mysql_num_rows($res) != 1) {
1318     + echo "No such sensor\n";
1319     + exit;
1320     + }
1321     + $o = mysql_fetch_object($res);
1322     + $sensor_id = $o->sensor_id;
1323     +} else {
1324     + echo "Unknown database type\n";
1325     + exit;
1326     +}
1327     +
1328     +if($dbtype == DB_PGSQL) {
1329     + $sql_ip = "and ip <<= '$ip'";
1330     +} else if($dbtype == DB_MYSQL) {
1331     + $p = parse_addr($ip);
1332     + if($p["mask"] == ip2long("255.255.255.255")) {
1333     + $sql_ip = "and ip = " .sprintf("%u", $p["ip"]);
1334     + } else if($p["mask"] == 0) {
1335     + $sql_ip = "";
1336     + } else {
1337     + $net = $p["ip"] & $p["mask"];
1338     + $bcast = $net | ~$p["mask"];
1339     + $sql_ip = "and ip between ".sprintf("%u", $net)." and ".sprintf("%u",$bcast);
1340     + }
1341     +}
1342     +
1343     +$pg_sql = "select ip,total,sample_duration,icmp,udp,tcp,ftp,http,p2p,extract(epoch from timestamp) as ts from $table where sensor_id=$sensor_id $sql_ip and timestamp > $timestamp::abstime and timestamp < ".($timestamp+$interval)."::abstime order by ip;";
1344     +$my_sql = "select ip,total,sample_duration,icmp,udp,tcp,ftp,http,p2p,unix_timestamp(timestamp) as ts from $table where sensor_id=$sensor_id $sql_ip and unix_timestamp(timestamp) > $timestamp and unix_timestamp(timestamp) < ".($timestamp+$interval)." order by ip";
1345     +//echo $my_sql."<br>"; exit(1);
1346     +if($dbtype == DB_PGSQL)
1347     + $result = pg_query($pg_sql);
1348     +else if($dbtype == DB_MYSQL)
1349     + $result = mysql_query($my_sql);
1350    
1351     // The SQL statement pulls the data out of the database ordered by IP address, that way we can average each
1352     // datapoint for each IP address to provide smoothing and then toss the smoothed value into the accumulator
1353     // to provide accurate total traffic rate.
1354    
1355     +$SentPeak = "";
1356     +$TotalSent = "";
1357     +$last_ip = "";
1358     +if($dbtype == DB_PGSQL) {
1359     while ($row = pg_fetch_array($result))
1360     {
1361     if ($row['ip'] != $last_ip)
1362     @@ -132,19 +190,82 @@
1363     $xint = (int) $x;
1364    
1365     //echo "xint: ".$xint."<br>";
1366     + if(!isset($Count))
1367     + $Count = array();
1368     + if(!isset($Count[$xint]))
1369     + $Count[$xint] = 0;
1370     + $Count[$xint]++;
1371     +
1372     + if ($row['total']/$row['sample_duration'] > $SentPeak)
1373     + $SentPeak = $row['total']/$row['sample_duration'];
1374     + $TotalSent += $row['total'];
1375     + if(!isset($total[$xint]))
1376     + $total[$xint] = 0;
1377     + $total[$xint] += $row['total']/$row['sample_duration'];
1378     + if(!isset($icmp[$xint]))
1379     + $icmp[$xint] = 0;
1380     + $icmp[$xint] += $row['icmp']/$row['sample_duration'];
1381     + if(!isset($udp[$xint]))
1382     + $udp[$xint] = 0;
1383     + $udp[$xint] += $row['udp']/$row['sample_duration'];
1384     + if(!isset($tcp[$xint]))
1385     + $tcp[$xint] = 0;
1386     + $tcp[$xint] += $row['tcp']/$row['sample_duration'];
1387     + if(!isset($ftp[$xint]))
1388     + $ftp[$xint] = 0;
1389     + $ftp[$xint] += $row['ftp']/$row['sample_duration'];
1390     + if(!isset($http[$xint]))
1391     + $http[$xint] = 0;
1392     + $http[$xint] += $row['http']/$row['sample_duration'];
1393     + if(!isset($p2p[$xint]))
1394     + $p2p[$xint] = 0;
1395     + $p2p[$xint] += $row['p2p']/$row['sample_duration'];
1396     + }
1397     +} else if($dbtype == DB_MYSQL) {
1398     +while ($row = mysql_fetch_array($result))
1399     + {
1400     + if ($row['ip'] != $last_ip)
1401     + {
1402     + AverageAndAccumulate();
1403     + $last_ip = $row['ip'];
1404     + }
1405     +
1406     + $x = ($row['ts']-$timestamp)*(($width-XOFFSET)/$interval)+XOFFSET;
1407     + $xint = (int) $x;
1408     +
1409     + //echo "xint: ".$xint."<br>";
1410     + if(!isset($Count))
1411     + $Count = array();
1412     + if(!isset($Count[$xint]))
1413     + $Count[$xint] = 0;
1414     $Count[$xint]++;
1415    
1416     if ($row['total']/$row['sample_duration'] > $SentPeak)
1417     $SentPeak = $row['total']/$row['sample_duration'];
1418     $TotalSent += $row['total'];
1419     + if(!isset($total[$xint]))
1420     + $total[$xint] = 0;
1421     $total[$xint] += $row['total']/$row['sample_duration'];
1422     + if(!isset($icmp[$xint]))
1423     + $icmp[$xint] = 0;
1424     $icmp[$xint] += $row['icmp']/$row['sample_duration'];
1425     + if(!isset($udp[$xint]))
1426     + $udp[$xint] = 0;
1427     $udp[$xint] += $row['udp']/$row['sample_duration'];
1428     + if(!isset($tcp[$xint]))
1429     + $tcp[$xint] = 0;
1430     $tcp[$xint] += $row['tcp']/$row['sample_duration'];
1431     + if(!isset($ftp[$xint]))
1432     + $ftp[$xint] = 0;
1433     $ftp[$xint] += $row['ftp']/$row['sample_duration'];
1434     + if(!isset($http[$xint]))
1435     + $http[$xint] = 0;
1436     $http[$xint] += $row['http']/$row['sample_duration'];
1437     + if(!isset($p2p[$xint]))
1438     + $p2p[$xint] = 0;
1439     $p2p[$xint] += $row['p2p']/$row['sample_duration'];
1440     }
1441     +}
1442    
1443     // One more time for the last IP
1444     AverageAndAccumulate();
1445     diff -ruN bandwidthd/phphtdocs/include.php bandwidthd-mysql-20050912/phphtdocs/include.php
1446     --- bandwidthd/phphtdocs/include.php 2005-09-23 16:08:12.000000000 +0200
1447     +++ bandwidthd-mysql-20050912/phphtdocs/include.php 2005-08-30 23:18:22.000000000 +0200
1448     @@ -21,20 +21,36 @@
1449     define("XOFFSET", 90);
1450     define("YOFFSET", 45);
1451    
1452     +define("DB_PGSQL", 1);
1453     +define("DB_MYSQL", 2);
1454     +
1455     require("config.conf");
1456    
1457     function ConnectDb()
1458     - {
1459     - global $db_connect_string;
1460     +{
1461     + global $dbtype;
1462     + global $pgsql_connect_string;
1463     + global $mysql_host, $mysql_user, $mysql_pass, $mysql_dbname;
1464     +
1465     + if($dbtype == DB_PGSQL)
1466     + $db = pg_pconnect($pgsql_connect_string);
1467     + else if($dbtype == DB_MYSQL)
1468     + $db = mysql_connect($mysql_host, $mysql_user, $mysql_pass);
1469     + else {
1470     + printf("DB Error, unknown database type");
1471     + exit(1);
1472     + }
1473     +
1474     + if (!$db) {
1475     + printf("DB Error, could not connect to database");
1476     + exit(1);
1477     + }
1478     +
1479     + if($dbtype == DB_MYSQL)
1480     + mysql_select_db($mysql_dbname);
1481    
1482     - $db = pg_pconnect($db_connect_string);
1483     - if (!$db)
1484     - {
1485     - printf("DB Error, could not connect to database");
1486     - exit(1);
1487     - }
1488     - return($db);
1489     - }
1490     + return($db);
1491     +}
1492    
1493     function fmtb($kbytes)
1494     {
1495     @@ -63,6 +79,74 @@
1496     return(sprintf("<td align=right><tt>%.1f%s</td>", $Output, $Suffix));
1497     }
1498    
1499     +$masks = array(0 => "0.0.0.0",
1500     + 1 => "128.0.0.0",
1501     + 2 => "192.0.0.0",
1502     + 3 => "224.0.0.0",
1503     + 4 => "240.0.0.0",
1504     + 5 => "248.0.0.0",
1505     + 6 => "252.0.0.0",
1506     + 7 => "254.0.0.0",
1507     + 8 => "255.0.0.0",
1508     + 9 => "255.128.0.0",
1509     + 10 => "255.192.0.0",
1510     + 11 => "255.224.0.0",
1511     + 12 => "255.240.0.0",
1512     + 13 => "255.248.0.0",
1513     + 14 => "255.252.0.0",
1514     + 15 => "255.254.0.0",
1515     + 16 => "255.255.0.0",
1516     + 17 => "255.255.128.0",
1517     + 18 => "255.255.192.0",
1518     + 19 => "255.255.224.0",
1519     + 20 => "255.255.240.0",
1520     + 21 => "255.255.248.0",
1521     + 22 => "255.255.252.0",
1522     + 23 => "255.255.254.0",
1523     + 24 => "255.255.255.0",
1524     + 25 => "255.255.255.128",
1525     + 26 => "255.255.255.192",
1526     + 27 => "255.255.255.224",
1527     + 28 => "255.255.255.240",
1528     + 29 => "255.255.255.248",
1529     + 30 => "255.255.255.252",
1530     + 31 => "255.255.255.254",
1531     + 32 => "255.255.255.255");
1532     +
1533     +function parse_addr($addr)
1534     +{
1535     + global $masks;
1536     +
1537     + if(!$addr)
1538     + return array("ip" => 0, "mask" => 0);
1539     +
1540     + $pos = strpos($addr, "/");
1541     + if(!$pos) {
1542     + $ip = $addr;
1543     + $mask = "255.255.255.255";
1544     + }
1545     + else {
1546     + $ip = substr($addr, 0, $pos);
1547     + $mask = substr($addr, $pos+1);
1548     + if(!strpos($mask, "."))
1549     + $mask = $masks[(int)$mask];
1550     + }
1551     +
1552     + return array("ip" => ip2long($ip), "mask" => ip2long($mask));
1553     +}
1554     +
1555     +function bd_escape_string($string)
1556     +{
1557     + global $dbtype;
1558     +
1559     + if($dbtype == DB_PGSQL)
1560     + return pg_escape_string($string);
1561     + else if($dbtype == DB_MYSQL)
1562     + return mysql_real_escape_string($string);
1563     + else
1564     + return $string;
1565     +}
1566     +
1567     $starttime = time();
1568     set_time_limit(300);
1569     -?>
1570     \ No newline at end of file
1571     +?>
1572     diff -ruN bandwidthd/phphtdocs/index.php bandwidthd-mysql-20050912/phphtdocs/index.php
1573     --- bandwidthd/phphtdocs/index.php 2005-09-23 16:08:12.000000000 +0200
1574     +++ bandwidthd-mysql-20050912/phphtdocs/index.php 2005-09-09 23:46:02.000000000 +0200
1575     @@ -4,6 +4,8 @@
1576    
1577     // Get variables from url
1578    
1579     +$sensor_name = "";
1580     +
1581     if (isset($_GET['sensor_name']) && $_GET['sensor_name'] != "none")
1582     $sensor_name = $_GET['sensor_name'];
1583    
1584     @@ -19,27 +21,61 @@
1585     if (isset($_GET['limit']) && $_GET['limit'] != "none")
1586     $limit = $_GET['limit'];
1587    
1588     -
1589     $db = ConnectDb();
1590     ?>
1591     -<FORM name="navigation" method=get action=<?=$PHP_SELF?>>
1592     +<FORM name="navigation" method=get action=<?=$_SERVER["PHP_SELF"]?>>
1593     <table width=100% cellspacing=0 cellpadding=5 border=1>
1594     <tr>
1595     <td>
1596     <?
1597     -$sql = "SELECT sensor_name from sensors order by sensor_name;";
1598     -$result = @pg_query($sql);
1599     -if (!$result)
1600     - {
1601     - echo "<center>Collecting data...</center>";
1602     - exit;
1603     - }
1604     +if($dbtype == DB_PGSQL) {
1605     + $sql = "SELECT sensor_id,sensor_name,to_char(last_connection, 'Dy Mon FMDD HH24:MI:SS YYYY') as last_connection FROM sensors ORDER BY sensor_name;";
1606     + $result = @pg_query($sql);
1607     +}
1608     +else if($dbtype == DB_MYSQL) {
1609     + $sql = "SELECT sensor_id,sensor_name,DATE_FORMAT(last_connection, '%a %b %e %k:%i:%s %Y') AS last_connection FROM sensors ORDER BY sensor_name";
1610     + $result = @mysql_query($sql);
1611     +}
1612     +else {
1613     + echo "<center>DB Error, unknown database type</center>";
1614     + exit;
1615     +}
1616     +if (!$result) {
1617     + echo "<center>Collecting data...</center>";
1618     + exit;
1619     +}
1620     ?>
1621     <SELECT name="sensor_name">
1622     <OPTION value="none">--Select A Sensor--
1623     <?
1624     -while ($r = pg_fetch_array($result))
1625     +if($dbtype == DB_PGSQL) {
1626     + while ($r = pg_fetch_array($result)) {
1627     + if($sensor_name == $r['sensor_name']) {
1628     + $last = $r['last_connection'];
1629     + $sensor_id = $r['sensor_id'];
1630     + }
1631     + echo "<option value=\"".$r['sensor_name']."\" ".($sensor_name==$r['sensor_name']?"SELECTED":"").">".$r['sensor_name']."\n";
1632     + }
1633     +} else if($dbtype = DB_MYSQL) {
1634     + while ($r = mysql_fetch_array($result)) {
1635     + if($sensor_name == $r['sensor_name']) {
1636     + $last = $r['last_connection'];
1637     + $sensor_id = $r['sensor_id'];
1638     + }
1639     echo "<option value=\"".$r['sensor_name']."\" ".($sensor_name==$r['sensor_name']?"SELECTED":"").">".$r['sensor_name']."\n";
1640     + }
1641     +}
1642     +?>
1643     +<?
1644     +// Set defaults
1645     +if (!isset($interval))
1646     + $interval = DFLT_INTERVAL;
1647     +
1648     +if (!isset($timestamp))
1649     + $timestamp = time() - $interval + (0.05*$interval);
1650     +
1651     +if (!isset($limit))
1652     + $limit = 20;
1653     ?>
1654     </SELECT>
1655     <td><SELECT name="interval">
1656     @@ -65,20 +101,15 @@
1657     </table>
1658     </FORM>
1659     <?
1660     -// Set defaults
1661     -if (!isset($interval))
1662     - $interval = DFLT_INTERVAL;
1663     -
1664     -if (!isset($timestamp))
1665     - $timestamp = time() - $interval + (0.05*$interval);
1666     -
1667     -if (!isset($limit))
1668     - $limit = 20;
1669     -
1670     // Validation
1671     -if (!isset($sensor_name))
1672     +if (!isset($sensor_name) || !$sensor_name)
1673     exit(0);
1674    
1675     +if(!isset($sensor_id)) {
1676     + echo "<center>No such sensor</center>\n";
1677     + exit(0);
1678     +}
1679     +
1680     // Print Title
1681    
1682     if (isset($limit))
1683     @@ -86,12 +117,27 @@
1684     else
1685     echo "<h2>All Records - $sensor_name</h2>";
1686    
1687     +if(isset($last))
1688     + echo "Last connection: " . $last . "</BR>\n";
1689     +
1690     // Sqlize the incomming variables
1691     -if (isset($subnet))
1692     - $sql_subnet = "and ip <<= '$subnet'";
1693     +if($dbtype == DB_PGSQL) {
1694     + $sql_subnet = "and ip <<= '$subnet'";
1695     +} else if($dbtype == DB_MYSQL) {
1696     + $p = parse_addr($subnet);
1697     + if($p["mask"] == ip2long("255.255.255.255")) {
1698     + $sql_subnet = "and ip = " .sprintf("%u", $p["ip"]);
1699     + } else if($p["mask"] == 0) {
1700     + $sql_subnet = "";
1701     + } else {
1702     + $net = $p["ip"] & $p["mask"];
1703     + $bcast = $net | ~$p["mask"];
1704     + $sql_subnet = "and ip between ".sprintf("%u", $net)." and ".sprintf("%u",$bcast);
1705     + }
1706     +}
1707    
1708     // Sql Statement
1709     -$sql = "select tx.ip, rx.scale as rxscale, tx.scale as txscale, tx.total+rx.total as total, tx.total as sent,
1710     +$pg_sql = "select tx.ip, rx.scale as rxscale, tx.scale as txscale, tx.total+rx.total as total, tx.total as sent,
1711     rx.total as received, tx.tcp+rx.tcp as tcp, tx.udp+rx.udp as udp,
1712     tx.icmp+rx.icmp as icmp, tx.http+rx.http as http,
1713     tx.p2p+rx.p2p as p2p, tx.ftp+rx.ftp as ftp
1714     @@ -99,18 +145,16 @@
1715    
1716     (SELECT ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1717     sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1718     -from sensors, bd_tx_log
1719     -where sensor_name = '$sensor_name'
1720     -and sensors.sensor_id = bd_tx_log.sensor_id
1721     +from bd_tx_log
1722     +where sensor_id = $sensor_id
1723     $sql_subnet
1724     and timestamp > $timestamp::abstime and timestamp < ".($timestamp+$interval)."::abstime
1725     group by ip) as tx,
1726    
1727     (SELECT ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1728     sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1729     -from sensors, bd_rx_log
1730     -where sensor_name = '$sensor_name'
1731     -and sensors.sensor_id = bd_rx_log.sensor_id
1732     +from bd_rx_log
1733     +where sensor_id = $sensor_id
1734     $sql_subnet
1735     and timestamp > $timestamp::abstime and timestamp < ".($timestamp+$interval)."::abstime
1736     group by ip) as rx
1737     @@ -118,13 +162,46 @@
1738     where tx.ip = rx.ip
1739     order by total desc;";
1740    
1741     -//echo "</center><pre>$sql</pre><center>"; exit(0);
1742     -pg_query("SET sort_mem TO 30000;");
1743     -$result = pg_query($sql);
1744     -pg_query("set sort_mem to default;");
1745     +$my_sql = "select inet_ntoa(tx.ip) as ip, rx.scale as rxscale, tx.scale as txscale, tx.total+rx.total as total, tx.total as sent,
1746     +rx.total as received, tx.tcp+rx.tcp as tcp, tx.udp+rx.udp as udp,
1747     +tx.icmp+rx.icmp as icmp, tx.http+rx.http as http,
1748     +tx.p2p+rx.p2p as p2p, tx.ftp+rx.ftp as ftp
1749     +from
1750    
1751     -if ($limit == "all")
1752     - $limit = pg_num_rows($result);
1753     +(SELECT ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1754     +sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1755     +from bd_tx_log
1756     +where sensor_id = $sensor_id
1757     +$sql_subnet
1758     +and unix_timestamp(timestamp) > $timestamp and unix_timestamp(timestamp) < ".($timestamp+$interval)."
1759     +group by ip) as tx,
1760     +
1761     +(SELECT ip, max(total/sample_duration)*8 as scale, sum(total) as total, sum(tcp) as tcp, sum(udp) as udp, sum(icmp) as icmp,
1762     +sum(http) as http, sum(p2p) as p2p, sum(ftp) as ftp
1763     +from bd_rx_log
1764     +where sensor_id = $sensor_id
1765     +$sql_subnet
1766     +and unix_timestamp(timestamp) > $timestamp and unix_timestamp(timestamp) < ".($timestamp+$interval)."
1767     +group by ip) as rx
1768     +
1769     +where tx.ip = rx.ip
1770     +order by total desc";
1771     +
1772     +//echo "</center><pre>$my_sql</pre><center>"; exit(0);
1773     +if($dbtype == DB_PGSQL) {
1774     + pg_query("SET sort_mem TO 30000;");
1775     + $result = pg_query($pg_sql);
1776     +} else if($dbtype == DB_MYSQL)
1777     + $result = mysql_query($my_sql);
1778     +if($dbtype == DB_PGSQL)
1779     + pg_query("set sort_mem to default;");
1780     +
1781     +if ($limit == "all") {
1782     + if($dbtype == DB_PGSQL)
1783     + $limit = pg_num_rows($result);
1784     + else if($dbtype == DB_MYSQL)
1785     + $limit = mysql_num_rows($result);
1786     +}
1787    
1788     echo "<table width=100% border=1 cellspacing=0><tr><td>Ip<td>Name<td>Total<td>Sent<td>Received<td>tcp<td>udp<td>icmp<td>http<td>p2p<td>ftp";
1789    
1790     @@ -132,19 +209,27 @@
1791     $subnet = "0.0.0.0/0";
1792    
1793     // Output Total Line
1794     -echo "<TR><TD><a href=Total>Total</a><TD>$subnet";
1795     -foreach (array("total", "sent", "received", "tcp", "udp", "icmp", "http", "p2p", "ftp") as $key)
1796     - {
1797     - for($Counter=0, $Total = 0; $Counter < pg_num_rows($result); $Counter++)
1798     - {
1799     - $r = pg_fetch_array($result, $Counter);
1800     - $Total += $r[$key];
1801     - }
1802     - echo fmtb($Total);
1803     - }
1804     +echo "<TR><TD><a href=\"#Total\">Total</a><TD>$subnet";
1805     +foreach (array("total", "sent", "received", "tcp", "udp", "icmp", "http", "p2p", "ftp") as $key) {
1806     + if($dbtype == DB_PGSQL) {
1807     + for($Counter=0, $Total = 0; $Counter < pg_num_rows($result); $Counter++) {
1808     + $r = pg_fetch_array($result, $Counter);
1809     + $Total += $r[$key];
1810     + }
1811     + } else if($dbtype == DB_MYSQL) {
1812     + if(mysql_num_rows($result) > 0)
1813     + mysql_data_seek($result, 0);
1814     + for($Counter = 0, $Total = 0; $Counter < mysql_num_rows($result); $Counter++) {
1815     + $r = mysql_fetch_array($result);
1816     + $Total += $r[$key];
1817     + }
1818     + }
1819     + echo fmtb($Total);
1820     +}
1821     echo "\n";
1822    
1823     // Output Other Lines
1824     +if($dbtype == DB_PGSQL) {
1825     for($Counter=0; $Counter < pg_num_rows($result) && $Counter < $limit; $Counter++)
1826     {
1827     $r = pg_fetch_array($result, $Counter);
1828     @@ -155,15 +240,39 @@
1829     fmtb($r['tcp']).fmtb($r['udp']).fmtb($r['icmp']).fmtb($r['http']).
1830     fmtb($r['p2p']).fmtb($r['ftp'])."\n";
1831     }
1832     +} else if($dbtype == DB_MYSQL) {
1833     +if(mysql_num_rows($result) > 0)
1834     + mysql_data_seek($result, 0);
1835     +for($Counter=0; $Counter < mysql_num_rows($result) && $Counter < $limit; $Counter++)
1836     + {
1837     + $r = mysql_fetch_array($result);
1838     + echo "<tr><td><a href=#".$r['ip'].">";
1839     + echo $r['ip']."<td>".gethostbyaddr($r['ip']);
1840     + echo "</a>";
1841     + echo fmtb($r['total']).fmtb($r['sent']).fmtb($r['received']).
1842     + fmtb($r['tcp']).fmtb($r['udp']).fmtb($r['icmp']).fmtb($r['http']).
1843     + fmtb($r['p2p']).fmtb($r['ftp'])."\n";
1844     + }
1845     +}
1846     echo "</table></center>";
1847    
1848     // Output Total Graph
1849     -for($Counter=0, $Total = 0; $Counter < pg_num_rows($result); $Counter++)
1850     - {
1851     - $r = pg_fetch_array($result, $Counter);
1852     - $scale = max($r['txscale'], $scale);
1853     - $scale = max($r['rxscale'], $scale);
1854     - }
1855     +//$scale = 0;
1856     +//if($dbtype == DB_PGSQL) {
1857     +// for($Counter=0; $Counter < pg_num_rows($result); $Counter++) {
1858     +// $r = pg_fetch_array($result, $Counter);
1859     +// $scale = max($r['txscale'], $scale);
1860     +// $scale = max($r['rxscale'], $scale);
1861     +// }
1862     +//} else if($dbtype == DB_MYSQL) {
1863     +// if(mysql_num_rows($result) > 0)
1864     +// mysql_data_seek($result, 0);
1865     +// for($Counter = 0; $Counter < mysql_num_rows($result); $Counter++) {
1866     +// $r = mysql_fetch_array($result);
1867     +// $scale = max($r['txscale'], $scale);
1868     +// $scale = max($r['rxscale'], $scale);
1869     +// }
1870     +//}
1871    
1872     if ($subnet == "0.0.0.0/0")
1873     $total_table = "bd_tx_total_log";
1874     @@ -174,7 +283,7 @@
1875     echo "</a>";
1876     echo "Send:<br><img src=graph.php?ip=$subnet&interval=$interval&sensor_name=".$sensor_name."&table=$total_table><br>";
1877     echo "<img src=legend.gif><br>\n";
1878     -if ($subnet == "0.0.0.0/0")
1879     +if ($subnet == "0.0.0.0/0" || $subnet == "0/0")
1880     $total_table = "bd_rx_total_log";
1881     else
1882     $total_table = "bd_rx_log";
1883     @@ -183,6 +292,7 @@
1884    
1885    
1886     // Output Other Graphs
1887     +if($dbtype == DB_PGSQL) {
1888     for($Counter=0; $Counter < pg_num_rows($result) && $Counter < $limit; $Counter++)
1889     {
1890     $r = pg_fetch_array($result, $Counter);
1891     @@ -197,5 +307,24 @@
1892     echo "Receive:<br><img src=graph.php?ip=".$r['ip']."&interval=$interval&sensor_name=".$sensor_name."&table=bd_rx_log&yscale=".(max($r['txscale'], $r['rxscale']))."><br>";
1893     echo "<img src=legend.gif><br>\n";
1894     }
1895     +} else if($dbtype == DB_MYSQL) {
1896     +if(mysql_num_rows($result) > 0)
1897     + mysql_data_seek($result, 0);
1898     +for($Counter=0; $Counter < mysql_num_rows($result) && $Counter < $limit; $Counter++)
1899     + {
1900     + $r = mysql_fetch_array($result);
1901     + echo "<a name=".$r['ip']."><h3><a href=details.php?sensor_name=$sensor_name&ip=".$r['ip'].">";
1902     + if ($r['ip'] == "0.0.0.0")
1903     + echo "Total - Total of all subnets</h3>";
1904     + else
1905     + echo $r['ip']." - ".gethostbyaddr($r['ip'])."</h3>";
1906     + echo "</a>";
1907     + echo "Send:<br><img src=graph.php?ip=".$r['ip']."&interval=$interval&sensor_name=".$sensor_name."&table=bd_tx_log&yscale=".(max($r['txscale'], $r['rxscale']))."><br>";
1908     + echo "<img src=legend.gif><br>\n";
1909     + echo "Receive:<br><img src=graph.php?ip=".$r['ip']."&interval=$interval&sensor_name=".$sensor_name."&table=bd_rx_log&yscale=".(max($r['txscale'], $r['rxscale']))."><br>";
1910     + echo "<img src=legend.gif><br>\n";
1911     + }
1912     +}
1913    
1914     -include('footer.php');
1915     \ No newline at end of file
1916     +include('footer.php');
1917     +?>

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed