database connection
This commit is contained in:
parent
2db093ea7a
commit
a30314eb7a
2
Makefile
2
Makefile
|
@ -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
|
||||||
|
|
||||||
|
|
20
conntrack.c
20
conntrack.c
|
@ -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()");
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
69
database.c
69
database.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue