database connection

This commit is contained in:
Olaf Rempel 2007-03-25 15:24:47 +02:00
parent 2db093ea7a
commit a30314eb7a
6 changed files with 69 additions and 32 deletions

View File

@ -1,5 +1,5 @@
CFLAGS := -O2 -pipe -Wall CFLAGS := -O2 -pipe -Wall
LDFLAGS := -lpthread -lnfnetlink -lnetfilter_conntrack LDFLAGS := -lpthread -lnfnetlink -lnetfilter_conntrack -lmysqlclient
OBJS := configfile.o conntrack.o database.o hashtable.o logging.o ctstats.o OBJS := configfile.o conntrack.o database.o hashtable.o logging.o ctstats.o

View File

@ -2,6 +2,10 @@
#include <time.h> #include <time.h>
#include <pthread.h> #include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libnfnetlink/libnfnetlink.h> #include <libnfnetlink/libnfnetlink.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h> #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
@ -10,6 +14,7 @@
#include "hashtable.h" #include "hashtable.h"
#define DEFAULT_HASHSIZE 127 #define DEFAULT_HASHSIZE 127
#define DEFAULT_NETMASK "255.255.255.255"
static pthread_t ct_thread; static pthread_t ct_thread;
@ -17,6 +22,7 @@ static struct nfct_handle *cth;
static struct hash_table *table[2]; static struct hash_table *table[2];
static int hash_select = 0; static int hash_select = 0;
static struct in_addr netmask;
static int conntrack_event_cb(void *arg, unsigned int flags, int type, void *privdata) static int conntrack_event_cb(void *arg, unsigned int flags, int type, void *privdata)
{ {
@ -31,7 +37,7 @@ static int conntrack_event_cb(void *arg, unsigned int flags, int type, void *pri
return -1; return -1;
} }
entry->src_ip = ct->tuple[NFCT_DIR_ORIGINAL].src.v4; entry->src_ip = (ct->tuple[NFCT_DIR_ORIGINAL].src.v4 & netmask.s_addr);
entry->protonum = ct->tuple[NFCT_DIR_ORIGINAL].protonum; entry->protonum = ct->tuple[NFCT_DIR_ORIGINAL].protonum;
entry->dst_port = ct->tuple[NFCT_DIR_ORIGINAL].l4dst.tcp.port; entry->dst_port = ct->tuple[NFCT_DIR_ORIGINAL].l4dst.tcp.port;
@ -42,7 +48,7 @@ static int conntrack_event_cb(void *arg, unsigned int flags, int type, void *pri
return 0; return 0;
} }
int conntrack_dump_hash(void (*callback)(struct hash_entry *entry, void *privdata), void *privdata) struct hash_table * conntrack_get_hash(void)
{ {
/* /*
* switch hashtable * switch hashtable
@ -52,13 +58,17 @@ int conntrack_dump_hash(void (*callback)(struct hash_entry *entry, void *privdat
*/ */
int used_hash = hash_select; int used_hash = hash_select;
hash_select ^= 0x01; hash_select ^= 0x01;
return table[used_hash];
purge_hash(table[used_hash], callback, privdata);
return 0;
} }
int conntrack_init(void) int conntrack_init(void)
{ {
char *mask = config_get_string("global", "netmask", DEFAULT_NETMASK);
if (inet_aton(mask, &netmask) == 0) {
log_print(LOG_ERROR, "conntrack_init: invalid netmask");
return -1;
}
cth = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_DESTROY); cth = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_DESTROY);
if (cth == NULL) { if (cth == NULL) {
log_print(LOG_ERROR, "conntrack_init: nfct_open()"); log_print(LOG_ERROR, "conntrack_init: nfct_open()");

View File

@ -7,6 +7,6 @@ int conntrack_init(void);
int conntrack_start_event_thread(void); int conntrack_start_event_thread(void);
int conntrack_close(void); int conntrack_close(void);
int conntrack_dump_hash(void (*callback)(struct hash_entry *entry, void *privdata), void *privdata); struct hash_table * conntrack_get_hash(void);
#endif // _CONNTRACK_H_ #endif // _CONNTRACK_H_

View File

@ -61,7 +61,7 @@ int main(int argc, char *argv[])
if (config_parse(config)) if (config_parse(config))
exit(1); exit(1);
/* init netlink, hashtables, mutexes */ /* init netlink & hashtables */
if (conntrack_init()) if (conntrack_init())
exit(1); exit(1);
@ -71,13 +71,14 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
/* start event listener */
conntrack_start_event_thread(); conntrack_start_event_thread();
int intervall = config_get_int("global", "intervall", DEFAULT_INTERVALL); int intervall = config_get_int("global", "intervall", DEFAULT_INTERVALL);
while (1) { while (1) {
sleep(intervall); sleep(intervall);
/* fill database */ /* parse hashes, fill database */
database_analyse(); database_analyse();
} }

View File

@ -1,10 +1,11 @@
[global] [global]
intervall 30 intervall 30
hashsize 127 hashsize 127
netmask 255.255.255.255
logfile ctstats.log logfile ctstats.log
[mysql] [mysql]
hostname localhost hostname cinnagar.lan
username ctstats username ctstats
password ctstats password ctstats
database ctstats database ctstats

View File

@ -1,52 +1,77 @@
#include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <mysql/mysql.h>
#include "configfile.h"
#include "conntrack.h" #include "conntrack.h"
#include "database.h" #include "database.h"
#include "hashtable.h" #include "hashtable.h"
#include "logging.h" #include "logging.h"
static MYSQL *dbh;
static void purge_hash_cb(struct hash_entry *entry, void *privdata) static void purge_hash_cb(struct hash_entry *entry, void *privdata)
{ {
struct in_addr src_ip = { .s_addr = entry->src_ip }; struct in_addr src_ip = { .s_addr = entry->src_ip };
char *proto; char query[256];
switch (entry->protonum) { int len = snprintf(query, sizeof(query),
case IPPROTO_TCP: "INSERT INTO stats SET srcip='%s', proto='%u', dport='%u', srcbytes='%llu', dstbytes='%llu', count='%u'",
proto = "tcp "; inet_ntoa(src_ip), entry->protonum, ntohs(entry->dst_port),
break;
case IPPROTO_UDP:
proto = "udp ";
break;
case IPPROTO_ICMP:
proto = "icmp";
break;
default:
proto = "unkn";
break;
}
log_print(LOG_DEBUG, "%4s %15s:%5d -> %8llu / %8llu (%u)",
proto, inet_ntoa(src_ip), ntohs(entry->dst_port),
entry->src_bytes, entry->dst_bytes, entry->count); entry->src_bytes, entry->dst_bytes, entry->count);
if (mysql_real_query(dbh, query, len +1) != 0)
log_print(LOG_WARN, "purge_hash_cb: mysql_real_query(): %s", mysql_error(dbh));
log_print(LOG_DEBUG, query);
} }
int database_analyse(void) int database_analyse(void)
{ {
conntrack_dump_hash(purge_hash_cb, NULL); struct hash_table *hash = conntrack_get_hash();
if (mysql_ping(dbh) != 0) {
log_print(LOG_WARN, "database_analyse: mysql_ping(): %s", mysql_error(dbh));
purge_hash(hash, NULL, NULL);
return 0;
}
purge_hash(hash, purge_hash_cb, NULL);
return 0; return 0;
} }
int database_init(void) int database_init(void)
{ {
dbh = mysql_init(NULL);
if (dbh == NULL) {
log_print(LOG_ERROR, "database_init: mysql_init(): %s", mysql_error(dbh));
return -1;
}
char *hostname = config_get_string("mysql", "hostname", NULL);
char *username = config_get_string("mysql", "username", NULL);
char *password = config_get_string("mysql", "password", NULL);
MYSQL *ret = mysql_real_connect(dbh, hostname, username, password, NULL, 0, NULL, 0);
if (ret != dbh) {
log_print(LOG_ERROR, "database_init: mysql_real_connect(): %s", mysql_error(dbh));
mysql_close(dbh);
return -1;
}
char *database = config_get_string("mysql", "database", NULL);
if (mysql_select_db(dbh, database) != 0) {
log_print(LOG_ERROR, "database_init: mysql_select_db(): %s", mysql_error(dbh));
mysql_close(dbh);
return -1;
}
return 0; return 0;
} }
int database_close(void) int database_close(void)
{ {
mysql_close(dbh);
return 0; return 0;
} }