This commit is contained in:
Olaf Rempel 2007-03-31 21:16:52 +02:00
parent 7bdc6e0774
commit 0cf8957c81
9 changed files with 106 additions and 64 deletions

View File

@ -36,13 +36,13 @@
struct conf_section { struct conf_section {
struct list_head list; struct list_head list;
struct list_head tupel_list; struct list_head tupel_list;
char *name; const char *name;
}; };
struct conf_tupel { struct conf_tupel {
struct list_head list; struct list_head list;
char *option; const char *option;
char *parameter; const char *parameter;
}; };
static LIST_HEAD(config_list); static LIST_HEAD(config_list);
@ -142,6 +142,23 @@ int config_parse(const char *config)
return 0; return 0;
} }
void config_free(void)
{
struct conf_section *section, *section_tmp;
struct conf_tupel *tupel, *tupel_tmp;
list_for_each_entry_safe(section, section_tmp, &config_list, list) {
list_for_each_entry_safe(tupel, tupel_tmp, &section->tupel_list, list) {
list_del(&tupel->list);
free((char *)tupel->option);
free((char *)tupel->parameter);
free(tupel);
}
list_del(&section->list);
free(section);
}
}
static struct conf_section * config_get_section(const char *name) static struct conf_section * config_get_section(const char *name)
{ {
struct conf_section *section; struct conf_section *section;
@ -153,7 +170,7 @@ static struct conf_section * config_get_section(const char *name)
return NULL; return NULL;
} }
char * config_get_string(const char *section_str, const char *option, char *def) const char * config_get_string(const char *section_str, const char *option, const char *def)
{ {
struct conf_section *section = config_get_section(section_str); struct conf_section *section = config_get_section(section_str);
if (section != NULL) { if (section != NULL) {
@ -172,7 +189,7 @@ char * config_get_string(const char *section_str, const char *option, char *def)
int config_get_int(const char *section, const char *option, int def) int config_get_int(const char *section, const char *option, int def)
{ {
char *ret = config_get_string(section, option, NULL); const char *ret = config_get_string(section, option, NULL);
if (ret == NULL) { if (ret == NULL) {
log_print(LOG_WARN, "config [%s:%s] not found, using default: '%d'", log_print(LOG_WARN, "config [%s:%s] not found, using default: '%d'",
section, option, def); section, option, def);

View File

@ -1,11 +1,10 @@
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
#include <netinet/in.h>
int config_parse(const char *config); int config_parse(const char *config);
void config_free(void);
char * config_get_string(const char *section_str, const char *option, char *def); const char * config_get_string(const char *section_str, const char *option, const char *def);
int config_get_int(const char *section, const char *option, int def); int config_get_int(const char *section, const char *option, int def);

View File

@ -63,7 +63,7 @@ struct hash_table * conntrack_get_hash(void)
int conntrack_init(void) int conntrack_init(void)
{ {
char *mask = config_get_string("global", "netmask", DEFAULT_NETMASK); const char *mask = config_get_string("global", "netmask", DEFAULT_NETMASK);
if (inet_aton(mask, &netmask) == 0) { if (inet_aton(mask, &netmask) == 0) {
log_print(LOG_ERROR, "conntrack_init: invalid netmask"); log_print(LOG_ERROR, "conntrack_init: invalid netmask");
return -1; return -1;
@ -116,6 +116,9 @@ int conntrack_start_event_thread(void)
int conntrack_close(void) int conntrack_close(void)
{ {
if (ct_thread)
pthread_cancel(ct_thread);
destroy_hash(table[1]); destroy_hash(table[1]);
destroy_hash(table[0]); destroy_hash(table[0]);

View File

@ -4,6 +4,8 @@
#include <string.h> #include <string.h>
#include <getopt.h> #include <getopt.h>
#include <signal.h>
#include <errno.h>
#include "configfile.h" #include "configfile.h"
#include "conntrack.h" #include "conntrack.h"
@ -21,6 +23,13 @@ static struct option opts[] = {
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
static int sig_received = 0;
static void my_sighandler(int s)
{
sig_received = 1;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *config = DEFAULT_CONFIG; char *config = DEFAULT_CONFIG;
@ -72,29 +81,41 @@ int main(int argc, char *argv[])
} }
/* check logfile */ /* check logfile */
char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE); const char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE);
if (logfile != NULL && debug == 0) { if (logfile != NULL && debug == 0) {
/* start logging */ /* start logging */
if (!log_init(logfile)) if (log_init(logfile))
exit(1); exit(1);
/* zum daemon mutieren */ /* zum daemon mutieren */
daemon(-1, 0); daemon(-1, 0);
} }
log_print(LOG_EVERYTIME, "ctstats started (pid: %d)", getpid());
signal(SIGINT, my_sighandler);
signal(SIGTERM, my_sighandler);
/* start event listener */ /* 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) {
sleep(intervall);
/* parse hashes, fill database */ struct timeval tv;
tv.tv_sec = intervall;
tv.tv_usec = 0;
while (sig_received == 0) {
select(0, NULL, NULL, NULL, &tv);
errno = 0;
tv.tv_sec = intervall;
tv.tv_usec = 0;
database_analyse(); database_analyse();
} }
/* how to stop? */
database_close(); database_close();
conntrack_close(); conntrack_close();
log_close();
return 0; return 0;
} }

View File

@ -13,7 +13,7 @@
static MYSQL *dbh; static MYSQL *dbh;
static void purge_hash_cb(struct hash_entry *entry, void *privdata) static void purge_hash_cb(const struct hash_entry *entry, void *privdata)
{ {
int long *now = (long *)privdata; int long *now = (long *)privdata;
char query[256]; char query[256];
@ -50,9 +50,9 @@ int database_init(void)
return -1; return -1;
} }
char *hostname = config_get_string("mysql", "hostname", NULL); const char *hostname = config_get_string("mysql", "hostname", NULL);
char *username = config_get_string("mysql", "username", NULL); const char *username = config_get_string("mysql", "username", NULL);
char *password = config_get_string("mysql", "password", NULL); const char *password = config_get_string("mysql", "password", NULL);
MYSQL *ret = mysql_real_connect(dbh, hostname, username, password, NULL, 0, NULL, 0); MYSQL *ret = mysql_real_connect(dbh, hostname, username, password, NULL, 0, NULL, 0);
if (ret != dbh) { if (ret != dbh) {
log_print(LOG_ERROR, "database_init: mysql_real_connect(): %s", mysql_error(dbh)); log_print(LOG_ERROR, "database_init: mysql_real_connect(): %s", mysql_error(dbh));
@ -60,7 +60,7 @@ int database_init(void)
return -1; return -1;
} }
char *database = config_get_string("mysql", "database", NULL); const char *database = config_get_string("mysql", "database", NULL);
if (mysql_select_db(dbh, database) != 0) { if (mysql_select_db(dbh, database) != 0) {
log_print(LOG_ERROR, "database_init: mysql_select_db(): %s", mysql_error(dbh)); log_print(LOG_ERROR, "database_init: mysql_select_db(): %s", mysql_error(dbh));
mysql_close(dbh); mysql_close(dbh);

View File

@ -41,7 +41,7 @@ struct hash_table * create_hash(uint32_t buckets)
} }
void purge_hash(struct hash_table *table, void purge_hash(struct hash_table *table,
void (*callback)(struct hash_entry *entry, void *privdata), void (*callback)(const struct hash_entry *entry, void *privdata),
void *privdata) void *privdata)
{ {
uint32_t i; uint32_t i;
@ -71,7 +71,7 @@ void destroy_hash(struct hash_table *table)
free(table); free(table);
} }
static uint32_t calc_hashkey(struct hash_entry *entry, uint32_t initval) static uint32_t calc_hashkey(const struct hash_entry *entry, uint32_t initval)
{ {
uint32_t a = entry->src_ip; uint32_t a = entry->src_ip;
uint32_t b = entry->protonum; uint32_t b = entry->protonum;
@ -86,7 +86,7 @@ static uint32_t calc_hashkey(struct hash_entry *entry, uint32_t initval)
return c; return c;
} }
static int cmp_entry(struct hash_entry *a, struct hash_entry *b) static int cmp_entry(const struct hash_entry *a, const struct hash_entry *b)
{ {
return (a->src_ip ^ b->src_ip) | return (a->src_ip ^ b->src_ip) |
(a->protonum ^ b->protonum) | (a->protonum ^ b->protonum) |

View File

@ -25,7 +25,7 @@ struct hash_table {
struct hash_table * create_hash(uint32_t buckets); struct hash_table * create_hash(uint32_t buckets);
void purge_hash(struct hash_table *table, void purge_hash(struct hash_table *table,
void (*callback)(struct hash_entry *entry, void *privdata), void (*callback)(const struct hash_entry *entry, void *privdata),
void *privdata); void *privdata);
void destroy_hash(struct hash_table *table); void destroy_hash(struct hash_table *table);

View File

@ -29,75 +29,74 @@
#define BUFSIZE 8192 #define BUFSIZE 8192
static FILE *log_fd = NULL; static FILE *log_fd = NULL;
static int log_prio = LOG_EVERYTIME;
static char *buffer = NULL; static char *buffer = NULL;
void log_print(int prio, const char *fmt, ...) int log_print(int prio, const char *fmt, ...)
{ {
va_list az; va_list az;
int len; int len = 0, retval;
if (prio < log_prio)
return 0;
if (buffer == NULL) { if (buffer == NULL) {
buffer = malloc(BUFSIZE); buffer = malloc(BUFSIZE);
if (buffer == NULL) { if (buffer == NULL) {
fprintf(stderr, "log_print: out of memory\nBailing out!\n"); fprintf(stderr, "log_print(): out of memory\n");
exit(-1); return -1;
} }
} }
if (log_fd != NULL) {
time_t tzgr;
time(&tzgr);
len += strftime(buffer, BUFSIZE, "%b %d %H:%M:%S :", localtime(&tzgr));
}
va_start(az, fmt); va_start(az, fmt);
len = vsnprintf(buffer, BUFSIZE, fmt, az); len += vsnprintf(buffer + len, BUFSIZE - len, fmt, az);
va_end(az); va_end(az);
if (len < 0 || len >= BUFSIZE) { if (len < 0 || len >= BUFSIZE) {
log_print(LOG_ERROR, "log_print: arguments too long");
errno = 0; errno = 0;
return; return log_print(LOG_ERROR, "log_print: arguments too long");
} }
if (errno) { if (errno) {
strncpy(buffer + len, ": ", BUFSIZE - len); len += snprintf(buffer + len, BUFSIZE - len, ": %s", strerror(errno));
len += 2; errno = 0;
strncpy(buffer + len, strerror(errno), BUFSIZE - len);
} }
if (log_fd) { retval = fprintf((log_fd ? log_fd : stderr), "%s\n", buffer);
char tbuf[64]; fflush(log_fd);
time_t tzgr; return retval;
time(&tzgr);
strftime(tbuf, sizeof(tbuf), "%b %d %H:%M:%S :", localtime(&tzgr));
fprintf(log_fd, "%s %s\n", tbuf, buffer);
fflush(log_fd);
} else {
fprintf(stderr, "%s\n", buffer);
}
errno = 0;
} }
static void log_close(void) void log_close(void)
{ {
if (buffer) if (buffer)
free(buffer); free(buffer);
fclose(log_fd); if (log_fd)
fclose(log_fd);
} }
int log_init(char *logfile) int log_init(const char *logfile)
{ {
if (log_fd != NULL)
log_close();
log_fd = fopen(logfile, "a"); log_fd = fopen(logfile, "a");
if (log_fd == NULL) { if (log_fd == NULL) {
log_print(LOG_ERROR, "log_open('%s'): %s", logfile); fprintf(stderr, "log_init(): can not open logfile");
return 0; return -1;
} }
return 0;
if (atexit(log_close) != 0) { }
log_print(LOG_ERROR, "log_open(): atexit()");
return 0; void log_setprio(int prio)
} {
log_prio = prio;
log_print(LOG_EVERYTIME, "==========================");
return 1;
} }

View File

@ -10,7 +10,10 @@
#define LOG_EVERYTIME 0 #define LOG_EVERYTIME 0
int log_init(char *logfile); int log_init(const char *logfile);
void log_print(int prio, const char *fmt, ... ); void log_close(void);
void log_setprio(int prio);
int log_print(int prio, const char *fmt, ... );
#endif /* _LOGGING_H_ */ #endif /* _LOGGING_H_ */